Overview

MyOLEDB Provider v3.0
 is an OLE DB provider capable of supplying OLE DB consumer with “base” functional access to the data stored in MySQL (ISAM, MyISAM, ...) format. Provider supports schemas, commands and MySQL data sources enumerator object.

MyOLEDB is designed by SWsoft, Inc

© 1998-2000 SWsoft


Connection string

If you use OLE DB interfaces directly, set initialization property DBPROP_INIT_DATASOURCE to

  • name of MySQL database - like test
  • or a connection string like one used in MyODBC - like server=localhost;DB=test

If you use ADO, set connection string to Provider=MySQLProv; Data Source=xxx, where xxx is

  • name of MySQL database - like test
  • or a connection string like one used in MyODBC - like server=localhost;DB=test

© 2000 SWsoft


Supported Interfaces

The MyOLEDB Provider complies with the Base Level of OLE DB provider’s functionality, according to Microsoft leveling classification and supports the following interfaces:

Object

Interface

Methods

DataSource IDBCreateSession IDBCreateSession::CreateSession
IDBInfo IDBInfo::GetKeywords
IDBInfo::GetLiteralInfo
IDBInitialize IDBInitialize::Initialize
IDBInitialize::Uninitialize
IDBProperties IDBProperties::GetProperties
IDBProperties::GetPropertyInfo
IPersist IPersist::GetClassID
IPersistFile IPersist::GetClassID
IPersistFile::Load
IPersistFile::GetCurFile
Data Sources Enumerator ISourcesRowset ISourcesRowset::GetSourcesRowset
IParseDisplayName IParseDisplayName::ParseDisplayName
Session IGetDataSource IGetDataSource::GetDataSource
IOpenRowset IOpenRowset::OpenRowset
ISessionProperties ISessionProperties::GetProperties
ISessionProperties::SetProperties
IDBCreateCommand IDBCreateCommand::CreateCommand
IDBSchemaRowset IDBSchemaRowset::GetRowset
IDBSchemaRowset::GetSchemas
Rowset IAccessor IAccessor::AddRefAccessor
IAccessor::CreateAccessor
IAccessor::GetBindings
IAccessor::ReleaseAccessor
IConvertType IConvertType::CanConvert
IColumnsInfo IColumnsInfo::GetColumnsInfo
IColumnsInfo::MapColumnIDs

IRowset

IRowset::AddRefRows
IRowset::GetData
IRowset::GetNextRows
IRowset::ReleaseRows
IRowset::RestartPosition
IRowsetIdentity IRowsetIdentity::IsSameRow
IRowsetInfo IRowsetInfo::GetProperties
IRowsetInfo::GetReferencedRowset
IRowsetInfo::GetSpecification
IConnectionPointContainer for IRowsetNotify IConnectionPointContainer::EnumConnectionPoints
IConnectionPointContainer::FindConnectionPoint
IRowsetChange IRowsetChange::DeleteRows
IRowsetChange::InsertRows
IRowsetChange::SetData
IRowsetFind IRowsetFind::FindNextRow
IRowsetLocate IRowsetLocate::Compare
IRowsetLocate::GetRowsAt
IRowsetLocate::GetRowsByBookmark
IRowsetLocate::Hash
IRowsetScroll IRowsetScroll::GetApproximatePosition
IRowsetLocate::GetRowsAtRatio

Command

IAccessor IAccessor::AddRefAccessor
IAccessor::CreateAccessor
IAccessor::GetBindings
IAccessor::ReleaseAccessor
IColumnsInfo IColumnsInfo::GetColumnsInfo
IColumnsInfo::MapColumnIDs
IConvertType IConvertType::CanConvert
ICommand ICommand::Cancel
ICommand::Execute
ICommand::GetDBSession
ICommandProperties ICommandProperties::GetProperties
ICommandProperties::SetProperties
ICommandText ICommandText::GetCommandText
ICommandText::SetCommandText

ICommandPrepare

ICommandPrepare::Prepare
ICommandPrepare::Unprepare
ICommandWithParameters ICommandWithParameters ::GetParameterInfo
ICommandWithParameters::MapParameterNames
ICommandWithParameters::SetParameterInfo

© 2000 SWsoft


IAccessor

IAccessor provides methods for accessor management.

To create an accessor, a consumer calls CreateAccessor. The consumer may create and release accessors at any time while the rowset or command remains in existence. When one thread of a consumer shares an accessor with another thread, it calls AddRefAccessor to increment the reference count of that accessor.

When the consumer is done with a rowset, it calls ReleaseAccessor to release any accessors on the rowset, including accessors inherited from the command. When the consumer is done with a command, it calls ReleaseAccessor to release any accessors created on the command. In both cases, the consumer must call ReleaseAccessor once for each reference count on the accessor.

Method | Description
AddRefAccessor | Adds a reference count to an existing accessor.
CreateAccessor | Creates an accessor from a set of bindings.
GetBindings | Returns the bindings in an accessor.
ReleaseAccessor | Releases an accessor.


IAccessor::AddRefAccessor

Adds a reference count to an existing accessor.

HRESULT AddRefAccessor (
   HACCESSOR   hAccessor,
   ULONG *         pcRefCount);

Parameters

hAccessor

[in]
The handle of the accessor for which to increment the reference count.

pcRefCount

[out]
A pointer to memory in which to return the reference count of the accessor handle. If pcRefCount is a null pointer, no reference count is returned.

Return Code

S_OK
The method succeeded.

E_FAIL
A provider-specific error occurred.

E_UNEXPECTED
ITransaction::Commit or ITransaction::Abort was called and the object is in a zombie state. This error can be returned only when the method is called on a rowset.

DB_E_BADACCESSORHANDLE
hAccessor was invalid.

Comments

The consumer must increment the reference count on an accessor by calling AddRefAccessor before passing it to another thread.

See Also

IAccessor::CreateAccessor, IAccessor::ReleaseAccessor


IAccessor::CreateAccessor

CreateAccessor creates an accessor from a set of bindings.

HRESULT CreateAccessor (
   DBACCESSORFLAGS      dwAccessorFlags,
   ULONG                     cBindings,
   const DBBINDING            rgBindings[],
   ULONG                     cbRowSize,
   HACCESSOR *               phAccessor,
   DBBINDSTATUS            rgStatus[]);

Parameters

dwAccessorFlags

[in]
A bitmask that describes the properties of the accessor and how it is to be used. These flags have the following meanings.

Value Description
DBACCESSOR_
INVALID 		This flag is used by GetBindings to indicate that the method failed.
DBACCESSOR_
PASSBYREF 		The accessor is a reference accessor.

The value passed in the consumer buffer is a pointer to the passer's internal buffer. This pointer need not point to the start of the internal buffer, as long as the relative offsets of all elements of the buffer align with the offsets specified in the accessor. The passee must know the internal structure of the passer's buffer in order to read information from it. The passee must not free the buffer at the pointer, nor may it write to this buffer.

For row accessors, this buffer is the rowset's copy of the row. The consumer reads information directly from this copy of the row at a later point in time, so the provider must guarantee that the pointer remains valid.

For parameter accessors, this buffer is the consumer's buffer. The provider reads data from this buffer only when ICommand::Execute is called, so the pointer is not required to remain valid after Execute returns.

Support for this flag is optional. A consumer determines whether a provider supports this bit by calling IDBProperties::GetProperties for the DBPROP_BYREFACCESSORS property.

When this flag is used, the dwMemOwner in the DBBINDING structure is ignored. If the accessor is used for row data, the accessor refers to the provider's memory; the consumer must not write to or free this memory. If the accessor is used for input parameters, the provider copies the row of data without assuming ownership.

It is an error to specify an output or input/output parameter in a reference accessor.

DBACCESSOR_
ROWDATA 		The accessor is a row accessor and describes bindings to columns in the rowset.

An accessor may be a row accessor, a parameter accessor, or both.

DBACCESSOR_
PARAMETERDATA 		The accessor is a parameter accessor and describes bindings to parameters in the command text. In a parameter accessor, it is an error to bind an input or an input/output parameter more than once.
DBACCESSOR_
OPTIMIZED 		The row accessor is to be optimized. This hint may affect how a provider structures its internal buffers. A particular column can be bound by only one optimized accessor. The column can also be bound by other, nonoptimized accessors, but the types specified in the nonoptimized accessors must be convertable from the type in the optimized accessor. All optimized accessors must be created before the first row is fetched with IRowset::GetNextRows, IRowsetLocate::GetRowsAt, IRowsetLocate::GetRowsByBookmark, or IRowsetScroll::GetRowsAtRatio.

This flag is ignored for parameter accessors.

cBindings

[in]
The number of bindings in the accessor.

If cBindings is zero, CreateAccessor creates a null accessor. Null accessors are used only by IRowsetChange::InsertRow to create a new row in which each column is set to its default value, NULL, or a status of DBSTATUS_E_UNAVAILABLE. Providers that support InsertRow must support the creation of null accessors. For more information, see InsertRow.

rgBindings

[in]
An array of DBBINDING structures.

cbRowSize

[in]
The numer of bytes allocated for a single set of parameters or criteria values in the consumer's buffer.

cbRowSize is used by ICommand::Execute to process multiple sets of parameters. A single accessor may describe multiple sets of values. cbRowSize is generally the size of the structure that contains a single set of parameter or critieria values and is used as the offset to the start of the next set of values within the array of structures. For example, if cParamSets is greater than 1 in the DBPARAMS structure passed to Execute, the provider assumes that the pData element of this structure points to an array of structures containing parameter values, each cbRowSize bytes in size.

cbRowSize must be large enough to contain the structure defined by the bindings in rgBindings. The provider is not required to verify this, although it may.

cbRowSize is not used when fetching rowset data.

phAccessor

[out]
A pointer to memory in which to return the handle of the created accessor. If CreateAccessor fails, it must attempt to set *phAccessor to a null handle.

rgStatus

[out]
An array of cBindings DBBINDSTATUS values in which CreateAccessor returns the status of each binding; that is, whether it was successfully validated or not. If rgStatus is a null pointer, no bind status values are returned. The consumer allocates and owns the memory for this array. The bind status values are returned for the following reasons.

Value | Description
DBBINDSTATUS_OK | No errors were found in the binding. Because accessor validation can be deferred, a status of DBBINDSTATUS_OK does not necessarily mean that the binding was successfully validated.
DBBINDSTATUS_
BADORDINAL 		A parameter ordinal was zero in a parameter accessor.

If the accessor is validated against the metadata when CreateAccessor is called, DBBINDSTATUS_BADORDINAL can be returned for the following reasons:

  • In a row accessor, a column ordinal in a binding was outside the range of available columns on the rowset.

  • In a parameter accessor, a parameter ordinal was greater than the number of parameters in the command text.

These reasons cause a status value of DBSTATUS_E_BADACCESSOR to be returned if the accessor is validated when used.

Some providers may support binding more parameters than the number of parameters in the command text, and such providers do not return DBBINDSTATUS_BADORDINAL in this case.

DBBINDSTATUS_
UNSUPPORTED
CONVERSION 		If the accessor is validated against the metadata when CreateAccessor is called, DBBINDSTATUS_UNSUPPORTEDCONVERSION can be returned for the following reason:
  • The specified conversion was not supported by the provider.
  • The consumer attempted to convert a column to a storage object (ISequentialStream, IStorage, IStream, ILockBytes) and the particular conversion is not supported by the provider.

These reasons cause a status value of DBSTATUS_E_BADACCESSOR to be returned if the accessor is validated when used.

DBBINDSTATUS_
BADBINDINFO 		dwPart in a binding was not one of the following:

DBPART_VALUE
DBPART_LENGTH
DBPART_STATUS

eParamIO in a binding in a parameter accessor was not one of the following:

DBPARAMIO_INPUT
DBPARAMIO_OUTPUT
DBPARAMIO_INPUT | DBPARAMIO_OUTPUT

A row accessor was optimized and a column ordinal in a binding was already used in another optimized accessor.

In a parameter accessor, two or more bindings contained the same ordinal for an input or input/output parameter.

wType in a binding was DBTYPE_EMPTY or DBTYPE_NULL.

wType in a binding was one of the following:

DBTYPE_BYREF | DBTYPE _EMPTY,
DBTYPE_BYREF | DBTYPE_NULL, or
DBTYPE_BYREF | DBTYPE_RESERVED.

wType in a binding was used with more than one of the following mutually exclusive type indicators: DBTYPE_BYREF, DBTYPE_ARRAY, or DBTYPE_VECTOR.

wType in a binding was DBTYPE_IUNKNOWN, and pObject in the same binding was a null pointer.

Provider-owned memory was specified for a nonpointer type in a nonreference row accessor.

Provider-owned memory was specified for a column and the provider does not support binding to provider-owned memory for this column.

Provider-owned memory was specified for a column for which IColumnsInfo::GetColumnInfo returned DBCOLUMNFLAGS_ISLONG.

In a nonreference parameter accessor, a binding specified provider-owned memory.

An output or input/output parameter was specified in a parameter reference accessor.

dwFlags in a binding was set to DBBINDFLAG_HTML, and wType for the same binding was not a string value.

If the accessor is validated against the metadata when CreateAccessor is called, DBBINDSTATUS_BADBINDINFO can be returned for the following reasons:

  • A row accessor was not optimized, a column number in a binding specified a column that was already used in an optimized accessor, and the provider did not support a conversion from the type specified in the optimized accessor for the column to the type specified in wType.

  • In a parameter accessor, eParamIO in a binding specified the incorrect I/O type for the parameter. Some providers cannot determine parameter I/O types and never return DBBINDSTATUS_BADBINDINFO in this case.

  • In a reference accessor, the value specified for dwPart, obValue, cbMaxLen, or wType in a binding did not match the format of the corresponding element in the rowset's copy of the row.

  • In a nonreference accessor, a binding specified provider-owned memory, wType was X | DBTYPE_BYREF, and the data type of the corresponding element of the rowset's copy of the row was not X or X | DBTYPE_BYREF.

  • In a nonreference accessor, a binding specified provider-owned memory, wType was DBTYPE_BSTR, and the data type of the corresponding element of the rowset's copy of the row was not DBTYPE_BSTR.

  • The accessor was used for passing key column values in IRowsetIndex::Seek or IRowsetIndex::SetRange, and the order in which the key columns were bound did not match the order in which they were returned in IColumnsInfo::GetColumnInfo.

  • The accessor was used for passing key column values in Seek or SetRange, and a less significant key column was bound without binding all more significant key columns.

  • The accessor was used for passing key column values in Seek or SetRange, and a non-key column was bound before the last bound key column.

  • These reasons cause a status value of DBSTATUS_E_BADACCESSOR to be returned if the accessor is validated when used.
DBBINDSTATUS_
BADSTORAGE
FLAGS 		dwFlags, in the DBOBJECT structure pointed to by a binding, specified invalid storage flags.

If the accessor is validated against the metadata when CreateAccessor is called, DBBINDSTATUS_BADSTORAGEFLAGS can be returned for the following reason:

  • dwFlags, in the DBOBJECT structure pointed to by a binding, specified a valid storage flag that was not supported by the object.

These reasons cause a status value of DBSTATUS_E_BADACCESSOR to be returned if the accessor is validated when used.

DBBINDSTATUS_
NOINTERFACE 		If the accessor is validated against the metadata when CreateAccessor is called, DBBINDSTATUS_NOINTERFACE can be returned for the following reasons:
  • The provider did not support the storage interface specified in iid in the DBOBJECT structure pointed to by a binding in the accessor.

  • The OLE object in a column or parameter did not support the interface specified in iid in the DBOBJECT structure pointed to by the corresponding binding in the accessor.

  • The provider supports only one open storage object at a time—that is, DBPROP_MULTIPLESTORAGEOBJECTS is VARIANT_FALSE—and wType in more than one binding was DBTYPE_IUNKNOWN.

These reasons cause a status value of DBSTATUS_E_BADACCESSOR to be returned if the accessor is validated when used.

Return Code

S_OK
The method succeeded. If rgStatus is not a null pointer, each element is set to DBBINDSTATUS_OK.

E_FAIL
A provider-specific error occurred.

E_INVALIDARG
phAccessor was a null pointer.

cBindings was not zero and rgBindings was a null pointer.

E_UNEXPECTED
ITransaction::Commit or ITransaction::Abort was called and the object is in a zombie state. This error can be returned only when the method is called on a rowset.

DB_E_BADACCESSORFLAGS
dwAccessorFlags was invalid.

The DBACCESSOR_PARAMETERDATA bit was set in dwAccessorFlags, and the provider does not support parameters.

Neither the DBACCESSOR_PARAMETERDATA bit nor the DBACCESSOR_ROWDATA bit was set in dwAccessorFlags.

A method that fetches rows (IRowset::GetNextRows, IRowsetLocate::GetRowsAt, IRowsetLocate::GetRowsByBookmark, or IRowsetScroll::GetRowsAtRatio) had already been called and the DBACCESSOR_OPTIMIZED bit in dwAccessorFlags was set.

The DBACCESSOR_ PARAMETERDATA bit was set and CreateAccessor was called on a rowset.

DB_E_BYREFACCESSORNOTSUPPORTED
dwAccessorFlags was DBACCESSOR_PASSBYREF and the value of the DBPROP_BYREFACCESSORS property is VARIANT_FALSE.

DB_E_ERRORSOCCURRED
Accessor validation failed. To determine which bindings failed, the consumer checks the values returned in rgStatus, at least one of which is not DBBINDSTATUS_OK.

DB_E_NOTREENTRANT
The provider called a method from IRowsetNotify in the consumer and the method has not yet returned.

DB_E_NULLACCESSORNOTSUPPORTED
cBindings was zero and the rowset does not support IRowsetChange::InsertRow, or CreateAccessor was called on a command.

Comments

CreateAccessor always checks all error conditions that do not require it to validate the accessor against the metadata. As a general rule, this means it checks the error conditions for all of the return codes except those that return DB_E_ERRORSOCCURRED. CreateAccessor may validate the accessor against the metadata for row accessors created on the rowset; it never validates the accessor against the metadata for row or parameter accessors created on the command. When CreateAccessor validates the accessor against the metadata, it validates each binding in the accessor, setting the appropriate DBBINDSTATUS values as it goes. If CreateAccessor fails in any way, it does not create the accessor and sets *phAccessor to a null handle.

If CreateAccessor does not validate the accessor against the metadata, then the validation is said to be delayed. CreateAccessor simply creates the accessor and validation is done by the first method that uses the accessor. If the accessor is found to be invalid, it remains in existence and can be used again.

If accessor validation is delayed, the provider determines whether the method validating the accessor validates it against the metadata before or during data transfer. If the method validates the accessor before transferring any data, it can return any of the return codes listed below for this purpose. If the method validates the accessor while transferring the data, it sets the status value of any column or parameter for which the accessor is invalid (within the context of the method) to DBSTATUS_E_BADACCESSOR and returns DB_S_ERRORSOCCURRED or DB_E_ERRORSOCCURRED. Whether the method continues processing other columns or parameters depends on both the method and the provider.

The following return codes are returned by methods that perform delayed accessor validation before transferring any data. The DBBINDSTATUS value to which each corresponds is also listed.

Return code | DBBINDSTATUS value
E_NOINTERFACE | DBBINDSTATUS_NOINTERFACE
DB_E_BADBINDINFO | DBBINDSTATUS_BADBINDINFO
DB_E_BADORDINAL | DBBINDSTATUS_BADORDINAL
DB_E_BADSTORAGEFLAGS | DBBINDSTATUS_ BADSTORAGEFLAGS
DB_E_UNSUPPORTEDCONVERSION | DBBINDSTATUS_ UNSUPPORTEDCONVERSION

Providers that do not support conversion of BLOB or non-BLOB data to a data structured storage interface should fail the accessor creation method with DB_E_ERRORSOCCURED and report DBBINDSTATUS_UNSUPPORTEDCONVERSION on the column specifying the incorrect binding.

See Also

IAccessor::GetBindings, IAccessor::ReleaseAccessor, IConvertType::CanConvert, IRowset::GetData, IRowsetChange::SetData


IAccessor::GetBindings

Returns the bindings in an accessor.

HRESULT GetBindings (
   HACCESSOR               hAccessor,
   DBACCESSORFLAGS *   pdwAccessorFlags,
   ULONG *                     pcBindings,
   DBBINDING **               prgBindings);

Parameters

hAccessor

[in]
The handle of the accessor for which to return the bindings.

pdwAccessorFlags

[out]
A pointer to memory in which to return a bitmask that describes the properties of the accessor and how it is intended to be used. For more information, see dwAccessorFlags in CreateAccessor. If this method fails, *pdwAccessorFlags is set to DBACCESSOR_INVALID.

pcBindings

[out]
A pointer to memory in which to return the number of bindings in the accessor. If this method fails, *pcBindings is set to zero.

prgBindings

[out]
A pointer to memory in which to return an array of DBBINDING structures. One DBBINDING structure is returned for each binding in the accessor. The provider allocates memory for these structures and any structures pointed to by elements of these structures; for example, if pObject in a binding structure is not a null pointer, the provider allocates a DBOBJECT structure for return to the consumer. The provider returns the address to the memory for these structures; the consumer releases the memory for these structures with IMalloc::Free when it no longer needs the bindings. If *pcBindings is zero on output or the method fails, the provider does not allocate any memory and ensures that *prgBindings is a null pointer on output.

Return Code

S_OK
The method succeeded.

E_FAIL
A provider-specific error occurred.

E_INVALIDARG
pdwAccessorFlags, pcBindings, or prgBindings was a null pointer.

E_OUTOFMEMORY
The provider was unable to allocate sufficient memory in which to return the binding structures.

E_UNEXPECTED
ITransaction::Commit or ITransaction::Abort was called and the object is in a zombie state. This error can be returned only when the method is called on a rowset.

DB_E_BADACCESSORHANDLE
hAccessor was invalid.

DB_E_NOTREENTRANT
The provider called a method from IRowsetNotify in the consumer and the method has not yet returned.

Comments

This method makes no logical change to the state of the object.

If the accessor is a null accessor, then the method sets *pcBindings to zero and *prgBindings to a null pointer.

See Also

IAccessor::CreateAccessor


IAccessor::ReleaseAccessor

Releases an accessor.

HRESULT ReleaseAccessor (
   HACCESSOR   hAccessor,
   ULONG *         pcRefCount);

Parameters

hAccessor

[in]
The handle of the accessor to release.

pcRefCount

[out]
A pointer to memory in which to return the remaining reference count of the accessor handle. If pcRefCount is a null pointer, no reference count is returned.

Return Code

S_OK
The method succeeded.

E_FAIL
A provider-specific error occurred.

DB_E_BADACCESSORHANDLE
hAccessor was invalid.

DB_E_NOTREENTRANT
The provider called a method from IRowsetNotify in the consumer and the method has not yet returned.

Comments

ReleaseAccessor decrements the reference count of the accessor. If the reference count reaches zero, it releases the accessor and all resources used by the accessor. After an accessor is released, methods called with the handle to that accessor return DB_E_BADACCESSORHANDLE.

On rowsets, accessors are read-only and can be shared among threads in a free-threaded style without synchronization. The consumer must call ReleaseAccessor to decrement the reference count on an accessor that has been passed to a thread and is no longer needed by that thread.

This method can be called while the rowset is in a zombie state to enable the consumer to clean up after a transaction has been committed or aborted.

See Also

IAccessor::AddRefAccessor, IAccessor::CreateAccessor


IColumnsInfo

IColumnsInfo is the simpler of two interfaces that can be used to expose information about columns of a rowset or prepared command. It provides a limited set of information in an array.

GetColumnInfo returns the most commonly used metadata: column IDs, data types, updatability, and so on. GetColumnInfo returns the metadata in an array of structures, which can be created and accessed quickly. The metadata returned, however, is limited.

Method | Description
GetColumnInfo | Returns the column metadata needed by most consumers.
MapColumnIDs | Returns an array of ordinals of the columns in a rowset that are identified by the specified column IDs.


IColumnsInfo::GetColumnInfo

Returns the column metadata needed by most consumers.

HRESULT GetColumnInfo (
   ULONG *                  pcColumns,
   DBCOLUMNINFO **   prgInfo,
   OLECHAR **            ppStringsBuffer);

Parameters

pcColumns

[out]
A pointer to memory in which to return the number of columns in the rowset; this number includes the bookmark column, if there is one. If GetColumnInfo is called on a command that does not return rows, *pcColumns is set to zero. If this method terminates due to an error, *pcColumns is set to zero.

prgInfo

[out]
A pointer to memory in which to return an array of DBCOLUMNINFO structures. One structure is returned for each column in the rowset. The provider allocates memory for the structures and returns the address to this memory; the consumer releases this memory with IMalloc::Free when it no longer needs the column information. If *pcColumns is 0 on output or terminates due to an error, the provider does not allocate any memory and ensures that *prgInfo is a null pointer on output. For more information, see "DBCOLUMNINFO Structures" in the Comments section.

ppStringsBuffer

[out]
A pointer to memory in which to return a pointer to storage for all string values (names used either within columnid or for *pwszName) within a single allocation block. If no returned columns have either form of string name, or if this method terminates due to error, this parameter returns a null pointer. If there are any string names, then this will be a buffer containing all the values of those names. The consumer should free the buffer with IMalloc::Free when finished working with the names. If *pcColumns is zero on output, the provider does not allocate any memory and ensures that *ppStringsBuffer is a null pointer on output. Each of the individual string values stored in this buffer is terminated by a null-termination character. Therefore, the buffer may contain one or more strings, each with its own null-termination character, and may contain embedded null-termination characters.

Return Code

S_OK
The method succeeded.

E_FAIL
A provider-specific error occurred.

E_INVALIDARG
pcColumns, prgInfo, or ppStringsBuffer was a null pointer.

E_OUTOFMEMORY
The provider was unable to allocate sufficient memory in which to return the column information structures.

E_UNEXPECTED
ITransaction::Commit or ITransaction::Abort was called and the object is in a zombie state. This error can be returned only when the method is called on a rowset.

DB_E_ERRORSINCOMMAND
The command text contained one or more errors. Providers should use OLE DB error objects to return details about the errors.

DB_E_NOCOMMAND
No command text was set. This error can be returned only when this method is called from the Command object.

DB_E_NOTPREPARED
The command exposed ICommandPrepare and the command text was set, but the command was not prepared. This error can be returned only when this method is called from the Command object.

DB_E_NOTREENTRANT
The provider called a method from IRowsetNotify in the consumer and the method has not yet returned.

DB_SEC_E_PERMISSIONDENIED
The consumer did not have sufficient permission to retrieve the column information.

Comments

This function makes no logical change to the state of the object.

GetColumnInfo returns a fixed set of column metadata in an array of DBCOLUMNINFO structures, one per column. The returned metadata is that most commonly used by consumers, such as the data type and column ID.

The order of the structures is the order in which the columns appear in the rowset (column ordinal order).

Bookmark columns may be returned on any rowset, regardless of its source (for example, ICommand::Execute, IOpenRowset::OpenRowset, or IDBSchemaRowset::GetRowset) or whether bookmarks were requested. When bookmarks are returned, they will always appear as the first element of *prgInfo with iOrdinal equal to zero. When processing the columns returned by GetColumnInfo, generic consumers should be prepared to receive and handle bookmark columns appropriately (that is, not display them to the user if not appropriate for the application).

Calling GetColumnInfo on a command before the command is executed may be an expensive operation.

DBCOLUMNINFO Structures

GetColumnInfo returns column metadata in DBCOLUMNINFO structures.

typedef struct tagDBCOLUMNINFO {
 LPOLESTR  pwszName;
 ITypeInfo * pTypeInfo;
 ULONG   iOrdinal;
 DBCOLUMNFLAGS dwFlags;
 ULONG   ulColumnSize;
 DBTYPE    wType;
 BYTE    bPrecision;
 BYTE    bScale;
 DBID    columnid;
} DBCOLUMNINFO;

The elements of this structure are used as follows.

Element | Description
pwszName Pointer to the name of the column; this might not be unique. If this cannot be determined, a null pointer is returned.

The name can be different from the string part of the column ID if the column has been renamed by the command text. This name always reflects the most recent renaming of the column in the current view or command text.

pTypeInfo | Reserved for future use. Providers should return a null pointer in pTypeInfo.
iOrdinal | The ordinal of the column. This is zero for the bookmark column of the row, if any. Other columns are numbered starting from one.
dwFlags | A bitmask that describes column characteristics. The DBCOLUMNFLAGS enumerated type specifies the bits in the bitmask. For more information, see the following section.
ulColumnSize The maximum possible length of a value in the column. For columns that use a fixed-length data type, this is the size of the data type. For columns that use a variable-length data type, this is one of the following:
  • The maximum length of the column in characters, for DBTYPE_STR and DBTYPE_WSTR, or bytes, for DBTYPE_BYTES, if one is defined. For example, a CHAR(5) column in an SQL table has a maximum length of 5.
  • The maximum length of the data type in characters, for DBTYPE_STR and DBTYPE_WSTR, or bytes, for DBTYPE_BYTES, if the column does not have a defined length.

    For data types that do not have a length, this is set to ~0 (bitwise, the value is not 0; that is, all bits are set to 1).

  • ~0 (bitwise, the value is not 0; that is, all bits are set to 1) if neither the column nor the data type has a defined maximum length.
wType | The indicator of the column's data type. If the data type of the column varies from row to row, this must be DBTYPE_VARIANT.
bPrecision If wType is a numeric data type, this is the maximum precision of the column. The precision of columns with a data type of DBTYPE_DECIMAL or DBTYPE_NUMERIC depends on the definition of the column.

For DBTYPE_DBTIMESTAMP data types, this is the length of the string representation (assuming the maximum allowed precision of the fractional seconds component).

If the column's data type is not numeric or datetime, this is ~0 (bitwise, the value is not 0; that is, all bits are set to 1).

bScale If wType is DBTYPE_DECIMAL or DBTYPE_NUMERIC, this is the number of digits to the right of the decimal point. Otherwise, this is ~0 (bitwise, the value is not 0; that is, all bits are set to 1).

For DBTYPE_DBTIMESTAMP data types, this is the length of the string representation of the fractional seconds component.

columnid The column ID of the column.

The column ID of a base table should be invariant under views.

DBCOLUMNFLAGS Enumerated Type

The dwFlags element of the DBCOLUMNINFO structure is a bitmask that describes column characteristics. The DBCOLUMNFLAGS enumerated type specifies the bits in the bitmask; the meanings of these values are as follows.

Value Description
DBCOLUMNFLAGS_
CACHEDEFERRED 		Set if, when a deferred column is first read, its value is cached by the provider. Later reads of the column are done from this cache. The contents of the cache can be overwritten by IRowsetChange::SetData. The cached value is released when the row handle is released. Otherwise, not set.

This flag can be set through the DBPROP_CACHEDEFERRED property in the Rowset property group.

DBCOLUMNFLAGS_
ISBOOKMARK 		Set if the column contains a bookmark. Otherwise, not set.
DBCOLUMNFLAGS_
ISCHAPTER 		Set if the column contains a chapter value. Otherwise, not set.
DBCOLUMNFLAGS_
ISFIXEDLENGTH 		Set if all data in the column has the same length. Otherwise, not set.

The flag is always set for fixed length data types except DBTYPE_BSTR. The flag is set for variable-length data types (DBTYPE_STR, DBTYPE_WSTR, DBTYPE_BSTR, and DBTYPE_BYTES) if all the values are the same length. The flag is set for DBTYPE_VECTOR or DBTYPE_ARRAY columns if all elements in each vector or array are of the same length and each vector or array has the same number of elements. Otherwise, the flag is not set.

The flag is not affected by DBTYPE_BYREF.

DBCOLUMNFLAGS_
ISLONG 		Set if the column contains a BLOB that contains very long data. The definition of very long data is provider-specific. The setting of this flag corresponds to the value of the IS_LONG column in the PROVIDER_TYPES schema rowset for the data type.

When this flag is set, the provider supports reading the value through a storage interface. Although such BLOBs can be retrieved in a single piece with IRowset::GetData, there may be provider-specific problems in doing so. For example, the BLOB might be truncated due to machine limits on memory or GetData might fail if called more than once for the BLOB. Furthermore, when this flag is set, the provider might not be able to accurately return the maximum length of the BLOB data in ulColumnSize in the DBCOLUMNINFO structure.

When this flag is not set, the BLOB can be accessed directly through GetData. It is provider-specific whether columns without this flag can be read through a storage interface.

DBCOLUMNFLAGS_
ISNULLABLE 		Set if the column can be set to NULL or if the provider cannot determine whether or not the column can be set to NULL. Otherwise, not set. This reflects only declarative rules. DBCOLUMNFLAGS_ISNULLABLE is generally used by consumers attempting to set data to determine whether or not a particular column might be able to hold a null value.
DBCOLUMNFLAGS_
ISROWID 		Set if the column contains a persistent row identifier that cannot be written to and has no meaningful value except to identify the row.
DBCOLUMNFLAGS_
ISROWVER 		Set if the column contains a timestamp or other versioning mechanism that cannot be written to directly and that is automatically updated to a new, increasing value when the row is updated and committed. The data type of a version column is provider-specific. How a version column is used—for example, how two version values are compared—is also provider-specific.
DBCOLUMNFLAGS_
MAYBENULL 		Set if NULL can be gotten from the column, or if the provider cannot guarantee that NULLs cannot be gotten from the column. Otherwise, not set. DBCOLUMNFLAGS_MAYBENULL is generally used by consumers reading data to determine whether or not they might encounter a null value. When DBCOLUMNINFO is returned in the COLUMNS rowset, DBCOLUMNFLAGS_MAYBENULL should not be set if a simple select over the single column of that table would return no null values.

DBCOLUMFLAGS_MAYBENULL can be set even if DBCOLUMNFLAGS_ISNULLABLE is not set. For example, in a left outer join, if there is no row on the right side that matches a row on the left side, the columns from the right side in the joined row contain NULLs, even if the underlying columns are non-nullable; that is, if DBCOLUMNFLAGS_ISNULLABLE is not set.

DBCOLUMNFLAGS_
MAYDEFER 		Set if the column is deferred. Otherwise, not set.

A deferred column is one for which the data is not fetched from the data source until the consumer attempts to get it. That is, the data is not fetched when the row is fetched, but when IRowset::GetData is called. This flag can be set through the DBPROP_DEFERRED property in the Rowset property group.

DBCOLUMNFLAGS_
WRITE 		Set if IRowsetChange::SetData can be called for the column. Otherwise, not set.

This flag can be set through the DBPROP_MAYWRITECOLUMN property in the Rowset property group.

Providers never set both DBCOLUMNFLAGS_WRITE and DBCOLUMNFLAGS_WRITEUNKNOWN; they are mutually exclusive. Absence of these flags means the column is read-only.

DBCOLUMNFLAGS_
WRITEUNKNOWN 		Set if it is not known whether IRowsetChange::SetData can be called for the column.

Providers never set both DBCOLUMNFLAGS_WRITE and DBCOLUMNFLAGS_WRITEUNKNOWN; they are mutually exclusive. Absence of these flags means the column is read-only.

See Also

IColumnsInfo::MapColumnIDs, IRowsetInfo::GetProperties


IColumnsInfo::MapColumnIDs

Returns an array of ordinals of the columns in a rowset that are identified by the specified column IDs.

HRESULT MapColumnIDs (
   ULONG      cColumnIDs,
   const DBID   rgColumnIDs[],
   ULONG      rgColumns[]);

Parameters

cColumnIDs

[in]
The number of column IDs to map. If cColumnIDs is 0, MapColumnIDs does nothing and returns S_OK.

rgColumnIDs

[in]
An array of IDs of the columns of which to determine the column ordinals. If rgColumnIDs contains a duplicate column ID, a column ordinal is returned once for each occurrence of the column ID. If the column ID is invalid, the corresponding element of rgColumns is set to DB_INVALIDCOLUMN.

rgColumns

[out]
An array of cColumnIDs ordinals of the columns identified by the elements of rgColumnIDs. The consumer allocates, but is not required to initialize, memory for this array and passes the address of this memory to the provider. The provider returns the column IDs in the array.

Return Code

S_OK
The method succeeded. All elements of rgColumns are set to values other than DB_INVALIDCOLUMN.

DB_S_ERRORSOCCURRED
An element of rgColumnIDs was invalid. If the column ID is invalid, the corresponding element of rgColumns is set to DB_INVALIDCOLUMN.

E_FAIL
A provider-specific error occurred.

E_INVALIDARG
cColumnIDs was not 0 and rgColumnIDs was a null pointer.

rgColumns was a null pointer.

E_UNEXPECTED
ITransaction::Commit or ITransaction::Abort was called and the object is in a zombie state. This error can be returned only when the method is called on a rowset.

DB_E_ERRORSOCCURRED
All elements of rgColumnIDs were invalid. All elements of rgColumns are set to DB_INVALIDCOLUMN.

DB_E_NOCOMMAND
No command text was set. This error can be returned only when this method is called from the Command object.

DB_E_NOTPREPARED
The command exposed ICommandPrepare and the command text was set, but the command was not prepared. This error can be returned only when this method is called from the Command object.

DB_E_NOTREENTRANT
The provider called a method from IRowsetNotify in the consumer and the method has not yet returned.

Comments

This method makes no logical change to the state of the object.

MapColumnIDs returns the ordinals of the columns in the rowset that are identified by the elements of rgColumnIDs. These column ordinals do not change during the life of the rowset. Column ordinals may change between different instantiations of a rowset if the command text does not define an order, such as a SELECT * FROM MyTable.

Two column IDs that are the same—except that one contains a GUID and the other contains a pointer to a GUID—are equivalent if both use the same GUID. Both are mapped to the same column ordinal.

See Also

IColumnsInfo::GetColumnInfo


IConnectionPointContainer

Method | Description
EnumConnectionPoints | Allows to enumerate connection points.
FindConnectionPoint | Returns a pointer to a connection point for a specified IID.


IConnectionPointContainer::EnumConnectionPoints

Creates an enumerator object to iterate through all the connection points supported in the connectable object, one connection point per outgoing IID.

HRESULT EnumConnectionPoints(
  IEnumConnectionPoints **ppEnum  //Address of output variable that
                                  // receives the IEnumConnectionPoints
                                  // interface pointer
);

Parameters

ppEnum
[out] Address of IEnumConnectionPoints* pointer variable that receives the interface pointer to the newly created enumerator.

Return Values

This method supports the standard return values E_OUTOFMEMORY and E_UNEXPECTED, as well as the following:

S_OK
The enumerator was successfully created.
E_POINTER
The value in ppEnum is not valid. For example, it may be NULL.

Remarks

Since IEnumConnectionPoints enumerates pointers to IConnectionPoint, the caller must use IConnectionPoint::GetConnectionInterface to determine the interface identifer of the outgoing interface that the connection point supports.

Notes to Callers

The caller is responsible for releasing the enumerator by calling (*ppEnum)->Release when it is no longer needed.


IConnectionPointContainer::FindConnectionPoint

Returns a pointer to the IConnectionPoin t interface of a connection point for a specified IID, if that IID describes a supported outgoing interface.

HRESULT FindConnectionPoint(
  REFIID riid,  //Requested connection point's interface identifier
  IConnectionPoint **ppCP
                //Address of output variable that receives the
                // IConnectionPoint interface pointer
);

Parameters

riid
[in] Interface identifier of the outgoing interface whose connection point object is being requested.
ppCP
[out] Address of IConnectionPoint* pointer variable that receives the interface pointer to the connection point that supports the riid interface. If an error occurs, the implementation sets *ppCP to NULL.

Return Values

This method supports the standard return values E_OUTOFMEMORY and E_UNEXPECTED, as well as the following:

S_OK
The ppCP pointer has a valid interface pointer.
E_POINTER
The address in ppCP is not valid. For example, it may be NULL.
CONNECT_E_NOCONNECTION
This connectable object does not support the outgoing interface specified by riid.

Remarks

This method is the QueryInterface equivalent for an object's outgoing interfaces, where the outgoing interface is specified with riid and where the interface pointer returned is always that of a connection point.

Notes to Callers

If the call is successful, the caller is responsible for releasing the connection point by calling (*ppCP)->Release when the connection point is no longer needed.


ICommand

ICommand contains methods to execute commands. A command can be executed many times and the parameter values can vary. This interface is mandatory on commands.

A command object contains a single text command, which is specified through ICommandText.

Method | Description
Cancel | Cancels the current command execution.
Execute | Executes the command.
GetDBSession | Returns an interface pointer to the session that created the command.


ICommand::Cancel

Cancels the current command execution.

HRESULT Cancel();

Parameters

None.

Return Code

S_OK
The method succeeded.

The command was not executing.

E_FAIL
A provider-specific error occurred.

DB_E_CANTCANCEL
The executing command cannot be canceled.

Comments

Cancel may be called on a separate thread after Execute has been called and before the method has returned. If the executing command can be canceled, the method returns S_OK, and Execute returns DB_E_CANCELED. If the executing command cannot be canceled, Cancel returns DB_E_CANTCANCEL and Execute continues. If the Execute method has not been called or has already returned, the method returns S_OK.

If the DBPROPVAL_ASYNCH_INITIALIZE bit in the DBPROP_ROWSET_ASYNCH property has been set prior to execution of the command, the Execute method may return with DB_S_ASYNCHRONOUS before the command has fully executed. Calling ICommand::Cancel after the Execute method has returned has no effect on any asynchronously executing commands. Once the Execute method has returned DB_S_ASYNCHRONOUS, the command can only be canceled by calling IDBAsynchStatus::Abort on the returned object.

See Also

ICommand::Execute


ICommand::Execute

Executes the command.

HRESULT Execute (
   IUnknown *      pUnkOuter,
   REFIID            riid,
   DBPARAMS *   pParams,
   LONG   *         pcRowsAffected,
   IUnknown **      ppRowset);

Parameters

pUnkOuter

[in]
A pointer to the controlling IUnknown interface if the rowset is being created as part of an aggregate; otherwise, it is null.

riid

[in]
The requested IID for the rowset returned in *ppRowset. This interface is conceptually added to the list of required interfaces on the resulting rowset, and the method fails (E_NOINTERFACE) if that interface cannot be supported on the resulting rowset.

If this is IID_NULL, then ppRowset is ignored and no rowset is returned, even if the command would otherwise generate a rowset. Specifying IID_NULL is useful in the case of text commands that do not generate rowsets, such as data definition commands, as a hint to the provider that no rowset properties need to be verified.

If riid is IID_IMultipleResults, the provider creates a multiple results object and returns a pointer to it in *ppRowset; it does this even if the command generates a single result. If the provider supports multiple results and the command generates multiple results but riid is not IID_IMultipleResults, the provider returns the first result and discards any remaining results. If riid is IID_IMultipleResults and the provider does not support multiple results, Execute returns E_NOINTERFACE.

pParams

[in/out]
A pointer to a DBPARAMS structure that specifies the values for one or more parameters. In text commands that use parameters, if no value is specified for a parameter through pParams, an error occurs.

struct DBPARAMS {
 void *  pData;
 ULONG   cParamSets;
 HACCESSOR hAccessor;
};

The elements of this structure are used as follows.

Element | Description
pData | Pointer to a buffer from which the provider retrieves input parameter data and to which the provider returns output parameter data, according to the bindings specified by hAccessor. This pointer must be a valid pointer to a contiguous block of consumer-owned memory for the input and output parameter values. When output parameter data is available to the consumer depends on the DBPROP_OUTPUTPARAMETERAVAILABILITY property.
cParamSets | The number of sets of parameters in *pData. If cParamSets is greater than one, then the bindings described by hAccessor define the offsets within *pData for each set of parameters, and cbRowSize (as specified in IAccessor::CreateAccessor) defines a single fixed offset between each of those values and the corresponding values for the next set of parameters. Sets of multiple parameters (cParamSets is greater than one) can be specified only if DBPROP_MULTIPLEPARAMSETS is VARIANT_TRUE and the command does not return any rowsets.
hAccessor | Handle of the accessor to use. If hAccessor is the handle of a null accessor (cBindings in CreateAccessor was 0), then Execute does not retrieve or return any parameter values.

If the command text does not include parameters, the provider ignores this argument.

pcRowsAffected

[out]
A pointer to memory in which to return the count of rows affected by a command that updates, deletes, or inserts rows. If cParamSets is greater than one, *pcRowsAffected is the total number of rows affected by all of the sets of parameters specified in the execution. If the number of affected rows is not available, *pcRowsAffected is set to DB_COUNTUNAVAILABLE on output. If the command does not update, delete, or insert rows, *pcRowsAffected is undefined on output. If pcRowsAffected is a null pointer, no count of rows is returned.

ppRowset

[in/out]
A pointer to the memory in which to return the rowset's pointer. If ppRowset is a null pointer, no rowset is created.

Return Code

S_OK
The method succeeded. In all DBPROP structures returned by the method, dwStatus is set to DBPROPSTATUS_OK, the status of all input parameters bound by the accessor is set to DBSTATUS_S_OK or DBSTATUS_S_ISNULL, and the status of all output parameters bound by the accessor is set to DBSTATUS_S_OK, DBSTATUS_S_ISNULL, or DBSTATUS_S_TRUNCATED or is unknown because the parameter value has not been returned yet.

DB_S_ASYNCHRONOUS
The method has initiated asynchronous creation of the rowset. The consumer can call IDBAsynchStatus to poll for status or IConnectionPointContainer to obtain the IID_IDBAsynchNotify connection point. Attempting to call any other interfaces may fail, and the full set of interfaces may not be available on the object until asynchronous initialization of the rowset has completed.

DB_S_ERRORSOCCURRED
This can be returned for any of the following reasons.

  • The command was executed but an error occurred while returning one or more output parameter values. To determine which output parameters were not returned, the consumer checks the status values.
  • The rowset was opened but one or more properties—for which the dwOptions element of the DBPROP structure was DBPROPOPTIONS_OPTIONAL—were not set. The consumer calls IRowsetInfo::GetProperties to determine which properties were set.

DB_S_STOPLIMITREACHED
Execution has been stopped because a resource limit has been reached. The results obtained so far have been returned. Execution cannot be resumed.

Multiple sets of parameters were specified and one or more, but not all of the parameters have been processed prior to the command being canceled by ICommand::Cancel or IDBAsynchStatus::Abort.

This return code takes precedence over DB_S_ERRORSOCCURRED. That is, if the conditions described here and in those described in DB_S_ERRORSOCCURRED both occur, the provider returns this code. When the consumer receives this return code, it should also check for the conditions described in DB_S_ERRORSOCCURRED.

E_FAIL
A provider-specific error occurred.

E_INVALIDARG
pParams was not ignored, cParamSets in the DBPARAMS structure pointed to by pParams was greater than one, ppRowset was not a null pointer, and the provider does not support multiple results.

pParams was not ignored and, in the DBPARAMS structure pointed to by pParams, pData was a null pointer.

pParams was not ignored, was not a null pointer, and in the DBPARAMS structure pointed to by pParams, cParamSets was zero.

riid was not IID_NULL and ppRowset was a null pointer.

E_NOINTERFACE
The rowset did not support the interface specified in riid.

riid was IID_IMultipleResults and the provider did not support multiple results objects.

DB_E_ABORTLIMITREACHED
Execution has been aborted because a resource limit has been reached. For example, a query timed out. No results have been returned.

DB_E_BADACCESSORHANDLE
pParams was not ignored and hAccessor in the DBPARAMS structure pointed to by pParams was invalid.

DB_E_BADACCESSORTYPE
hAccessor in the DBPARAMS structure pointed to by pParams was not the handle of a parameter accessor.

DB_E_CANCELED
The command was canceled by a call to Cancel on another thread. No records were affected.

DB_E_CANTCONVERTVALUE
A literal value in the command text could not be converted to the type of the associated column for reasons other than data overflow.

DB_E_DATAOVERFLOW
A literal value in the command text overflowed the type specified by the associated column.

DB_E_ERRORSINCOMMAND
The command text contained one or more errors. Providers should use OLE DB error objects to return details about the errors.

DB_E_ERRORSOCCURRED
The method failed due to one or more invalid input parameter values. To determine which input parameter values were invalid, the consumer checks the status values.

The command was not executed and no rowset was returned because one or more properties—for which the dwOptions element of the DBPROP structure was DBPROPOPTIONS_REQUIRED—were not set.

DB_E_INTEGRITYVIOLATION
A literal value in the command text violated the integrity constraints for the column.

DB_E_NOAGGREGATION
pUnkOuter was not a null pointer and the rowset being created does not support aggregation.

pUnkOuter was non-null and riid was not IID_Unknown.

DB_E_NOCOMMAND
No command text was currently set on the command object.

DB_E_NOTABLE
The specific table or view does not exist in the current data source.

DB_E_PARAMNOTOPTIONAL
A value was not supplied for a required parameter.

The command text used parameters and pParams was a null pointer.

DB_SEC_E_PERMISSIONDENIED
The consumer did not have sufficient permission to execute the command. For example, a rowset-returning command specified a column for which the consumer does not have read permission, or an update command specified a column for which the consumer does not have write permission.

DB_E_OBJECTOPEN
The provider would have to open a new connection to support the operation and DBPROP_MULTIPLECONNECTIONS is set to VARIANT_FALSE.

If this method performs deferred accessor validation and that validation takes place before any data is transferred, it can also return any of the following HRESULTs for the reasons listed in the corresponding DBBINDSTATUS values in IAccessor::CreateAccessor:

E_NOINTERFACE
DB_E_BADBINDINFO
DB_E_BADORDINAL
DB_E_BADSTORAGEFLAGS
DB_E_UNSUPPORTEDCONVERSION

Comments

If the command returns rows, such as an SQL SELECT statement, the result of this method is a rowset over the result rows. If no rows match the command, the rowset is still created. The resulting rowset is fully functional and can be used, for example, to insert new rows or determine column metadata.

If any or all parameters fail and the provider does not support errors within an array of parameters (that is, the command fails if any or all of the parameters fail), the provider returns DB_E_ERRORSOCCURRED and returns any error information for the failed parameters in their status bindings.

If any or all parameters fail and the provider supports errors within an array of parameters, the provider returns DB_S_ERRORSOCCURRED, sets pcRowsAffected to the number of successful parameters, and returns any error information for the failed parameters in their status bindings.

If Execute is called multiple times for a single command, with or without changes to the command text, the outcome may reflect changes in the underlying stored data, depending on the isolation level specified for the surrounding transaction.

Execute can be called when a rowset is already open on the command only if the only change between the calls is a change in the value of existing parameters. Methods that modify the command (ICommandProperties::SetProperties, and ICommandText::SetCommandText) while a rowset is open will fail and return DB_E_OBJECTOPEN. Each call to Execute creates a new rowset, which must be explicitly released by IRowset::Release.

Execute does not affect the prepared state of a command.

The consumer determines whether the command supports parameters by calling QueryInterface for ICommandWithParameters. If this interface is exposed, the command supports parameters; if it is not exposed, the command does not support parameters. If the command does not support parameters, Execute ignores pParams. However, if the command text includes parameters, Execute returns DB_E_ERRORSINCOMMAND.

If an input parameter value is not specified, Execute returns DB_E_PARAMNOTOPTIONAL. If the provider cannot describe parameters and the consumer has not called SetParameterInfo for all parameters, the behavior of Execute is undefined. For example, Execute might guess at the parameter information or it might fail completely.

If Execute returns DB_S_ERRORSOCCURRED or DB_E_ERRORSOCCURRED, the consumer can immediately call ICommandProperties::GetProperties with the DBPPROPSET_PROPERTIESINERROR property set to return the properties that could not be set.

Execute does not alter the value of any properties. That is, ICommandProperties::GetProperties returns the same value for a property regardless of whether it is called before or after Execute and whether Execute succeeded or failed. However, if a property value is not required, IRowsetInfo::GetProperties can return a different value for that property than ICommandProperties::GetProperties. For more information, see IRowsetInfo::GetProperties.

If several threads concurrently request execution of a given command, the corresponding executions are serialized, and each thread will block until its corresponding execution concludes.

See Also

ICommand::Cancel, ICommandText::SetCommandText


ICommand::GetDBSession

Returns an interface pointer to the session that created the command.

HRESULT GetDBSession (
   REFIID         riid,
   IUnknown **   ppSession);

Parameters

riid

[in]
The IID of the interface on which to return a pointer.

ppSession

[out]
A pointer to memory in which to return the interface pointer. If the provider does not have an object that created the command, it sets *ppSession to a null pointer. If GetDBSession fails, it must attempt to set *ppSession to a null pointer.

Return Code

S_OK
The method succeeded.

S_FALSE
The provider did not have an object that created the command. Therefore, it set *ppSession to a null pointer.

E_FAIL
A provider-specific error occurred.

E_INVALIDARG
ppSession was a null pointer.

E_NOINTERFACE
The session did not support the interface specified in riid.


ICommandPrepare

This optional interface encapsulates command optimization, a separation of compile time and run time, as found in traditional relational database systems. The result of this optimization is a command execution plan.

If the provider supports command preparation, by supporting this interface, commands must be in a prepared state prior to calling the following methods.

  • IColumnsInfo::GetColumnInfo

  • IColumnsInfo::MapColumnIDs
Method | Description
Prepare | Validates and optimizes the current command.
Unprepare | Discards the current command execution plan.


ICommandPrepare::Prepare

Validates and optimizes the current command.

HRESULT Prepare (
ULONG cExpectedRuns);

Parameters

cExpectedRuns

[in]
Using this parameter, the consumer can indicate how often the command execution plan, which is produced by Prepare, will be used; that is, how often the command is likely to be executed without renewed optimization. This guides the optimizer in determining tradeoffs between search effort and run-time processing effort. A value of zero indicates that the consumer is unable to provide an estimate, and leaves it to the optimizer to choose a default value.

Return Code

S_OK
The method succeeded.

DB_S_ERRORSOCCURRED
The command was prepared but one or more properties—for which the dwOptions element of the DBPROP structure was DBPROPOPTIONS_OPTIONAL—were not set. The consumer calls ICommandProperties::GetProperties to determine which properties were set.

E_FAIL
A provider-specific error occurred.

E_OUTOFMEMORY
The provider ran out of memory while preparing the command.

DB_E_ABORTLIMITREACHED
Preparation has been aborted because a resource limit has been reached. For example, the preparation timed out.

DB_E_ERRORSINCOMMAND
The command text contained one or more errors. Providers should use OLE DB error objects to return details about the errors.

DB_E_ERRORSOCCURRED
The command was not prepared because one or more properties—for which the dwOptions element of the DBPROP structure was DBPROPOPTIONS_REQUIRED—were not set. The consumer calls ICommandProperties::GetProperties to determine which properties were not set.

DB_E_NOCOMMAND
No command text was currently set on the Command object.

DB_E_OBJECTOPEN
A rowset was open on the command.

DB_SEC_E_PERMISSIONDENIED
The consumer did not have sufficient permission to prepare the command.

Comments

Although they are not required to do so, consumers should set any properties before calling Prepare, because these properties might be relevant to preparing the command.

If Prepare is called redundantly, the provider determines whether command optimization is reinvoked; the provider returns S_OK.

If Prepare returns DB_S_ERRORSOCCURRED or DB_E_ERRORSOCCURRED, the consumer can immediately call ICommandProperties::GetProperties with the DBPPROPSET_PROPERTIESINERROR property set to return the properties that could not be set.

See Also

ICommand::Execute, ICommandPrepare::Unprepare, ICommandWithParameters::SetParameterInfo


ICommandPrepare::Unprepare

Discards the current command execution plan.

HRESULT Unprepare();

Parameters

None.

Return Code

S_OK
The method succeeded.

E_FAIL
A provider-specific error occurred.

DB_E_OBJECTOPEN
A rowset was open on the command.

Comments

This method has no effect if the command was not prepared; the provider returns S_OK.

See Also

ICommandPrepare::Prepare


ICommandProperties

ICommandProperties specifies to the command the properties from the Rowset property group that must be supported by the rowsets returned by ICommand::Execute. A special case of these properties, and the ones most commonly requested, are the interfaces the rowset must support. In addition to interfaces, the consumer can request properties that modify the behavior of the rowset or interfaces.

All rowsets must support IRowset, IAccessor, IColumnsInfo, IRowsetInfo, and IConvertType. Providers may choose to return rowsets supporting other interfaces if doing so is possible and the support for the returned interfaces does not affect consumer code that is not expecting them. The riid parameter of ICommand::Execute should be one of the interfaces returned by IRowsetInfo::GetProperties.

This interface is mandatory on commands.

Method | Description
GetProperties | Returns the list of properties in the Rowset property group that are currently requested for the rowset.
SetProperties | Sets properties in the Rowset property group.


ICommandProperties::GetProperties

Returns the list of properties in the Rowset property group that are currently requested for the rowset.

HRESULT GetProperties (
   const ULONG            cPropertyIDSets,
   const DBPROPIDSET   rgPropertyIDSets[],
   ULONG *                  pcPropertySets,
   DBPROPSET **         prgPropertySets);

Parameters

cPropertyIDSets

[in]
The number of DBPROPIDSET structures in rgPropertyIDSets.

If cPropertySets is zero, the provider ignores rgPropertyIDSets and returns the values of all properties in the Rowset property group for which values have been set or defaults exist. It does not return the values of properties in the Rowset property group for which values have not been set and no defaults exist, nor does it return the values of properties for which no value has been set, nor default exists, and for which a value will be set automatically because a value for another property in the Rowset property group has been set.

If cPropertyIDSets is not zero, the provider returns the values of the requested properties. If a property is not supported, the returned value of dwStatus in the returned DBPROP structure for that property is DBPROPSTATUS_NOTSUPPORTED and the value of dwOptions is undefined.

rgPropertyIDSets

[in]
An array of cPropertyIDSets DBPROPIDSET structures. The properties specified in these structures must belong to the Rowset property group. The provider returns the values of the properties specified in these structures. If cPropertyIDSets is zero, then this parameter is ignored.

For information about the properties in the Rowset property group that are defined by OLE DB, see "Rowset Properties".

pcPropertySets

[out]
A pointer to memory in which to return the number of DBPROPSET structures returned in *prgPropertySets. If cPropertyIDSets is zero, *pcPropertySets is the total number of property sets for which the provider supports at least one property in the Rowset property group. If cPropertyIDSets is greater than zero, *pcPropertySets is set to cPropertyIDSets. If an error other than DB_E_ERRORSOCCURRED occurs, *pcPropertySets is set to zero.

prgPropertySets

[out]
A pointer to memory in which to return an array of DBPROPSET structures. If cPropertyIDSets is zero, then one structure is returned for each property set that contains at least one property belonging to the Rowset property group. If cPropertyIDSets is not zero, then one structure is returned for each property set specified in rgPropertyIDSets.

If cPropertyIDSets is not zero, the DBPROPSET structures in *prgPropertySets are returned in the same order as the DBPROPIDSET structures in rgPropertyIDSets; that is, for corresponding elements of each array, the guidPropertySet elements are the same. If cPropertyIDs, in an element of rgPropertyIDSets, is not zero, the DBPROP structures in the corresponding element of *prgPropertySets are returned in the same order as the DBPROPID values in rgPropertyIDs. Thus, in the case where no column properties are specified in rgPropertyIDSets, corresponding elements of the input rgPropertyIDs and the returned rgProperties have the same property ID. However, if a column property is requested in rgPropertyIDSets, multiple properties may be returned, one for each column, in rgProperties. In this case, corresponding elements of rgPropertyIDs and rgProperties will not have the same property ID, and rgProperties will contain more elements than rgPropertyIDs.

The provider allocates memory for the structures and returns the address to this memory; the consumer releases this memory with IMalloc::Free when it no longer needs the structures. Before calling IMalloc::Free for *prgPropertySets, the consumer should call IMalloc::Free for the rgProperties element within each element of *prgPropertySets. If *pcPropertySets is zero on output or an error other than DB_E_ERRORSOCCURRED occurs, the provider does not allocate any memory and ensures that *prgPropertySets is a null pointer on output.

Return Code

S_OK
The method succeeded. In all DBPROP structures returned by the method, dwStatus is set to DBPROPSTATUS_OK.

DB_S_ERRORSOCCURRED
No value was returned for one or more properties. The consumer checks dwStatus in the DBPROP structure to determine the properties for which values were not returned. GetProperties can fail to return properties for a number of reasons, including:

  • The property was not supported by the provider.

  • The property was not in the Rowset property group.

  • The property set was not supported by the provider. If cPropertyIDs in the DBPROPIDSET structure for the property set was zero, the provider cannot set dwStatus in the DBPROP structure because it does not know the IDs of any properties in the property set. Instead, it sets cProperties to zero in the DBPROPSET structure returned for the property set.

E_FAIL
A provider-specific error occurred.

E_INVALIDARG
cPropertyIDSets was not equal to zero and rgPropertyIDSets was a null pointer.

pcPropertySets or prgPropertySets was a null pointer.

In an element of rgPropertyIDSets, cPropertyIDs was not zero and rgPropertyIDs was a null pointer.

In an element of rgPropertyIDSets, guidPropertySet was DBPROPSET_PROPERTIESINERROR and cPropertyIDs was not zero, or rgPropertyIDs was not a null pointer.

cPropertyIDSets was greater than one and, in an element of rgPropertyIDSets, guidPropertySet was DBPROPSET_PROPERTIESINERROR.

E_OUTOFMEMORY
The provider was unable to allocate sufficient memory in which to return the DBPROPSET or DBPROP structures.

DB_E_ERRORSOCCURRED
No values were returned for any properties. The provider allocates memory for *prgPropertySets and the consumer checks dwStatus in the DBPROP structures to determine why properties were not returned. The consumer frees this memory when it no longer needs the information.

Comments

GetProperties returns the current values of properties that have been set by the consumer with ICommandProperties::SetProperties. For all values not set by the consumer, GetProperties returns the initial property value.

Even though IDBProperties::GetPropertyInfo lists a property as being supported by the provider, GetProperties will not return a value for it if it does not apply to the current circumstances. For example, the provider's ability to support the property might be affected by the current transaction or the current command text.

The property values returned by ICommandProperties::GetProperties are not affected by executing the command. However, IRowsetInfo::GetProperties might return a different value for a property than does ICommandProperties::GetProperties. For example, if a consumer requests ordered bookmarks if they are possible, it calls SetProperties to set the value of DBPROP_ORDEREDBOOKMARKS to VARIANT_TRUE and specifies a dwOptions value of DBPROPOPTIONS_OPTIONAL. If the provider cannot determine at this point in the definition of the command whether this is possible, ICommandProperties::GetProperties returns a value of VARIANT_TRUE and a dwOptions of DBPROPOPTIONS_OPTIONAL for this property. If the provider determines during optimization or execution that ordered bookmarks are not possible, IRowsetInfo::GetProperties returns a value of VARIANT_FALSE and a dwOptions of zero.

If ICommand::Execute returns DB_E_ERRORSOCCURRED, the consumer can immediately call GetProperties with the DBPROPSET_PROPERTIESINERROR property set to return all the properties that were in error.

See Also

ICommandProperties::SetProperties, IDBProperties::GetPropertyInfo, IRowsetInfo::GetProperties


ICommandProperties::SetProperties

Sets properties in the Rowset property group.

HRESULT SetProperties (
   ULONG         cPropertySets,
   DBPROPSET   rgPropertySets[]);

Parameters

cPropertySets

[in]
The number of DBPROPSET structures in rgPropertySets. If this is zero, the provider ignores rgPropertySets and the method does not do anything.

rgPropertySets

[in/out]
An array of DBPROPSET structures containing properties and values to be set. The properties specified in these structures must belong to the Rowset property group. If the same property is specified more than once in rgPropertySets, then which value is used is provider-specific. If cPropertySets is zero, this parameter is ignored.

For information about the properties in the Rowset property group that are defined by OLE DB, see "Rowset Properties".

Return Code

S_OK
The method succeeded. In all DBPROP structures passed to the method, dwStatus is set to DBPROPSTATUS_OK.

DB_S_ERRORSOCCURRED
One or more properties were not set. Properties not in error remain set. The consumer checks dwStatus in the DBPROP structures to determine which properties were not set. SetProperties can fail to set properties for a number of reasons, including:

  • The property was not supported by the provider.

  • The property was not in the Rowset property group.

  • The property set was not supported by the provider.

  • The property is read-only and was not set to its default value.

  • It was not possible to set the property.

  • The value of dwOptions in a DBPROP structure was invalid.

  • colid in the DBPROP structure was not DB_NULLID and the property cannot be set on a column.

  • The data type in vValue in the DBPROP structure was not the data type of the property or was not VT_EMPTY.

  • The value in vValue in the DBPROP structure was invalid.

  • The property's value conflicted with an existing property.

E_FAIL
A provider-specific error occurred.

E_INVALIDARG
cPropertySets was not equal to zero and rgPropertySets was a null pointer.

In an element of rgPropertySets, cProperties was not zero and rgProperties was a null pointer.

DB_E_ERRORSOCCURRED
All property values were invalid and no properties were set. The consumer checks dwStatus in the DBPROP structures to determine why properties were not set. The method can fail to set properties for any of the reasons specified in DB_S_ERRORSOCCURRED, except the reason that states that it was not possible to set the property.

DB_E_OBJECTOPEN
Properties cannot be set while there is an open rowset.

Comments

Consumers should first set properties for interfaces and then set other properties that modify those interfaces. The combination of the values of an interface property and a noninterface property might result in another interface being requested. However, the value of a noninterface property, by itself, never results in another interface being requested.

Setting property values is a cumulative operation. That is, each call to SetProperties attempts to change the values of the specified properties. If a new value is illegal or conflicts with the value of another property, the value of the property is not changed and SetProperties returns DBPROPSTATUS_BADVALUE or DBPROPSTATUS_CONFLICTING in the dwStatus element of the DBPROP structure for the property. Properties are processed from the beginning of the array to the end of the array. As they are processed, properties that conflict with previously set properties, including those set previously on the same call, are marked with DBPROPSTATUS_CONFLICTING, and processing continues through the array of properties.

SetProperties cannot always determine whether a property can be set to its requested value. For example, the provider often cannot determine whether the rowset is updatable until it creates the rowset. In this case, SetProperties appears to successfully set the property value and the provider delays the determination until ICommand::Execute is called.

If the value of dwOptions for a property is DBPROPOPTIONS_OPTIONAL, the provider attempts to determine whether it can set the property to the requested value. If it can make this determination, it sets the property and returns DBPROPSTATUS_OK or does not set the property and returns DBPROPSTATUS_NOTSET. If it cannot make this determination, it can delay setting the property until the command is executed; in this case, the value of dwOptions returned for the property by GetProperties is DBPROPOPTIONS_OPTIONAL.

Consumers should not attempt to unset mandatory rowset interfaces such as IRowset, IAccessor, IColumnsInfo, and IRowsetInfo. These interfaces are always supported, and SetProperties returns DBPROPSTATUS_NOTSETTABLE for them.

Even if IDBProperties::GetPropertyInfo lists a property as being supported by the provider, SetProperties can return DBPROPSTATUS_NOTSUPPORTED when the consumer attempts to set the property value if the property does not apply to the current circumstances. For example, the provider's ability to support the property might be affected by the current transaction or the current command text.

If an error occurs when setting a particular property, SetProperties flags the error in dwStatus in the DBPROP structure and continues processing.

Although providers allow changing properties at any time before command execution, consumers are encouraged to set all properties prior to preparing the command to avoid forcing the provider to reprepare the command at execution.

See Also

ICommandProperties::GetProperties, IDBProperties::GetPropertyInfo, IRowsetInfo::GetProperties


ICommandText : ICommand

This interface is mandatory on commands.

A command object can have only one text command. When the command text is specified through SetCommandText, it replaces the existing command text.

Method | Description
GetCommandText | Returns the text command set by the last call to SetCommandText.
SetCommandText | Sets the command text, replacing the existing command text.


ICommandText::GetCommandText

Returns the text command set by the last call to SetCommandText.

HRESULT GetCommandText (
   GUID *            pguidDialect,
   LPOLESTR *   ppwszCommand);

Parameters

pguidDialect

[in/out]
A pointer to memory containing a GUID that specifies the syntax and general rules for parsing the command text—that is, the dialect that will be used by the provider to interpret the statement. This is generally the dialect specified in SetCommandText. However, if DBGUID_DEFAULT is specified in SetCommandText, the provider returns the particular dialect that it will use to interpret the statement. If the provider determines between multiple dialects at execution time for a command that has been set with DBGUID_DEFAULT, or if the provider is returning some provider-specific syntax that may be different from the command set in SetCommandText, it returns DBGUID_DEFAULT. Providers can define GUIDs for their own dialects.

If GetCommandText returns an error, *pguidDialect is set to DB_NULLGUID.

ppwszCommand

[out]
A pointer to memory in which to return the command text. The command object allocates memory for the command text and returns the address to this memory. The consumer releases this memory with IMalloc::Free when it no longer needs the text. If GetCommandText returns an error, *ppwszCommand is set to a null pointer.

Return Code

S_OK
The method succeeded.

DB_S_DIALECTIGNORED
The method succeeded, but the input value of pguidDialect was ignored. The text is returned in the dialect specified in SetCommandText or the dialect that makes the most sense to the provider. The value returned in *pguidDialect represents that dialect.

E_FAIL
A provider-specific error occurred.

E_INVALIDARG
ppwszCommand was a null pointer.

E_OUTOFMEMORY
The provider was unable to allocate sufficient memory in which to return the command text.

DB_E_NOCOMMAND
No command text was currently set on the command object.

See Also

ICommandText::SetCommandText

Comments

The GUID returned in GetCommandText is the dialect that will be used by the provider to interpret the statement. This is generally the dialect specified in SetCommandText. However, if DBGUID_DEFAULT is specified in SetCommandText, the provider should return the particular dialect that it will use to interpret the statement. If the provider determines between multiple dialects at execution time for a command that has been set with DBGUID_DEFAULT, or if the provider is returning some provider-specific syntax that may be different from the command set in SetCommandText, it returns DBGUID_DEFAULT.


ICommandText::SetCommandText

Sets the command text, replacing the existing command text.

HRESULT SetCommandText (
   REFGUID         rguidDialect,
   LPCOLESTR   pwszCommand);

Parameters

rguidDialect

[in]
A GUID that specifies the syntax and general rules for the provider to use in parsing the command text. For a complete description of dialects, see GetCommandText.

pwszCommand

[in]
A pointer to the text of the command.

If *pwszCommand is an empty string ("") or pwszCommand is a null pointer, the current command text is cleared and the command is put in an unprepared state. Any properties that have been set on the command are unaffected; that is, they retain their current values. Methods that require a command, such as ICommand::Execute or IColumnsInfo::GetColumnsInfo, will return DB_E_NOCOMMAND until a new command text is set.

Return Code

S_OK
The method succeeded.

E_FAIL
A provider-specific error occurred.

DB_E_DIALECTNOTSUPPORTED
The provider did not support the dialect specified in rguidDialect.

DB_E_OBJECTOPEN
A rowset was open on the command.

Comments

A command object contains a single text command, usually an SQL statement. The new command text is copied into the command object; thus, the consumer can delete the original text without affecting the command object. All meaningful error checking, such as syntax checking and parsing, is deferred until ICommand::Execute is called. SetCommandText only verifies that the command text can be copied into the command object's space.

If the text of a prepared or unprepared command is overwritten with new command text, by calling SetCommandText, the command object is left in an unprepared state.

SetCommandText does not alter the value of any properties. That is, ICommandProperties::GetProperties returns the same value for a property regardless of whether it is called before or after SetCommandText and whether SetCommandText succeeded or failed. Furthermore, setting the command text does not reset parameter information set through SetParameterInfo.

See Also

ICommand::Execute, ICommandText::GetCommandText


ICommandWithParameters

Providers that support parameters must support ICommandWithParameters. Any provider that returns DBPROPVAL_SQL_ANSI92_INTERMEDIATE or DBPROPVAL_SQL_ANSI92_FULL for the DBPROP_SQLSUPPORT property can support parameters.

This optional interface encapsulates parameters. Parameters are scalar values, or a vector of scalar values, typically expressed in predicates but possibly supported by many providers in any scalar expression.

For scalar parameters of prepared commands, there is a presumption that different parameter values do not require different plans. In other words, a single preparation and its resulting plan are satisfactory for all possible values of scalar parameters.

Parameter values are set when a command is executed. Methods are included here to offer a means for setting and obtaining a list of parameters and their types.

Method | Description
GetParameterInfo | Gets a list of the command’s parameters, their names, and their types.
MapParameterNames | Returns an array of parameter ordinals when given named parameters.
SetParameterInfo | Specifies the native data type of each parameter.


ICommandWithParameters:: GetParameterInfo

Gets a list of the command’s parameters, their names, and their types.

HRESULT GetParameterInfo (
   ULONG *               pcParams,
   DBPARAMINFO **   prgParamInfo,
   OLECHAR **         ppNamesBuffer);

Parameters

pcParams

[out]
A pointer to memory in which to return the number of parameters in the command. If an error occurs, *pcParams is set to zero.

prgParamInfo

[out]
A pointer to memory in which to return an array of parameter information structures. The command allocates memory for the array, as well as the strings, and returns the address to this memory. The consumer releases the array memory with IMalloc::Free when it no longer needs the parameter information. If *pcParams is zero on output or an error occurs, the provider does not allocate any memory and ensures that *prgParamInfo is a null pointer on output. Parameters are returned in ascending order according to the iOrdinal element of the PARAMINFO structure.

Here is the DBPARAMINFO structure:

typedef struct tagDBPARAMINFO {
 DBPARAMFLAGS dwFlags;
 ULONG    iOrdinal;
 LPOLESTR   pwszName;
 ITypeInfo *  pTypeInfo;
 ULONG    ulParamSize;
 DBTYPE   wType;
 BYTE     bPrecision;
 BYTE     bScale;
} DBPARAMINFO;

The elements of this structure are used as follows.

Element | Description
dwFlags A bitmask describing parameter characteristics; these values have the following meaning:
  • DBPARAMFLAGS_ISINPUT—Whether a parameter accepts values on input. Not set if this is unknown.

  • DBPARAMFLAGS_ISOUTPUT—Whether a parameter returns values on output. Not set if this is unknown. Providers support only those parameter types that make sense for their data source.
dwFlags
(continued)
  • DBPARAMFLAGS_ISSIGNED—Whether a parameter is signed. This is ignored if the type is inherently signed, such as DBTYPE_I2, or if the sign does not apply to the type, such as DBTYPE_BSTR. It is generally used in SetParameterInfo so the consumer can tell the provider if a provider-specific type name refers to a signed or unsigned type.

  • DBPARAMFLAGS_ISNULLABLE—Whether a parameter accepts NULLs. If nullability is unknown, this flag is set.

  • DBPARAMFLAGS_ISLONG—Whether a parameter contains a BLOB that contains very long data. The definition of very long data is provider specific. The flag setting corresponds to the value of the IS_LONG column in the PROVIDER_TYPES schema rowset for the data type.

    When this flag is set, the BLOB is best manipulated through one of the storage interfaces. Although such BLOBs can be sent in a single piece with ICommand::Execute, there may be provider-specific problems in doing so. For example, the BLOB might be truncated due to machine limits on memory. Furthermore, when this flag is set, the provider might not be able to accurately return the maximum length of the BLOB data in ulParamSize in GetParameterInfo.

    When this flag is not set, the BLOB can be accessed either through ICommand::Execute or through a storage interface.
iOrdinal | The ordinal of the parameter. Parameters are numbered from left to right as they appear in the command, with the first parameter in the command having an iOrdinal value of 1.
pwszName | The name of the parameter; it is a null pointer if there is no name. Names are normal names. The colon prefix (where used within SQL text) is stripped.
pTypeInfo | ITypeInfo describes the type, if pTypeInfo is not a null pointer.
ulParamSize The maximum possible length of a value in the parameter. For parameters that use a fixed-length data type, this is the size of the data type. For parameters that use a variable-length data type, this is one of the following:
  • The maximum length of the parameters in characters, for DBTYPE_STR and DBTYPE_WSTR, or bytes, for DBTYPE_BYTES, if one is defined. For example, a parameter for a CHAR(5) column in an SQL table has a maximum length of 5.

  • The maximum length of the data type in characters, for DBTYPE_STR and DBTYPE_WSTR, or bytes, for DBTYPE_BYTES, if the parameter does not have a defined length.

  • ~0 (bitwise, the value is not 0; that is, all bits are set to 1) if neither the parameter nor the data type has a defined maximum length.

For data types that do not have a length, this is set to ~0 (bitwise, the value is not 0; that is, all bits are set to 1).

wType | The indicator of the parameter’s data type.
bPrecision | If wType is a numeric type, bPrecision is the maximum number of digits, expressed in base 10. Otherwise, this is ~0 (bitwise, the value is not 0; that is, all bits are set to 1).
bScale | If wType is a numeric type with a fixed scale, bScale is the number of digits to the right, if bScale is positive, or left, if bScale is negative, of the decimal point. Otherwise, this is ~0 (bitwise, the value is not 0; that is, all bits are set to 1).

ppNamesBuffer

[out]
A pointer to memory in which to store all string values (names used within the *pwszName element of the DBPARAMINFO structures) with a single, globally allocated buffer. Specifying a null pointer for ppNamesBuffer suspends the return of parameter names. The command allocates memory for the buffer and returns the address to this memory. The consumer releases the memory with IMalloc::Free when it no longer needs the parameter information. If *pcParams is zero on output or an error occurs, the provider does not allocate any memory and ensures that *ppNamesBuffer is a null pointer on output.

Each of the individual string values stored in this buffer is terminated by a null termination character. Therefore, the buffer may contain one or more strings, each with its own null termination character, and may contain embedded null termination characters.

Return Code

S_OK
The method succeeded.

E_FAIL
A provider-specific error occurred.

E_INVALIDARG
pcParams or prgParamInfo was a null pointer.

E_OUTOFMEMORY
The provider was unable to allocate sufficient memory in which to return the parameter data array or parameter names.

DB_E_NOCOMMAND
The provider can derive parameter information, but it does not support command preparation. However, no command text was currently set on the Command object and no parameter information had been specified with SetParameterInfo.

DB_E_NOTPREPARED
The provider can derive parameter information, and it supports command preparation. However, the command was in an unprepared state and no parameter information was specified with SetParameterInfo.

DB_E_PARAMUNAVAILABLE
The provider cannot derive parameter information from the command and SetParameterInfo has not been called.

Comments

This method makes no logical change to the state of the object.

If SetParameterInfo has not been called for any parameters or SetParameterInfo has been called with cParams equal to zero, GetParameterInfo returns information about the parameters only if the provider can derive parameter information. If the provider cannot derive parameter information, GetParameterInfo returns DB_E_PARAMUNAVAILABLE.

If SetParameterInfo has been called for at least one parameter, GetParameterInfo returns the parameter information only for those parameters for which SetParameterInfo has been called. It does this even if the provider can derive information about the parameters for which SetParameterInfo was not called. The provider does not return a warning in this case because it often cannot determine the number of parameters and therefore cannot determine whether it has returned information for all parameters.

See Also

ICommandWithParameters::MapParameterNames, ICommandWithParameters::SetParameterInfo


ICommandWithParameters:: MapParameterNames

Returns an array of parameter ordinals when given named parameters.

HRESULT MapParameterNames (
   ULONG               cParamNames,
   const OLECHAR *      rgParamNames[],
   LONG                  rgParamOrdinals[]);

Parameters

cParamNames

[in]
The number of parameter names to map. If cParamNames is zero, MapParameterNames does nothing and returns S_OK.

rgParamNames

[in]
An array of parameter names of which to determine the parameter ordinals. If a parameter name is not found, the corresponding element of rgParamOrdinals is set to zero and the method returns DB_S_ERRORSOCCURRED.

rgParamOrdinals

[out]
An array of cParamNames ordinals of the parameters identified by the elements of rgParamNames. The consumer allocates (but is not required to initialize) memory for this array and passes the address of this memory to the provider. The provider returns the parameter ordinals in the array.

Return Code

S_OK
The method succeeded. Each element of rgParamOrdinals is set to a nonzero value.

DB_S_ERRORSOCCURRED
An element of rgParamNames was invalid. The corresponding element of rgParamOrdinals is set to zero.

E_FAIL
A provider-specific error occurred.

E_INVALIDARG
cParamNames was not zero and rgParamNames or rgParamOrdinals was a null pointer.

DB_E_ERRORSOCCURRED
All elements of rgParamNames were invalid. All elements of rgParamOrdinals are set to zero.

DB_E_NOCOMMAND
No command text was currently set on the Command object and no parameter information had been specified with SetParameterInfo.

DB_E_NOTPREPARED
The provider can derive parameter information and supports command preparation. However, the command was in an unprepared state and no parameter information had been specified with SetParameterInfo.

See Also

ICommandWithParameters::GetParameterInfo


ICommandWithParameters:: SetParameterInfo

Specifies the native data type of each parameter.

HRESULT SetParameterInfo (
   ULONG                        cParams,
   const ULONG                  rgParamOrdinals[],
   const DBPARAMBINDINFO   rgParamBindInfo[]);

Parameters

cParams

[in]
The number of parameters for which to set type information. If cParams is zero, the type information for all parameters is discarded, and rgParamOrdinals and rgParamBindInfo are ignored.

rgParamOrdinals

[in]
An array of cParams ordinals. These are the ordinals of the parameters for which to set type information. Type information for parameters whose ordinals are not specified is not affected.

rgParamBindInfo

[in]
An array of cParams DBPARAMBINDINFO structures. If rgParamBindInfo is a null pointer, then the type information for the parameters specified by the ordinals in rgParamOrdinals is discarded.

The DBPARAMBINDINFO structure is:

typedef struct tagDBPARAMBINDINFO {
 LPOLESTR   pwszDataSourceType;
 LPOLESTR   pwszName;
 ULONG    ulParamSize;
 DBPARAMFLAGS dwFlags;
 BYTE     bPrecision;
 BYTE     bScale;
} DBPARAMBINDINFO;

The elements of this structure are used as follows.

Element | Description
pwszDataSourceType A pointer to the provider-specific name of the parameter’s data type or a standard data type name. This name is not returned by GetParameterInfo; instead, the provider maps the data type specified by this name to an OLE DB type indicator and returns that type indicator. For a list of standard data type names, see ""Comments.""

If pwszDataSourceType is null, the provider attempts a default conversion from the data type specified in the binding for the parameter, or returns E_INVALIDARG if it cannot perform default parameter conversions.

pwszName The name of the parameter. This is a null pointer if the parameter does not have a name.

The consumer must specify a name for all or none of the parameters set at any time. If the provider does not support named parameters, this argument is ignored and the provider is not required to verify that all or none of the parameters are named.

ulParamSize The maximum possible length of a value in the parameter. For parameters that use a fixed-length data type, this is the size of the data type. For parameters that use a variable-length data type, this is one of the following:
  • The maximum length of the parameters in characters, for DBTYPE_STR and DBTYPE_WSTR, or bytes, for DBTYPE_BYTES, if one is defined. For example, a parameter for a CHAR(5) column in an SQL table has a maximum length of 5.

  • The maximum length of the data type in characters, for DBTYPE_STR and DBTYPE_WSTR, or bytes, for DBTYPE_BYTES, if the parameter does not have a defined length.

  • ~0 (bitwise, the value is not 0; that is, all bits are set to 1) if neither the parameter nor the data type has a defined maximum length.

For data types that do not have a length, this is set to ~0 (bitwise, the value is not 0; that is, all bits are set to 1).

This argument is ignored if pwszDataSourceType is null.

dwFlags | See the dwFlags element of the DBPARAMINFO structure in GetParameterInfo.
bPrecision If pwszDataSourceType is a numeric type, bPrecision is the maximum number of digits, expressed in base 10. Otherwise, it is ignored.

This argument is ignored if pwszDataSourceType is null.

bScale If pwszDataSourceType is a numeric type with a fixed scale, bScale is the number of digits to the right (if bScale is positive) or left (if bScale is negative) of the decimal point. Otherwise, it is ignored.

This argument is ignored if pwszDataSourceType is null.

Return Code

S_OK
The method succeeded.

DB_S_TYPEINFOOVERRIDDEN
The provider was capable of deriving the parameter type information and SetParameterInfo was called. The parameter type information specified in SetParameterInfo was used.

SetParameterInfo replaced parameter type information specified in a previous call to SetParameterInfo.

E_FAIL
A provider-specific error occurred.

E_INVALIDARG
cParams was not zero and rgParamOrdinals was a null pointer.

An element of rgParamOrdinals was zero.

In an element of rgParamBindInfo, the pwszDataSourceType element was a null pointer, and the provider does not support default parameter conversions.

In an element of rgParamBindInfo, the dwFlags element was invalid.

DB_E_BADPARAMETERNAME
In an element of rgParamBindInfo, the pwszName element specified an invalid parameter name. The provider does not check whether the name was correct for the specified parameter, just whether it was a valid parameter name.

In one or more elements of rgParamBindInfo, but not all, pwszName was null.

In one or more elements of rgParamBindInfo, pwszName was null and one or more parameters previously set and not overridden were specified with a non-null pwszName.

In one or more elements of rgParamBindInfo, pwszName was non-null and one or more parameters previously set and not overridden were specified with a null pwszName.

DB_E_BADTYPENAME
In an element of rgParamBindInfo, the pwszDataSourceType element specified an invalid data type name. The provider does not check whether the data type was correct for the specified parameter, just whether it was a data type name supported by the provider.

DB_E_OBJECTOPEN
A rowset was open on the command.

Comments

Providers generally derive parameter type information from the data source and return it to the consumer through GetParameterInfo. Consumers then use this information to build parameter accessors for use with ICommand::Execute.

Some providers—notably many SQL database providers—cannot derive parameter type information from the data source. For these providers, the consumer must supply the native parameter type information through SetParameterInfo. The provider uses the type information specified by SetParameterInfo to determine how to convert parameter data from the type supplied by the consumer (as indicated by the wType value in the binding structure) to the native type used by the data source. When the consumer specifies a data type with known precision, scale, and size values, any information supplied by the consumer for precision, scale, or size should be ignored by the provider.

The information that the consumer supplies must be correct and must be supplied for all parameters. Providers that cannot derive parameter type information cannot verify the supplied information against the parameter metadata, although they can determine that the specified values are legal values for the provider. Such providers sometimes cannot even determine the number of parameters in the command. The result of executing a command using incorrect parameter information or passing parameter information for the wrong number of parameters is undefined. For example, if the parameter type is LONG and the consumer specifies a type indicator of DBTYPE_STR in SetParameterInfo, the provider converts the data to a string before sending it to the data source. Because the data source is expecting a LONG, this will likely result in an error.

When the consumer calls SetParameterInfo, it specifies a provider-specific data type name (as derived from the PROVIDER_TYPES schema rowset) or a standard type name. If the consumer passes a standard type name, the provider maps it to a provider-specific type name. For example, a provider for an SQL DBMS might map ""DBTYPE_I2"" to ""SMALLINT"".

The following is a list of standard type names and their associated type indicators. This list contains many commonly known types. Individual providers may allow other, provider-specific names as well.

Standard type name | Type indicator
""DBTYPE_I1"" | DBTYPE_I1
"DBTYPE_I2" | DBTYPE_I2
"DBTYPE_I4" | DBTYPE_I4
"DBTYPE_I8" | DBTYPE_I8
"DBTYPE_UI1" | DBTYPE_UI1
"DBTYPE_UI2" | DBTYPE_UI2
"DBTYPE_UI4" | DBTYPE_UI4
"DBTYPE_UI8" | DBTYPE_UI8
"DBTYPE_R4" | DBTYPE_R4
"DBTYPE_R8" | DBTYPE_R8
"DBTYPE_CY" | DBTYPE_CY
"DBTYPE_DECIMAL" | DBTYPE_DECIMAL
"DBTYPE_NUMERIC" | DBTYPE_NUMERIC
"DBTYPE_BOOL" | DBTYPE_BOOL
"DBTYPE_ERROR" | DBTYPE_ERROR
"DBTYPE_UDT" | DBTYPE_UDT
"DBTYPE_VARIANT" | DBTYPE_VARIANT
"DBTYPE_IDISPATCH" | DBTYPE_IDISPATCH
"DBTYPE_IUNKNOWN" | DBTYPE_IUNKNOWN
"DBTYPE_GUID" | DBTYPE_GUID
"DBTYPE_DATE" | DBTYPE_DATE
"DBTYPE_DBDATE" | DBTYPE_DBDATE
"DBTYPE_DBTIME" | DBTYPE_DBTIME
"DBTYPE_DBTIMESTAMP" | DBTYPE_DBTIMESTAMP
"DBTYPE_BSTR" | DBTYPE_BSTR
"DBTYPE_CHAR" | DBTYPE_STR
"DBTYPE_VARCHAR" | DBTYPE_STR
"DBTYPE_LONGVARCHAR" | DBTYPE_STR
"DBTYPE_WCHAR" | DBTYPE_WSTR
"DBTYPE_WVARCHAR" | DBTYPE_WSTR
"DBTYPE_WLONGVARCHAR" | DBTYPE_WSTR
"DBTYPE_BINARY" | DBTYPE_BYTES
"DBTYPE_VARBINARY" | DBTYPE_BYTES
"DBTYPE_LONGVARBINARY" | DBTYPE_BYTES

After the consumer calls SetParameterInfo to specify the parameter type information, it can call GetParameterInfo to retrieve the type indicator for each parameter. These values—which are based on the information specified in SetParameterInfo—represent the best fit of OLE DB types to the native parameter types. The provider guarantees that, if the consumer uses these types in a parameter accessor, it will be able to convert the data from the OLE DB type to the native parameter type.

If the provider can derive parameter type information and the consumer calls SetParameterInfo, SetParameterInfo uses the specified type information and returns DB_S_TYPEINFOOVERRIDDEN. Because deriving type information can be an expensive operation, this may result in more efficient code.

See Also

ICommandWithParameters::GetParameterInfo


IConvertType

This interface is mandatory on commands, rowsets, and index rowsets.

This interface contains a single method that gives information about the availability of type conversions on a command or on a rowset.

Method | Description
CanConvert | Gives information about the availability of type conversions on a command or on a rowset.


IConvertType::CanConvert

Gives information about the availability of type conversions on a command or on a rowset.

HRESULT CanConvert (
   DBTYPE                  wFromType,
   DBTYPE                  wToType,
   DBCONVERTFLAGS   dwConvertFlags);

Parameters

wFromType

[in]
The source type of the conversion.

wToType

[in]
The target type of the conversion.

dwConvertFlags

[in]
Whether CanConvert is to determine if the conversion is supported on the rowset or on the command. These flags have the following meaning:

Value | Description
DBCONVERTFLAGS_ COLUMN | CanConvert is to determine if the conversion is supported when setting, getting, finding, filtering, or seeking on columns of the rowset. This flag is mutually exclusive with DBCONVERTFLAGS_PARAMETER.
DBCONVERTFLAGS_ ISFIXEDLENGTH | CanConvert is to determine a fixed length value of the DBTYPE specified in the dwFromType can be converted to the DBTYPE specified in wToType. This flag can coexist with either DBCONVERTFLAGS_COLUMN or DBCONVERTFLAGS_PARAMETER. This flag is only supported by OLE DB version 2.0 or greater providers.
DBCONVERTFLAGS_ ISLONG | CanConvert is to determine if the long version of the DBTYPE specified in the dwFromType can be converted to the DBTYPE specified in wToType. This flag is only valid when used in conjunction with a variable-length DBTYPE. This flag can coexist with either DBCONVERTFLAGS_COLUMN or DBCONVERTFLAGS_PARAMETER. This flag is only supported by OLE DB version 2.0 or greater providers.
DBCONVERTFLAGS_ PARAMETER | CanConvert is to determine if the conversion is supported on the parameters of the command.
DBCONVERTFLAGS_ FROMVARIANT | The DBTYPE specified in the wFromType represents a type within a VARIANT. CanConvert returns whether the conversion from a VARIANT of that type to the type specified in wToType is allowed.

Return Code

S_OK

The requested conversion is available.

S_FALSE

The requested conversion is not available.

wFromType or wToType were not valid types for the provider, and the provider was a version 2.0 or greater provider.

E_FAIL

A provider-specific error occurred.

E_INVALIDARG

The provider was an OLE DB 1.x provider and wFromType or wToType was not a valid type indicator for OLE DB 1.x .

DB_E_BADCONVERTFLAG

dwConvert flags was invalid.

The method was called on a command and its flags inquired about a conversion on a rowset, but the property DBPROP_ROWSETCONVERSIONSONCOMMAND was VARIANT_FALSE.

The DBCONVERTFLAG_PARAMETER bit was set and CanConvert was called on a rowset.

The DBCONVERTFLAGS_PARAMETER bit was set and CanConvert was called on a command (whether from a provider or not) that does not support parameters.

DBCONVERTFLAGS_ISLONG was specified, and the DBTYPE specified in dwFromType was not a variable-length DBTYPE.

DBCONVERTFLAGS_ISLONG was specified, and the provider was an OLE DB 1.x provider.

DBCONVERTFLAGS_ISFIXEDLENGTH was specified, and the provider was an OLE DB 1.x provider.

DB_E_BADTYPE

DBCONVERTFLAGS_FROMVARIANT was specified and the type specified in wFromType was not a VARIANT type.

Comments

CanConvert can be called from a command or a rowset. The consumer can call it on a command to inquire about conversions supported by that command and on a rowset to inquire about conversions supported by that rowset. The consumer might be able to call it on a command to inquire about conversions supported on rowsets generated from that command; whether this is supported is specified by the DBPROP_ROWSETCONVERSIONSONCOMMAND property.

Note that converting a value to or from DBTYPE_IUNKNOWN is different than requesting a stream over the value, even though streams are bound using DBTYPE_IUNKNOWN. Providers typically don't support conversion of character or binary values to and from DBTYPE_IUNKOWN, even though they may support binding such objects as streams.

See Also

IAccessor::CreateAccessor


IDBCreateCommand

Consumers call IDBCreateCommand::CreateCommand on a session to obtain a new command.

Method | Description
CreateCommand | Creates a new command.


IDBCreateCommand::CreateCommand

Creates a new command.

HRESULT CreateCommand(
   IUnknown *   pUnkOuter,
   REFIID         riid,
   IUnknown **   ppCommand);

Parameters

pUnkOuter

[in]
A pointer to the controlling IUnknown interface if the new command is being created as part of an aggregate. It is a null pointer if the command is not part of an aggregate.

riid

[in]
The IID of the interface requested on the command.

ppCommand

[out]
A pointer to memory in which to return the interface pointer on the newly created command.

Return Code

S_OK
The method succeeded.

E_FAIL
A provider-specific error occurred.

E_INVALIDARG
ppCommand was a null pointer.

E_NOINTERFACE
The command did not support the interface specified in riid.

E_OUTOFMEMORY
The provider did not have enough memory to create the command.

DB_E_NOAGGREGATION
pUnkOuter was not a null pointer and the command being created does not support aggregation.

pUnkOuter was non-null and riid was not IID_Unknown.

DB_E_OBJECTOPEN
The provider would have to open a new connection to support the operation and DBPROP_MULTIPLECONNECTIONS is set to VARIANT_FALSE.

Comments

If the session is transacted, the command and any actions performed as a result of executing that command are within the scope of the transaction.

See Also

ICommand


IDBCreateSession

Consumers call IDBCreateSession::CreateSession on a data source object to obtain a new session.

Method | Description
CreateSession | Creates a new session from the data source object and returns the requested interface on the newly created session.


IDBCreateSession::CreateSession

Creates a new session from the data source object and returns the requested interface on the newly created session.

HRESULT CreateSession (
   IUnknown *   pUnkOuter,
   REFIID         riid,
   IUnknown **   ppDBSession);

Parameters

pUnkOuter

[in]
A pointer to the controlling IUnknown interface if the new session is being created as part of an aggregate. It is a null pointer if the session is not part of an aggregate.

riid

[in]
The IID of the interface.

ppDBSession

[out]
A pointer to memory in which to return the interface pointer.

Return Code

S_OK
The method succeeded.

E_FAIL
A provider-specific error occurred.

E_INVALIDARG
ppDBSession was a null pointer.

E_NOINTERFACE
The session did not support the interface specified in riid.

E_OUTOFMEMORY
The provider did not have enough memory to create the session.

E_UNEXPECTED
The data source object was in an uninitialized state.

DB_E_NOAGGREGATION
pUnkOuter was not a null pointer and the session being created does not support aggregation.

pUnkOuter was non-null and riid was not IID_Unknown.

DB_E_OBJECTCREATIONLIMITREACHED
The maximum number of sessions supported by the provider has already been created. The consumer must release one or more currently held sessions before obtaining a new session object. This error is only returned by providers that have a fixed maximum number of sessions as returned by DBPROP_ACTIVESESSIONS. It is not returned due to other resource constraints, such as available memory (for which the provider returns E_OUTOFMEMORY).

DB_E_OBJECTOPEN
The provider would have to open a new connection to support the operation and DBPROP_MULTIPLECONNECTIONS is set to VARIANT_FALSE.

See Also

IDBProperties::GetPropertyInfo, ISessionProperties::SetProperties


IDBInfo

IDBInfo returns information about the keywords and literals a provider supports. It is an optional interface on the data source objects.

Method | Description
GetKeywords | Returns a list of provider-specific keywords.
GetLiteralInfo | Returns information about literals used in text commands and in table and index definitions.


IDBInfo::GetKeywords

Returns a list of provider-specific keywords.

HRESULT GetKeywords(
   LPOLESTR *   ppwszKeywords);

Parameters

ppwszKeywords

[out]
A pointer to memory in which to return the address of a string. The string contains a comma-separated list of all keywords unique to this provider; that is, a comma-separated list of keywords that are not in the list in the Comments section. If there are no keywords unique to this provider, or if an error occurs, the provider sets *ppwszKeywords to a null pointer.

The provider allocates memory for the string and returns the address to this memory; the consumer releases this memory with IMalloc::Free when it no longer needs the string.

Return Code

S_OK
The method succeeded.

E_FAIL
A provider-specific error occurred.

E_INVALIDARG
ppwszKeywords was a null pointer.

E_OUTOFMEMORY
The provider was unable to allocate sufficient memory in which to return the keywords.

E_UNEXPECTED
The data source object was in an uninitialized state.

Comments

The following table lists the keywords from OLE DB.

ABSOLUTE | INTO
ACTION | IS
ADD | ISOLATION
ALL | JOIN
ALLOCATE | KEY
ALTER | LANGUAGE
AND | LAST
ANY | LEADING
ARE | LEFT
AS | LEVEL
ASC | LIKE
ASSERTION | LOCAL
AT | LOWER
AUTHORIZATION | MATCH
AVG | MAX
BEGIN | MIN
BETWEEN | MINUTE
BIT | MODULE
BIT_LENGTH | MONTH
BOTH | NAMES
BY | NATIONAL
CASCADE | NATURAL
CASCADED | NCHAR
CASE | NEXT
CAST | NO
CATALOG | NOT
CHAR | NULL
CHAR_LENGTH | NULLIF
CHARACTER | NUMERIC
CHARACTER_LENGTH | OCTET_LENGTH
CHECK | OF
CLOSE | ON
COALESCE | ONLY
COLLATE | OPEN
COLLATION | OPTION
COLUMN | OR
COMMIT | ORDER
CONNECT | OUTER
CONNECTION | OUTPUT
CONSTRAINT | OVERLAPS
CONSTRAINTS | PARTIAL
CONTINUE | POSITION
CONVERT | PRECISION
CORRESPONDING | PREPARE
COUNT | PRESERVE
CREATE | PRIMARY
CROSS | PRIOR
CURRENT | PRIVILEGES
CURRENT_DATE | PROCEDURE
CURRENT_TIME | PUBLIC
CURRENT_TIMESTAMP | READ
CURRENT_USER | REAL
CURSOR | REFERENCES
DATE | RELATIVE
DAY | RESTRICT
DEALLOCATE | REVOKE
DEC | RIGHT
DECIMAL | ROLLBACK
DECLARE | ROWS
DEFAULT | SCHEMA
DEFERRABLE | SCROLL
DEFERRED | SECOND
DELETE | SECTION
DESC | SELECT
DESCRIBE | SESSION
DESCRIPTOR | SESSION_USER
DIAGNOSTICS | SET
DISCONNECT | SIZE
DISTINCT | SMALLINT
DISTINCTROW | SOME
DOMAIN | SQL
DOUBLE | SQLCODE
DROP | SQLERROR
ELSE | SQLSTATE
END | SUBSTRING
END-EXEC | SUM
ESCAPE | SYSTEM_USER
EXCEPT | TABLE
EXCEPTION | TEMPORARY
EXEC | THEN
EXECUTE | TIME
EXISTS | TIMESTAMP
EXTERNAL | TIMEZONE_HOUR
EXTRACT | TIMEZONE_MINUTE
FALSE | TO
FETCH | TRAILING
FIRST | TRANSACTION
FLOAT | TRANSLATE
FOR | TRANSLATION
FOREIGN | TRIGGER
FOUND | TRIM
FROM | TRUE
FULL | UNION
GET | UNIQUE
GLOBAL | UNKNOWN
GO | UPDATE
GOTO | UPPER
GRANT | USAGE
GROUP | USER
HAVING | USING
HOUR | VALUE
IDENTITY | VALUES
IMMEDIATE | VARCHAR
IN | VARYING
INDICATOR | VIEW
INITIALLY | WHEN
INNER | WHENEVER
INPUT | WHERE
INSENSITIVE | WITH
INSERT | WORK
INT | WRITE
INTEGER | YEAR
INTERSECT | ZONE
INTERVAL |

See Also

IDBInfo::GetLiteralInfo, IDBProperties::GetProperties


IDBInfo::GetLiteralInfo

Returns information about literals used in text commands, ITableDefinition, IIndexDefinition, and IOpenRowset, or any interface that takes DBIDs as arguments.

HRESULT GetLiteralInfo(
   ULONG                  cLiterals,
   const DBLITERAL         rgLiterals[],
   ULONG *                  pcLiteralInfo,
   DBLITERALINFO **   prgLiteralInfo,
   OLECHAR **            ppCharBuffer);

Parameters

cLiterals

[in]
The number of literals being asked about. If this is 0, the provider ignores rgLiterals and returns information about all of the literals it supports.

rgLiterals

[in]
An array of cLiterals literals about which to return information. If the consumer specifies an invalid DBLITERAL value in this array, GetLiteralInfo returns FALSE in fSupported in the corresponding element of the *prgLiteralInfo array.

If cLiterals is 0, this parameter is ignored.

pcLiteralInfo

[out]
A pointer to memory in which to return the number of literals for which information was returned. If cLiterals is 0, this is the total number of literals supported by the provider. If an error other than DB_E_ERRORSOCCURRED occurs, *pcLiteralInfo is set to 0.

prgLiteralInfo

[out]
A pointer to memory in which to return a pointer to an array of DBLITERALINFO structures. One structure is returned for each literal. The provider allocates memory for the structures and returns the address to this memory; the consumer releases this memory with IMalloc::Free when it no longer needs the structures. If *pcLiteralInfo is 0 on output or an error other than DB_E_ERRORSOCCURRED occurs, the provider does not allocate any memory and ensures that *prgLiteralInfo is a null pointer on output. For information about DBLITERALINFO structures, see the Comments section.

ppCharBuffer

[out]
A pointer to memory in which to return a pointer for all string values (pwszLiteralValue, pwszInvalidChars, and pwszInvalidStartingChars) within a single allocation block. The provider allocates this memory and the consumer releases it with IMalloc::Free when it no longer needs it. If *pcLiteralInfo is 0 on output or an error occurs, the provider does not allocate any memory and ensures that *ppCharBuffer is a null pointer on output. Each of the individual string values stored in this buffer is terminated by a null-termination character. Therefore, the buffer may contain one or more strings, each with its own null-termination character, and may contain embedded null-termination characters.

Return Code

S_OK
The method succeeded. In each structure returned in *prgLiteralInfo, the fSupported element is set to TRUE.

DB_S_ERRORSOCCURRED
rgLiterals contained at least one unsupported or invalid literal. In the structures returned in *prgLiteralInfo for unsupported or invalid literals, the fSupported element is set to FALSE.

E_FAIL
A provider-specific error occurred.

E_INVALIDARG
cLiterals was not equal to zero and rgLiterals was a null pointer.

pcLiteralInfo, prgLiteralInfo, or ppCharBuffer was a null pointer.

E_OUTOFMEMORY
The provider was unable to allocate sufficient memory in which to return the DBLITERALINFO structures or the strings containing the valid and starting characters.

E_UNEXPECTED
The data source object was in an uninitialized state.

DB_E_ERRORSOCCURRED
All literals were either invalid or unsupported. The provider allocates memory for *prgLiteralInfo and sets the value of the fSupported element in all of the structures to FALSE. The consumer frees this memory when it no longer needs the information.

Comments

In the context of GetLiteralInfo, a literal is one of several things:

  • A special character or characters used by text commands, such as the character used to quote identifiers. GetLiteralInfo returns the character or characters.

  • A literal data value, such as a character literal in an SQL statement. For such literal data values, GetLiteralInfo returns the maximum length of the literal in characters, a list of the characters that cannot be used in the literal, and a list of the characters that cannot be used as the first character of the literal.

  • The name of a database object such as a column or table. For such names, GetLiteralInfo returns the maximum length of the name in characters, a list of the characters that cannot be used in the name, and a list of the characters that cannot be used as the first character of the name.

Information about literals is returned in the DBLITERALINFO structure:

typedef struct tagDBLITERALINFO {
 LPOLESTR  pwszLiteralValue;
 LPOLESTR  pwszInvalidChars;
 LPOLESTR  pwszInvalidStartingChars;
 DBLITERAL lt;
 BOOL    fSupported;
 ULONG   cchMaxLen;
} DBLITERALINFO;

The elements of this structure are used as follows.

Element | Description
pwszLiteralValue | A pointer to a string in the *ppCharBuffer buffer containing the actual literal value. For example, if lt is DBLITERAL_LIKE_PERCENT, and the percent character (%) is used to match zero or more characters in a LIKE clause, this would be "%". This is used for DBLITERAL_CATALOG_SEPARATOR, DBLITERAL_ESCAPE_PERCENT_PREFIX, DBLITERAL_ESCAPE_UNDERSCORE_PREFIX, DBLITERAL_LIKE_PERCENT, DBLITERAL_LIKE_UNDERSCORE, DBLITERAL_QUOTE_PREFIX, and DBLITERAL_SCHEMA_SEPARATOR. For all other DBLITERAL values, pwszLiteralValue is not used and is set to a null pointer.
pwszInvalidChars | A pointer to a string in the *ppCharBuffer buffer containing the characters that are not valid in the literal. For example, if table names can contain anything other than a numeric character, this would be "0123456789" when lt is DBLITERAL_TABLE_NAME. If the literal can contain any valid character, this is a null pointer. This is not used for DBLITERAL_BINARY_LITERAL, DBLITERAL_CATALOG_SEPARATOR, DBLITERAL_ESCAPE_PERCENT_PREFIX, DBLITERAL_ESCAPE_UNDERSCORE_PREFIX, DBLITERAL_LIKE_PERCENT, DBLITERAL_LIKE_UNDERSCORE, DBLITERAL_QUOTE_PREFIX, and DBLITERAL_SCHEMA_SEPARATOR; pwszInvalidChars is set to a null pointer for these DBLITERAL values.
pwszInvalidStartingChars | A pointer to a string in the *ppCharBuffer buffer containing the characters that are not valid as the first character of the literal. If the literal can start with any valid character, this is a null pointer. For example, if table names can begin with anything other than a numeric character, this would be "0123456789" when lt is DBLITERAL_TABLE_NAME. This is not used for DBLITERAL_BINARY_LITERAL, DBLITERAL_CATALOG_SEPARATOR, DBLITERAL_ESCAPE_PERCENT_PREFIX, DBLITERAL_ESCAPE_UNDERSCORE_PREFIX, DBLITERAL_LIKE_PERCENT, DBLITERAL_LIKE_UNDERSCORE, DBLITERAL_QUOTE_PREFIX, and DBLITERAL_SCHEMA_SEPARATOR; pwszInvalidStartingChars is set to a null pointer for these DBLITERAL values.
lt | The literal described in the structure. For more information, see the following section.
fSupported | TRUE if the provider supports the literal specified by lt. If cLiterals is 0, this is always TRUE, because GetLiteralInfo only returns information about literals it supports in this case. FALSE if the provider does not support the literal; or the value of the corresponding element of the rgLiterals array was not a valid value in the DBLITERAL enumerated type.
cchMaxLen | The maximum number of characters in the literal. If there is no maximum or the maximum is unknown, cchMaxLen is set to ~0 (bitwise, the value is not 0; that is, all bits are set to 1). For DBLITERAL_CATALOG_SEPARATOR, DBLITERAL_ESCAPE_PERCENT_PREFIX, DBLITERAL_ESCAPE_UNDERSCORE_PREFIX, DBLITERAL_LIKE_PERCENT, DBLITERAL_LIKE_UNDERSCORE, DBLITERAL_QUOTE_PREFIX, and DBLITERAL_SCHEMA_SEPARATOR, this is the actual number of characters in the literal.

The following values of DBLITERAL are supported.

Value | Description
DBLITERAL_INVALID | An invalid value.
DBLITERAL_ BINARY_LITERAL | A binary literal in a text command.
DBLITERAL_ CATALOG_NAME | A catalog name in a text command.
DBLITERAL_ CATALOG_SEPARATOR | The character that separates the catalog name from the rest of the identifier in a text command.
DBLITERAL_ CHAR_LITERAL | A character literal in a text command.
DBLITERAL_ COLUMN_ALIAS | A column alias in a text command.
DBLITERAL_ COLUMN_NAME | A column name used in a text command or in a data-definition interface.
DBLITERAL_ CORRELATION_NAME | A correlation name (table alias) in a text command.
DBLITERAL_ CURSOR_NAME | A cursor name in a text command.
DBLITERAL_ ESCAPE_PERCENT_PREFIX | The character used in a LIKE clause to escape the character returned for the DBLITERAL_LIKE_PERCENT literal. For example, if a percent sign (%) is used to match zero or more characters and this is a backslash (\), the characters "abc\%%" match all character values that start with "abc%".
 | Some SQL dialects support a clause (the ESCAPE clause) that can be used to override this value.
DBLITERAL_ESCAPE_PERCENT_SUFFIX | The escape character, if any, used to suffix the character returned for the DBLITERAL_LIKE_PERCENT literal. For example, if a percent sign (%) is used to match zero or more characters, and percent signs are escaped by enclosing in open and close square brackets, DBLITERAL_ESCAPE_PERCENT_PREFIX is "[", DBLITERAL_ESCAPE_PERCENT_SUFFIX is "]", and the characters "abc[%]%" match all character values that start with "abc%". Providers that do not use a suffix character to escape the DBLITERAL_ESCAPE_PERCENT character do not return this literal value, and set the lt member of the DBLITERAL structure to DBLITERAL_INVALID if requested.
DBLITERAL_ ESCAPE_UNDERSCORE_PREFIX | The character used in a LIKE clause to escape the character returned for the DBLITERAL_LIKE_UNDERSCORE literal. For example, if an underscore (_) is used to match exactly one character and this is a backslash (\), the characters "abc\_ _" match all character values that are five characters long and start with "abc_". Some SQL dialects support a clause (the ESCAPE clause) that can be used to override this value.
DBLITERAL_ESCAPE_UNDERSCORE_SUFFIX | The escape character, if any, used to suffix the character returned for the DBLITERAL_LIKE_UNDERSCORE literal. For example, if an underscore (_) is used to match exactly one character, and underscores are escaped by enclosing in open and close square brackets, DBLITERAL_ESCAPE_UNDERSCORE_PREFIX is "[", DBLITERAL_ESCAPE_UNDERSCORE_SUFFIX is "]", and the characters "abc[_]_" match all character values that are five characters long and start with "abc_". Providers that do not use a suffix character to escape the DBLITERAL_ESCAPE_UNDERSCORE character do not return this literal value, and set the lt member of the DBLITERAL structure to DBLITERAL_INVALID if requested.
DBLITERAL_ INDEX_NAME | An index name used in a text command or in a data-definition interface.
DBLITERAL_ LIKE_PERCENT | The character used in a LIKE clause to match zero or more characters. For example, if this is a percent sign (%), the characters "abc%" match all character values that start with "abc".
DBLITERAL_ LIKE_UNDERSCORE | The character used in a LIKE clause to match exactly one character. For example, if this is an underscore (_), the characters "abc_" match all character values that are four characters long and start with "abc".
DBLITERAL_ PROCEDURE_NAME | A procedure name in a text command.
DBLITERAL_ SCHEMA_NAME | A schema name in a text command.
DBLITERAL_ SCHEMA_SEPARATOR | The character that separates the schema name from the rest of the identifier in a text command.
DBLITERAL_ TABLE_NAME | A table name used in a text command or in a data-definition interface.
DBLITERAL_ TEXT_COMMAND | A text command, such as an SQL statement.
DBLITERAL_ USER_NAME | A user name in a text command.
DBLITERAL_ VIEW_NAME | A view name in a text command.
DBLITERAL_QUOTE_PREFIX | The character used in a text command as the opening quote for quoting identifiers that contain special characters.
DBLITERAL_QUOTE_SUFFIX | The character used in a text command as the closing quote for quoting identifiers that contain special characters. 1.x providers that use the same character as the prefix and suffix may not return this literal value, and set the lt member of the DBLITERAL structure to DBLITERAL_INVALID if requested.

Note If a provider returns non-NULL CATALOG or SCHEMA column values in schema rowsets, then it must support IDBInfo to describe how a fully qualified name is assembled. A provider that does not support IDBInfo must return NULL values for CATALOG and SCHEMA columns in all schema rowsets.

See Also

IDBInfo::GetKeywords, IDBProperties::GetProperties


IDBInitialize

IDBInitialize is used to initialize and uninitialize data source objects and enumerators. It is a mandatory interface on data source objects and an optional interface on enumerators.

Method | Description
Initialize | Initializes a data source object or enumerator.
Uninitialize | Returns the data source object or enumerator to an uninitialized state.


IDBInitialize::Initialize

Initializes a data source object or enumerator.

HRESULT Initialize();

Parameters

None.

Return Code

S_OK
The method succeeded.

DB_S_ASYNCHRONOUS
The method has initiated asynchronous initialization of the data source. The consumer can call IDBAsynchStatus::GetStatus to poll for status or can register for notifications of asynchronous processing. Until asynchronous processing completes, the data source remains in an uninitialized state.

DB_S_ERRORSOCCURRED
The data source object or enumerator was initialized but one or more properties—for which the dwOptions element of the DBPROP structure was DBPROPOPTIONS_OPTIONAL—were not set. In order to return properties in error, the provider uses DBPROPSET_PROPERTIESINERROR. The method can fail to set properties for a number of reasons, including:

  • It was not possible to set the property.

  • The value in vValue in the DBPROP structure was invalid.

  • The property's value conflicted with an existing property.

E_FAIL
A provider-specific error occurred.

E_OUTOFMEMORY
The provider was unable to allocate sufficient memory in order to initialize the data source object or enumerator.

E_UNEXPECTED
The data source is in the process of being initialized asynchronously. To cancel asynchronous execution, call IDBAsynchStatus::Abort.

DB_E_ALREADYINITIALIZED
Initialize had already been called for the data source object or enumerator and an intervening call to Uninitialize had not been made.

DB_E_CANCELED
The provider prompted for additional information and the user selected Cancel.

DB_E_ERRORSOCCURRED
The data source object or enumerator was not initialized because one or more properties—for which the dwOptions element of the DBPROP structure was DBPROPOPTIONS_REQUIRED—were not set. The consumer checks dwStatus in the DBPROP structures to determine which properties were in error. The method can fail to set properties for any of the reasons specified in DB_S_ERRORSOCCURRED, except the reason that states that it was not possible to set the property.

DB_SEC_E_AUTH_FAILED
Authentication of the consumer to the data source or enumerator failed. The data source object or enumerator remains in the uninitialized state.

Comments

Initialize initializes the data source object or enumerator. It uses the values of properties in the Initialization property group that have been set with IDBProperties::SetProperties. If the consumer has not set values for all required properties, Initialize can prompt for values.

If Initialize returns DB_S_ERRORSOCCURRED or DB_E_ERRORSOCCURRED, the consumer can immediately call IDBProperties::GetProperties with the DBPPROPSET_PROPERTIESINERROR property set to return the properties that could not be set.

See Also

IDBInitialize::Uninitialize, IDBProperties::SetProperties


IDBInitialize::Uninitialize

Returns the data source object or enumerator to an uninitialized state.

HRESULT Uninitialize();

Parameters

None.

Return Code

S_OK
The method succeeded.

E_FAIL
A provider-specific error occurred.

E_UNEXPECTED
The data source is in the process of being initialized asynchronously. To cancel asynchronous initialization, call IDBAsynchStatus::Abort.

DB_E_OBJECTOPEN
There were open sessions, commands, or rowsets on the data source object.

Comments

The consumer is not required to uninitialize a data source object or enumerator before releasing it, but may use this method to release the state associated with the data source object or enumerator so that it can be reinitialized with Initialize or a new state loaded on a data source object.

It is an error to call Uninitialize when there are open sessions, commands, or rowsets on the data source object; that is, the consumer must release all interface pointers on all sessions, commands, and rowsets on the data source object before calling Uninitialize. It is not an error to call Uninitialize if Initialize has not been called.

See Also

IDBInitialize::Initialize


IDBProperties

IDBProperties is used to set and get the values of properties on the data source object or enumerator and to get information about all properties supported by the provider.

Before the data source object or enumerator is initialized, the consumer can work only with properties in the Initialization property group. After the data source object or enumerator is initialized, the consumer can work with properties in the Initialization, Data Source, and Data Source Information property groups, although it cannot set the value of properties in the Initialization property group.

Only properties in the Initialization property group are guaranteed to survive uninitialization. That is, if the consumer uninitializes and reinitializes a data source object or enumerator, it might need to reset the values of properties in groups other than Initialization.

IDBProperties is a mandatory interface for data source objects and an optional interface for enumerators. However, if an enumerator exposes IDBInitialize, it must expose IDBProperties.

Method | Description
GetProperties | Returns the values of properties in the Data Source, Data Source Information, and Initialization property groups that are currently set on the data source object or the values of properties in the Initialization property group that are currently set on the enumerator.
GetPropertyInfo | Returns information about all properties supported by the provider.
SetProperties | Sets properties in the Data Source and Initialization property groups, for data source objects, or the Initialization property group, for enumerators.


IDBProperties::GetProperties

Returns the values of properties in the Data Source, Data Source Information, and Initialization property groups that are currently set on the data source object or the values of properties in the Initialization property group that are currently set on the enumerator.

HRESULT GetProperties (
   ULONG                  cPropertyIDSets,
   const DBPROPIDSET   rgPropertyIDSets[],
   ULONG *                  pcPropertySets,
   DBPROPSET **         prgPropertySets);

Parameters

cPropertyIDSets

[in]
The number of DBPROPIDSET structures in rgPropertyIDSets.

If cPropertyIDSets is zero, the provider ignores rgPropertyIDSets. If the data source object or enumerator has not been initialized, the provider returns the values of all properties in the Initialization property group for which values have been set or defaults exist. If the data source object or enumerator has been initialized, the provider returns the values of all properties in the Data Source, Data Source Information, and Initialization property groups, for data source objects, or the Initialization property group, for enumerators, for which values have been set or defaults exist. The provider does not return the values of properties in any of these property groups for which values have not been set and no defaults exist.

If cPropertyIDSets is not zero, the provider returns the values of the requested properties. If a property is not supported, or if the data source object or enumerator is not initialized and the value of a property in a group other than the Initialization property group is requested, the returned value of dwStatus in the returned DBPROP structure for that property is DBPROPSTATUS_NOTSUPPORTED and the value of dwOptions is undefined.

rgPropertyIDSets

[in]
An array of cPropertyIDSets DBPROPIDSET structures. If the data source object or enumerator has not been initialized, the properties specified in these structures must belong to the Initialization property group. If the data source object or enumerator has been initialized, the properties specified in these structures must belong to the Data Source, Data Source Information, or Initialization property group, for data source objects, or the Initialization property group, for enumerators. The provider returns the values of the properties specified in these structures. If cPropertyIDSets is zero, then this argument is ignored.

For information about the properties in the Data Source, Data Source Information, and Initialization property groups that are defined by OLE DB, see "Data Source Properties," and "Initialization Properties".

pcPropertySets

[out]
A pointer to memory in which to return the number of DBPROPSET structures returned in *prgPropertySets. If cPropertyIDSets is zero, *pcPropertySets is the total number of property sets for which the provider supports at least one property in the Data Source, Data Source Information, or Initialization property group, for data source objects, or the Initialization property group, for enumerators. If cPropertyIDSets is greater than zero, *pcPropertySets is set to cPropertyIDSets. If an error other than DB_E_ERRORSOCCURRED occurs, *pcPropertySets is set to zero.

prgPropertySets

[out]
A pointer to memory in which to return an array of DBPROPSET structures. If cPropertyIDSets is zero, then one structure is returned for each property set that contains at least one property belonging to the Initialization property group (if the data source object or enumerator is not initialized), the Data Source, Data Source Information, or Initialization property group (if the data source object is initialized), or the Initialization property group (if the enumerator is initialized). If cPropertyIDSets is not zero, then one structure is returned for each property set specified in rgPropertyIDSets.

In the case of properties in the Initialization property group and for a previously persisted data source object, those properties related to sensitive authentication information such as password will be returned in an encrypted form if DBPROP_AUTH_PERSIST_ENCRYPTED is VARIANT_TRUE.

If cPropertyIDSets is not zero, the DBPROPSET structures in *prgPropertySets are returned in the same order as the DBPROPIDSET structures in rgPropertyIDSets; that is, for corresponding elements of each array, the guidPropertySet elements are the same. If cPropertyIDs, in an element of rgPropertyIDSets, is not zero, the DBPROP structures in the corresponding element of *prgPropertySets are returned in the same order as the DBPROPID values in rgPropertyIDs; that is, for corresponding elements of each array, the property IDs are the same.

The provider allocates memory for the structures and returns the address to this memory; the consumer releases this memory with IMalloc::Free when it no longer needs the structures. Before calling IMalloc::Free for *prgPropertySets, the consumer should call IMalloc::Free for the rgProperties element within each element of *prgPropertySets. If *pcPropertySets is zero on output or an error other than DB_E_ERRORSOCCURRED occurs, the provider does not allocate any memory and ensures that *prgPropertySets is a null pointer on output.

Return Code

S_OK
The method succeeded. In all DBPROP structures returned by the method, dwStatus is set to DBPROPSTATUS_OK.

DB_S_ERRORSOCCURRED
No value was returned for one or more properties. The consumer checks dwStatus in the DBPROP structure to determine the properties for which values were not returned. GetProperties can fail to return properties for a number of reasons, including:

  • The property was not supported by the provider.

  • The data source object or enumerator was not initialized and the property was not in the Initialization property group.

  • The method was called on the data source object, the data source object was initialized, and the property was not in the Data Source, Data Source Information, or Initialization property groups.

  • The method was called on the enumerator, the enumerator was initialized, and the property was not in the Initialization property group.

  • The property set was not supported by the provider. If cPropertyIDs in the DBPROPIDSET structure for the property set was zero, the provider cannot set dwStatus in the DBPROP structure because it does not know the IDs of any properties in the property set. Instead, it sets cProperties to zero in the DBPROPSET structure returned for the property set.

E_FAIL
A provider-specific error occurred.

E_INVALIDARG
cPropertyIDSets was not equal to zero and rgPropertyIDSets was a null pointer.

pcPropertySets or prgPropertySets was a null pointer.

In an element of rgPropertyIDSets, cPropertyIDs was not zero and rgPropertyIDs was a null pointer.

In an element of rgPropertyIDSets, guidPropertySet was DBPROPSET_PROPERTIESINERROR and cPropertyIDs was not zero or rgPropertyIDs was not a null pointer.

cPropertyIDSets was greater than 1 and, in an element of rgPropertyIDSets, guidPropertySet was DBPROPSET_PROPERTIESINERROR.

E_OUTOFMEMORY
The provider was unable to allocate sufficient memory in which to return the DBPROPSET or DBPROP structures.

DB_E_ERRORSOCCURRED
Values were not returned for any properties. The provider allocates memory for *prgPropertySets and the consumer checks dwStatus in the DBPROP structures to determine why properties were not returned. The consumer frees this memory when it no longer needs the information.

Comments

If IDBInitialize::Initialize returns DB_E_ERRORSOCCURRED, the consumer can immediately call GetProperties with the DBPROPSET_PROPERTIESINERROR property set to return all the properties that were in error.

See Also

IDBProperties::GetPropertyInfo, IDBProperties::SetProperties


IDBProperties::GetPropertyInfo

GetPropertyInfo returns information about all properties supported by the provider.

HRESULT GetPropertyInfo(
   ULONG                  cPropertyIDSets,
   const DBPROPIDSET   rgPropertyIDSets[],
   ULONG *                  pcPropertyInfoSets,
   DBPROPINFOSET **   prgPropertyInfoSets,
   OLECHAR **            ppDescBuffer);

Parameters

cPropertyIDSets

[in]
The number of DBPROPIDSET structures in rgPropertyIDSets.

If cPropertyIDSets is zero, the provider ignores rgPropertyIDSets. When called on the enumerator, the provider returns information about all properties in the Initialization property group. When called on the data source object, if the data source object has not been initialized, the provider returns information about all properties in the Initialization property group. If the data source object has been initialized, the provider returns information about all of the properties in all of the property sets it supports.

If cPropertyIDSets is not zero, the provider returns information about the requested properties. If a property is not supported, or if the method is called on an enumerator or an uninitialized data source object and the value of a property in a group other than the Initialization property group is requested, the returned value of dwStatus in the returned DBPROPINFO structure for that property is DBPROPFLAGS_NOTSUPPORTED and the values of the pwszDescription, vtType, and vValues elements are undefined.

rgPropertyIDSets

[in]
An array of cPropertyIDSets DBPROPIDSET structures. When called on the enumerator, the properties specified in these structures must belong to the Initialization property group. When called on the data source object, if the data source object has not been initialized, the properties must belong to the Initialization property group. If the data source object has been initialized, the properties can belong to any property group. The provider returns information about the properties specified in these structures. If cPropertyIDSets is zero, then this parameter is ignored.

The following special GUIDs are defined for use with GetPropertyInfo. All of these GUIDs can be used on data source objects; only the DBPROPSET_DBINITALL GUID can be used on enumerators. If any of these GUIDs are specified in the guidPropertySet element of a DBPROPIDSET structure, the cPropertyIDs and rgPropertyIDs elements of that structure are ignored. However, the consumer should set these to zero and a null pointer, respectively, because the provider might attempt to verify that they are valid values. Consumers cannot pass special GUIDs and the GUIDs of other property sets in the same call to GetPropertyInfo. That is, if one element of rgPropertyIDSets contains a special GUID, all elements of rgPropertyIDSets must contain special GUIDs. These GUIDs are not returned in the guidPropertySet element of the DBPROPINFOSET structures returned in rgPropertyInfoSets. Instead, the GUID of the property set to which the property belongs is returned.

Property Set GUID | Description
DBPROPSET_DATASOURCEALL | Returns all properties in the Data Source property group, including provider-specific properties.
DBPROPSET_DATASOURCEINFOALL | Returns all properties in the Data Source Information property group, including provider-specific properties.
DBPROPSET_DBINITALL | Returns all properties in the Initialization property group, including provider-specific properties.
DBPROPSET_ROWSETALL | Returns all properties in the Rowset property group, including provider-specific properties.
DBPROPSET_SESSIONALL | Returns all properties in the Session property group, including provider-specific properties.

pcPropertyInfoSets

[out]
A pointer to memory in which to return the number of DBPROPINFOSET structures returned in *prgPropertyInfoSets. If cPropertyIDSets is zero, *pcPropertyInfoSets is the total number of property sets for which the provider supports at least one property. If *pcPropertyInfoSets is not zero and one of the special GUIDs listed in rgPropertyIDSets was used, *pcPropertyInfoSets may differ from cPropertyInfoSets. If an error other than DB_E_ERRORSOCCURRED occurs, *pcPropertyInfoSets is set to zero.

prgPropertyInfoSets

[out]
A pointer to memory in which to return an array of DBPROPINFOSET structures. If cPropertyIDSets is zero, then one structure is returned for each property set that contains at least one property supported by the provider. If cPropertyIDSets is not zero, then one structure is returned for each property set specified in rgPropertyIDSets.

If cPropertyIDSets is not zero, the DBPROPINFOSET structures in *prgPropertyInfoSets are returned in the same order as the DBPROPIDSET structures in rgPropertyIDSets; that is, for corresponding elements of each array, the guidPropertySet elements are the same. If cPropertyIDs, in an element of rgPropertyIDSets, is not zero, the DBPROPINFO structures in the corresponding element of *prgPropertyInfoSets are returned in the same order as the DBPROPID values in rgPropertyIDs; that is, for corresponding elements of each array, the property IDs are the same. The only exception to these rules is when one of the special GUIDs listed in rgPropertyIDSets was used. In this case, the order of the property information returned may differ from the order specified in rgPropertyIDSets.

The provider allocates memory for the structures and returns the address to this memory; the consumer releases this memory with IMalloc::Free when it no longer needs the structures. Before calling IMalloc::Free for *prgPropertyInfoSets, the consumer should call IMalloc::Free for the rgPropertyInfos element within each element of *prgPropertyInfoSets. If *pcPropertyInfoSets is zero on output or if an error other than DB_E_ERRORSOCCURRED occurs, then *prgPropertyInfoSets must be a null pointer on output.

ppDescBuffer

[out]
A pointer to memory in which to return a pointer to storage for all string values returned in the *pwszDescription element of the DBPROPINFO structure. The provider allocates this memory with IMalloc and the consumer frees it with IMalloc::Free when it no longer needs the property descriptions. If ppDescBuffer is a null pointer on input, GetPropertyInfo does not return the property descriptions. If *pcPropertyInfoSets is zero on output or if an error occurs, the provider does not allocate any memory and ensures that *ppDescBuffer is a null pointer on output. Each of the individual string values stored in this buffer is terminated by a null-termination character. Therefore, the buffer may contain one or more strings, each with its own null-termination character, and may contain embedded null-termination characters.

Return Code

S_OK
The method succeeded. In all DBPROPINFO structures returned by the method, dwFlags is set to a value other than DBPROPFLAGS_NOTSUPPORTED.

DB_S_ERRORSOCCURRED
In an element of rgPropertyIDSets, a property specified in rgPropertyIDs was not supported by the provider; this includes the case in which the property set to which the property belongs is not supported by the provider. In the DBPROPINFO structures returned for the property, dwFlags is set to DBPROPFLAGS_NOTSUPPORTED.

In an element of rgPropertyIDSets, the property set specified in guidPropertySet was not supported by the provider. In the DBPROPINFOSET structure returned for the property set, cPropertyInfos is set to zero, and rgPropertyInfos is set to a null pointer.

The method was called on the enumerator and, in an element of rgPropertyIDSets, a property belonged to a group other than the Initialization property group.

The method was called on an uninitialized data source object and, in an element of rgPropertyIDSets, a property belonged to a group other than the Initialization property group.

E_FAIL
A provider-specific error occurred.

E_INVALIDARG
pcPropertyInfoSets or prgPropertyInfoSets was a null pointer.

cPropertyIDSets was not equal to zero and rgPropertyIDSets was a null pointer.

In an element of rgPropertyIDSets, cPropertyIDs was not zero and rgPropertyIDs was a null pointer.

In one element of rgPropertyIDSets, guidPropertySet specified one of the special GUIDs listed in the description of rgPropertyIDSets. In a different element of rgPropertyIDSets, guidPropertySet specified the GUID of a normal property set.

E_OUTOFMEMORY
The provider was unable to allocate sufficient memory in which to return the DBPROPINFOSET or DBPROPINFO structures or the property descriptions.

DB_E_ERRORSOCCURRED
Errors occurred while attempting to return information about all properties. The provider allocates memory for *prgPropertyInfoSets and the consumer checks dwFlags in the DBPROPINFO structures to determine why information about each property was not returned. The consumer frees this memory when it no longer needs the information. The method can fail to return information about properties for any of the reasons specified in DB_S_ERRORSOCCURRED.

Comments

GetPropertyInfo returns information about supported properties, including the property set to which they belong, their ID, their data type, the object to which they apply, and whether they can be read or written. Properties in the Initialization and Data Source Creation property groups for which the consumer must supply a value before calling Initialize are marked with the DBPROPFLAGS_REQUIRED bit in the dwFlags element of the DBPROPINFO structure.

Whether a property is supported is different from its value. For example, if a provider supports IRowsetLocate, it supports the DBPROP_IRowsetLocate property. Whether a rowset actually exposes IRowsetLocate depends on whether the consumer sets the value of the corresponding property to VARIANT_TRUE or VARIANT_FALSE.

The rowset properties returned by GetPropertyInfo indicate the set of properties that the provider knows about. The properties that may actually be supported for any particular rowset may be a subset of these properties. For example, a schema rowset may not be able to support all of the same properties as a rowset resulting from calling OpenRowset, or the properties that can be supported on a rowset generated from a command may vary depending on the command text. In general, consumers should not make assumptions based on the information returned by GetPropertyInfo. When opening a rowset, consumers should specify DBPROPOPTIONS_REQUIRED for the minimum number of properties required to be able to consume the rowset, and should set dwOptions for properties that provide the consumer additional functionality to DBPROPTIONS_OPTIONAL.

See Also

IDBProperties::GetProperties, IDBProperties::SetProperties


IDBProperties::SetProperties

Sets properties in the Data Source and Initialization property groups, for data source objects, or the Initialization property group, for enumerators.

HRESULT SetProperties (
   ULONG         cPropertySets,
   DBPROPSET   rgPropertySets[]);

Parameters

cPropertySets

[in]
The number of DBPROPSET structures in rgPropertySets. If this is zero, the provider ignores rgPropertySets and the method does not do anything.

rgPropertySets

[in/out]
An array of DBPROPSET structures containing properties and values to be set. If the data source object or enumerator is uninitialized, the properties specified in these structures must belong to the Initialization property group. If the data source object is initialized, the properties must belong to the Data Source property group. If the enumerator is initialized, it is an error to call this method. If the same property is specified more than once in rgPropertySets, then which value is used is provider-specific. If cPropertySets is zero, this parameter is ignored.

For information about the properties in the Data Source and Initialization property groups that are defined by OLE DB, see "Data Source Properties" and "Initialization Properties".

Return Code

S_OK
The method succeeded. In all DBPROP structures passed to the method, dwStatus is set to DBPROPSTATUS_OK.

DB_S_ERRORSOCCURRED
One or more properties were not set. Properties not in error remain set. The consumer checks dwStatus in the DBPROP structures to determine which properties were not set. SetProperties can fail to set properties for a number of reasons, including:

  • The property was not supported by the provider.

  • The data source object or enumerator was not initialized and the property was not in the Initialization property group.

  • The data source object was initialized and the property was not in the Data Source property group.

  • The property set was not supported by the provider.

  • The property is read-only and was not set to its default value.

  • It was not possible to set the property.

  • colid in the DBPROP structure was not DB_NULLID.

  • The value of dwOptions in the DBPROP structure was invalid.

  • The data type in vValue in the DBPROP structure was not the data type of the property or was not VT_EMPTY.

  • The value in vValue in the DBPROP structure was invalid.

  • The property's value conflicted with an existing property.

E_FAIL
A provider-specific error occurred.

E_INVALIDARG
cPropertySets was not equal to zero and rgPropertySets was a null pointer.

In an element of rgPropertySets, cProperties was not zero and rgProperties was a null pointer.

DB_E_ALREADYINITIALIZED
The method was called on the enumerator and the enumerator was already initialized.

DB_E_ERRORSOCCURRED
All property values were invalid and no properties were set. The consumer checks dwStatus in the DBPROP structures to determine why properties were not set. The method can fail to set properties for any of the reasons specified in DB_S_ERRORSOCCURRED, except the reason that states that it was not cheap to set the property.

See Also

IDBProperties::GetProperties, IDBProperties::GetPropertyInfo


IDBSchemaRowset

This is an optional interface on sessions. It is used to provide advanced schema information.

Consumers can get information about a data source without knowing its structure by using the IDBSchemaRowset methods.

Providers must return all of the columns in the rowsets they return. If they cannot return the information in a column, they must return an appropriate value. Generally, this is NULL. Providers can return provider-specific columns after the last column defined by OLE DB.

Here is list of supported schemas.

Method | Description
GetRowset | Returns a schema rowset.
GetSchemas | Returns a list of schema rowsets accessible by IDBSchemaRowset::GetRowset.


IDBSchemaRowset::GetRowset

Returns a schema rowset.

HRESULT GetRowset (
   IUnknown *         punkOuter,
   REFGUID            rguidSchema,
   ULONG            cRestrictions,
   const VARIANT      rgRestrictions[],
   REFIID               riid,
   ULONG            cPropertySets,
   DBPROPSET      rgPropertySets[],
   IUnknown **         ppRowset);

Parameters

pUnkOuter

[in]
A pointer to the controlling IUnknown interface if the rowset is being created as part of an aggregate. If the IDBSchemaRowset interface is not being aggregated, it is a null pointer.

rguidSchema

[in]
A GUID identifying the schema rowset. For more information, see the "Comments" section and IDBSchemaRowset.

cRestrictions

[in]
The count of restriction values.

rgRestrictions

[in]
An array of restriction values. These are applied in order to the restriction columns. That is, the first restriction value applies to the first restriction column, the second restriction value applies to the second restriction column, and so on. For more information, see the "Comments" section.

riid

[in]
The IID of the requested rowset interface. This interface is conceptually added to the list of required interfaces on the resulting rowset, and the method fails (E_NOINTERFACE) if that interface cannot be supported on the resulting rowset.

cPropertySets

[in]
The number of DBPROPSET structures in rgPropertySets. If this is 0, the provider ignores rgPropertySets.

rgPropertySets

[in/out]
An array of DBPROPSET structures containing properties and values to be set. The properties specified in these structures must belong to the Rowset property group. If the same property is specified more than once in rgPropertySets, then it is provider-specific which value is used. If cPropertySets is 0, this argument is ignored.

For information about the properties in the Rowset property group that are defined by OLE DB, see "Rowset Properties".

ppRowset

[out]
A pointer to memory in which to return the requested interface pointer on the schema rowset. This rowset is read-only. If no applicable schema information exists, an empty rowset is returned.

Return Code

S_OK
The method succeeded. In all DBPROP structures passed to the method, dwStatus is set to DBPROPSTATUS_OK.

DB_S_ASYNCHRONOUS
The method has initiated asynchronous creation of the rowset. The consumer can call IDBAsynchStatus to poll for status or IConnectionPointContainer to obtain the IID_IDBAsynchNotify connection point. Attempting to call any other interfaces may fail and the full set of interfaces may not be available on the object until asynchronous initialization of the rowset has completed.

DB_S_ERRORSOCCURRED
The rowset was opened but one or more properties—for which the dwOptions element of the DBPROP structure was DBPROPOPTIONS_OPTIONAL—were not set. The consumer checks dwStatus in the DBPROP structures to determine which properties were not set. The method can fail to set properties for a number of reasons:

  • The property was not supported by the provider.

  • The property was not in the Rowset property group.

  • The property set was not supported by the provider.

  • It was not possible to set the property.

  • The colid in the DBPROP structure was invalid.

  • The data type in vValue in the DBPROP structure was not the data type of the property or was not VT_EMPTY.

  • The value in vValue in the DBPROP structure was invalid.

  • The property's value conflicted with an existing property.

  • A property was specified to be applied to all columns, but could not be applied to one or more columns.

E_FAIL
A provider-specific error occurred.

E_INVALIDARG
rguidSchema was invalid.

rguidSchema specified a schema rowset that was not supported by the provider.

cRestrictions was greater than the number of restriction columns for the schema rowset specified in rguidSchema.

In one or more restriction values specified in rgRestrictions, the vt element of the VARIANT was the incorrect type.

cRestrictions was greater than zero and rgRestrictions was a null pointer.

In an element of rgRestrictions, the vt element of the VARIANT was not VT_EMPTY and the provider did not support the corresponding restriction.

ppRowset was a null pointer.

In an element of rgPropertySets, cProperties was not 0 and rgProperties was a null pointer.

cPropertySets was greater than zero and rgPropertySets was a null pointer.

E_NOINTERFACE
The schema rowset did not support the interface specified in riid.

E_OUTOFMEMORY
The provider was unable to allocate sufficient memory in which to create the rowset.

DB_E_ABORTLIMITREACHED
The method failed because a resource limit has been reached. For example, a query used to implement the method timed out. No rowset is returned.

DB_E_ERRORSOCCURRED
No rowset was returned because one or more properties—for which the dwOptions element of the DBPROP structure was DBPROPOPTIONS_REQUIRED or an invalid value—were not set. The consumer checks dwStatus in the DBPROP structures to determine which properties were not set. None of the satisfiable properties are remembered. The method can fail to set properties for any of the reasons specified in DB_S_ERRORSOCCURRED, except the reason that states that it was not possible to set the property.

DB_E_NOAGGREGATION
pUnkOuter was not a null pointer and the rowset being created does not support aggregation.

pUnkOuter was non-null and riid was not IID_Unknown.

DB_E_NOTSUPPORTED
The provider does not support restrictions on one or more of the columns in the corresponding schema.

DB_SEC_E_PERMISSIONDENIED
The consumer did not have sufficient permission to create the schema rowset.

DB_E_OBJECTOPEN
The provider would have to open a new connection to support the operation and DBPROP_MULTIPLECONNECTIONS is set to VARIANT_FALSE.

Comments

GetRowset allows the consumer to specify restrictions that limit the set of rows returned by the schema rowset, but does not define the format for such restrictions. The restriction array contains single values that are compared for equality to the corresponding value in the schema rowset. Only rows that exactly match the restriction value in the corresponding column are returned in the rowset. Pattern matching is not supported.

When preparing an array of restriction values, consumers are not required to specify values for all of the restriction columns on a rowset. Any columns for which no restriction values are specified are not restricted.

There are two ways for a consumer to explicitly specify that there is no restriction value for a column. First, the consumer cannot specify a restriction value for the column. For example, if there are three restriction columns, the consumer passes only two restriction values; these apply to the first two restriction columns and no value is specified for the third restriction column.

Second, the consumer can set the vt element of the VARIANT specified for the column to VT_EMPTY, even if the provider does not support restrictions on the column. For example, suppose there are three restriction columns, the provider supports restrictions on the first and third columns, and the consumer wants to restrict values on these two columns. The consumer passes three restriction values. The first and third values are the desired restrictions and the second value is a VARIANT with a vt element of VT_EMPTY.

If the vt element of the VARIANT specified for a restriction column is VT_NULL, this means that the column must be NULL to satisfy the restriction. This is equivalent to the IS NULL predicate in SQL. If the vt element of the VARIANT specified for a restriction column is VT_BSTR and the bstrVal element is set to a null pointer, this means that the column must contain an empty string to satisfy the restriction.

See Also

IDBSchemaRowset::GetSchemas


IDBSchemaRowset::GetSchemas

Returns a list of schema rowsets accessible by IDBSchemaRowset::GetRowset.

HRESULT GetSchemas (
   ULONG *      pcSchemas,
   GUID **      prgSchemas,
   ULONG**      prgRestrictionSupport);

Parameters

pcSchemas

[out]
A pointer to memory in which to return the number of GUIDs in *prgSchemas. The returned count of schema GUIDs is always at least 3, because all providers must support the TABLES, COLUMNS, and PROVIDER_TYPES schema rowsets. If an error occurs, *pcSchemas is set to 0.

prgSchemas

[out]
A pointer to memory in which to return an array of GUIDs identifying supported schema rowsets. For more information, see IDBSchemaRowset. The rowset allocates memory for the GUIDs and returns the address to this memory. The consumer releases this memory with IMalloc::Free when it no longer needs the list of GUIDs. If an error occurs, *prgSchemas is set to a null pointer.

prgRestrictionSupport

[out]
A pointer to memory in which to return an array of ULONGs, one element for each supported schema rowset, describing the restriction columns supported for that schema rowset. For a given schema rowset, the array element corresponding to the schema rowset will have the appropriate bit set if the provider implements a restriction on that column. Bits that do not correspond to currently defined restriction columns should not be set.

The rowset allocates memory for the restrictions and returns the address to this memory. The consumer releases this memory with IMalloc::Free when it no longer needs the list of restrictions. If an error occurs, *prgRestrictionSupport is set to a null pointer.

If prgRestrictionSupport is a null pointer, the rowset does not allocate any memory or return any restrictions.

Return Code

S_OK
The method succeeded.

E_FAIL
A provider-specific error occurred.

E_INVALIDARG
pcSchemas, prgSchemas, or prgRestrictionSupport was a null pointer.

E_OUTOFMEMORY
The provider was unable to allocate sufficient memory in which to return the array of schema GUIDs or restriction support information.

See Also

IDBSchemaRowset::GetRowset


IGetDataSource

This is a mandatory interface on the session for obtaining an interface pointer to the data source object.

Method | Description
GetDataSource | Returns an interface pointer on the data source object that created this session.


IGetDataSource::GetDataSource

Returns an interface pointer on the data source object that created the session.

HRESULT GetDataSource (
   REFIID       riid,
   IUnknown **   ppDataSource);

Parameters

riid

[in]
The IID of the interface on which to return a pointer.

ppDataSource

[out]
A pointer to memory in which to return the interface pointer. If GetDataSource fails, it must attempt to set *ppDataSource to a null pointer.

Return Code

S_OK
The method succeeded.

E_FAIL
A provider-specific error occurred.

E_INVALIDARG
ppDataSource was a null pointer.

E_NOINTERFACE
The object that created this session did not support the interface specified in riid.

See Also

ICommand::GetDBSession, IRowsetInfo::GetSpecification


IOpenRowset

IOpenRowset is a required interface on the session. It can be supported by providers that do not support creating rowsets through commands.

The IOpenRowset model enables consumers to open and work directly with individual tables or indexes in a data source by using IOpenRowset::OpenRowset, which generates a rowset of all rows in the table or index.

Method | Description
OpenRowset | Opens and returns a rowset that includes all rows from a single base table or index.


IOpenRowset::OpenRowset

Opens and returns a rowset that includes all rows from a single base table or index.

HRESULT OpenRowset(
   IUnknown *      pUnkOuter,
   DBID *            pTableID,
   DBID *            pIndexID,
   REFIID            riid,
   ULONG         cPropertySets,
   DBPROPSET   rgPropertySets[],
   IUnknown **      ppRowset);

Parameters

pUnkOuter

[in]
The controlling IUnknown if the rowset is to be aggregated, otherwise a null pointer.

pTableID

[in]
The DBID of the table to open. For more information, see the "Comments" section.

pIndexID

[in]
The DBID of the index to open. For more information, see the "Comments" section.

riid

[in]
The IID of the interface to return in *ppRowset. This interface is conceptually added to the list of required interfaces on the resulting rowset, and the method fails (E_NOINTERFACE) if that interface cannot be supported on the resulting rowset. This must be an interface that the rowset supports, even when ppRowset is set to a null pointer and no rowset is created.

cPropertySets

[in]
The number of DBPROPSET structures in rgPropertySets. If this is zero, the provider ignores rgPropertySets.

rgPropertySets

[in/out]
An array of DBPROPSET structures containing properties and values to be set. The properties specified in these structures must belong to the Rowset property group. If the same property is specified more than once in rgPropertySets, then it is provider-specific which value is used. If cPropertySets is zero, this argument is ignored.

For information about the properties in the Rowset property group that are defined by OLE DB, see "Rowset Properties".

ppRowset

[in/out]
A pointer to memory in which to return the interface pointer to the created rowset. If ppRowset is a null pointer, no rowset is created; properties are verified and if a required property cannot be set, DB_E_ERRORSOCCURRED is returned. If OpenRowset fails, *ppRowset is set to a null pointer.

Return Code

S_OK
The method succeeded and the rowset is opened. In all DBPROP structures passed to the method, dwStatus is set to DBPROPSTATUS_OK.

DB_S_ASYNCHRONOUS
The method has initiated asynchronous creation of the rowset. The consumer can call IDBAsynchStatus to poll for status or IConnectionPointContainer to obtain the IID_IDBAsynchNotify connection point. Attempting to call any other interfaces may fail, and the full set of interfaces may not be available on the object until asynchronous initialization of the rowset has completed.

DB_S_ERRORSOCCURRED
The rowset was opened but one or more properties—for which the dwOptions element of the DBPROP structure was DBPROPOPTIONS_OPTIONAL—were not set. The consumer checks dwStatus in the DBPROP structures to determine which properties were not set. The method can fail to set properties for a number of reasons, including:

  • colid in the DBPROP structure was invalid.

  • The data type in vValue in the DBPROP structure was not the data type of the property or was not VT_EMPTY.

  • The value in vValue in the DBPROP structure was invalid.

  • The property's value conflicted with an existing property.

  • A property was specified to be applied to all columns, but could not be applied to one or more columns.

  • The property was not supported by the provider.

  • It was not possible to set the property.

DB_S_STOPLIMITREACHED
Execution has been stopped because a resource limit has been reached. The results obtained so far have been returned. This return code takes precedence over DB_S_ERRORSOCCURRED; that is, if the conditions descrbed here and in those described in DB_S_ERRORSOCCURRED both occur, the provider returns this code. When the consumer receives this return code, it should also check for the conditions described in DB_S_ERRORSOCCURRED.

E_FAIL
A provider-specific error occurred.

E_INVALIDARG
pTableID and pIndexID were both null pointers.

cPropertySets was not zero and prgPropertySets was a null pointer.

In an element of rgPropertySets, cProperties was not zero and rgProperties was a null pointer.

E_NOINTERFACE
The rowset did not support the interface specified in riid or riid was IID_NULL.

DB_E_ERRORSOCCURRED
No rowset was returned because one or more properties—for which the dwOptions element of the DBPROP structure was DBPROPOPTIONS_REQUIRED or an invalid value—were not set. The consumer checks dwStatus in the DBPROP structures to determine which properties were not set. None of the satisfiable properties are remembered. The method can fail to set properties for any of the reasons specified in DB_S_ERRORSOCCURRED except the reason that states that it was not possible to set the property.

DB_E_ABORTLIMITREACHED
The method failed because a resource limit has been reached. For example, a query used to implement the method timed out. No rowset is returned.

DB_E_NOAGGREGATION
pUnkOuter was not a null pointer and the rowset being created does not support aggregation.

pUnkOuter was non-null and riid was not IID_Unknown.

DB_E_NOINDEX
The specified index does not exist in the current data source or did not apply to the specified table.

The provider does not support opening indexes through IOpenRowset.

DB_E_NOTABLE
The specified table does not exist in the current data source.

DB_E_PARAMNOTOPTIONAL
The table specified by pTableID is a procedure that requires one or more parameters.

DB_SEC_E_PERMISSIONDENIED
The consumer did not have sufficient permission to open the rowset. For example, a rowset included a column for which the consumer does not have read permission.

DB_E_OBJECTOPEN
The provider would have to open a new connection to support the operation and DBPROP_MULTIPLECONNECTIONS is set to VARIANT_FALSE.

Comments

If the table or index has no rows, the rowset is still created. The resulting rowset is fully functional and can be used, for example, to insert new rows or determine column metadata.

pTableID and pIndexID are used in the following combinations:

  • If pTableID is not a null pointer and pIndexID is a null pointer, the table identified by *pTableID is opened.

  • If pTableID is a null pointer and pIndexID is not a null pointer, *pIndexID must uniquely and fully identify an index; this index is opened. If *pIndexID does not uniquely and fully identify an index, DB_E_NOINDEX is returned.

  • If neither pTableID nor pIndexID is a null pointer, *pIndexID must identify an index for the table identified by *pTableID; this index is opened. If *pIndexID does not identify an index for the table identified by *pTableID, DB_E_NOINDEX is returned.

  • If both pTableID and pIndexID are null pointers, E_INVALIDARG is returned.

Consumers must supply fully qualified names as pTableID on providers that support catalog or schema names. For more information, see "Fully Qualified Names," Chapter 4.

The threading model of the returned rowset is determined by the property DBPROP_ROWTHREADMODEL.

See Also

IDBCreateCommand::CreateCommand


IParseDisplayName

The IParseDisplayName interface parses a displayable name string to convert it into a moniker for custom moniker implementations. Display name parsing is necessary when the end user inputs a string to identify a component, as in the following situations:

  • A compound document application that supports linked components typically supports the Edit:Links... dialog box. Through this dialog box, the end user can enter a display name to specify a new link source for a specified linked component. The compound document needs to have this input string converted into a moniker.
  • A script language such as the macro language of a spreadsheet can allow textual references to a component. The language's interpreter needs to have such a reference converted into a moniker in order to execute the macro.

Compound document applications that support links to embedded components or to pseudo-objects within their documents must provide an implementation of the IOleItemContainer interface, which is derived indirectly from IParseDisplayName. In effect, such a compound document is providing a namespace for identifying its internal components; and its IOleItemContainer implementation (which includes the IParseDisplayName implementation) is the interface through which another application can access this namespace. Alternatively, the compound document application can implement IParseDisplayName as part of its class object, which is accessible through the CoGetClassObject function.

Monikers that support their own namespace with custom requirements for parsing names also implement this interface.

Methods

IParseDisplayName Method | Description
ParseDisplayName | Parses the display name returning a moniker corresponding to it.


IParseDisplayName::ParseDisplayName

Parses the display name to extract a component of the string that it can convert into a moniker, using the maximum number of characters from the left side of the string.

HRESULT ParseDisplayName(
  IBindCtx *pbc,     //Pointer to bind context
  LPOLESTR pszDisplayName,
                     //Pointer to string containing display name
  ULONG *pchEaten,   //Pointer to length, in characters, of display
                     //name
  IMoniker **ppmkOut //Address of output variable that receives the
                     //resulting IMoniker interface pointer
);

Parameters

pbc
[in] Pointer to the bind context to be used in this binding operation.
pszDisplayName
[in] Pointer to a zero-terminated string containing the display name to be parsed. For Win32 applications, the LPOLESTR type indicates a wide character string (two bytes per character); otherwise, the string has one byte per character.
pchEaten
[out Pointer to the number of characters in the display name that correspond to the ppmkOut moniker.
ppmkOut
[out] Address of IMoniker* pointer variable that receives the interface pointer to the resulting moniker. If an error occurs, the implementation sets *ppmkOut to NULL. If *ppmkOut is non-NULL, the implementation must call (*ppmkOut)->IUnknown::AddRef; so it is the caller's responsibility to call (*ppmkOut)->IUnknown::Release.

Return Values

This method supports the standard return values E_OUTOFMEMORY and E_UNEXPECTED, as well as the following:

S_OK
The parse operation was successful.
MK_E_SYNTAX
Syntax error in the display name. Parsing failed because szDisplayName could only be partially resolved into a moniker. In this case, *pchEaten has the number of characters that were successfully parsed into a moniker prefix. The parameter ppmkOut should be NULL.
MK_E_NOOBJECT
The display name does not identify a component in this namespace.
E_INVALIDARG
One or more parameters are invalid.

Remarks

In general, the maximum prefix of szDisplayName that is syntactically valid and that represents an object should be consumed by this method and converted to a moniker.

Typically, this method is called by MkParseDisplayName[Ex]. In the initial step of the parsing operation, the MkParseDisplayName[Ex] function can retrieve the IParseDisplayName interface directly from an instance of a class identified with either the "@ProgID" or "ProgID" notation. Subsequent parsing steps can query for the interface on an intermediate object.

The main loop of MkParseDisplayName[Ex] finds the next moniker piece by calling the equivalent method in the IMoniker interface, that is, IMoniker::ParseDisplayName, on the moniker that it currently holds. In this call to IMoniker::ParseDisplayName, the MkParseDisplayName[Ex] function passes NULL in the pmkToLeft parameter. If the moniker currently held by MkParseDisplayName[Ex] is a generic composite, the call to IMoniker::ParseDisplayName is forwarded by that composite onto its last piece, passing the prefix of the composite to the left of the piece in pmkToLeft.

Some moniker classes will be able to handle this parsing internally to themselves since they are designed to designate only certain kinds of objects. Others will need to bind to the object that they designate to accomplish the parsing process. As is usual, these objects should not be released by IMoniker::ParseDisplayName but instead should be transferred to the bind context via IBindCtx::RegisterObjectBound or IBindCtx::GetRunningObjectTable followed by IRunningObjectTable::Register for release at a later time.


IPersist

Method | Description
GetClassID | Retrieves the class identifier for an object, which is used later for data manipulations.


IPersist::GetClassID

Retrieves the class identifier (CLSID) of an object. The CLSID is a unique value that identifies the code that can manipulate the persistent data.

HRESULT GetClassID(
  CLSID *pClassID  //Pointer to CLSID of object
);

Parameter

pClassID
[out]Points to the location of the CLSID on return. The CLSID is a globally unique identifier (GUID) that uniquely represents an object class that defines the code that can manipulate the object's data.

Return Values

S_OK
The CLSID was successfully retrieved.
E_FAIL
The CLSID could not be retrieved.

Remarks

The GetClassID method retrieves the class identifier (CLSID) for an object, used in later operations to load object-specific code into the caller's context.


IPersistFile

The IPersistFile interface provides methods that permit an object to be loaded from or saved to a disk file, rather than a storage object or stream. Because the information needed to open a file varies greatly from one application to another, the implementation of IPersistFile::Load on the object must also open its disk file.

The IPersistFile interface inherits its definition from IPersist, so all implementations must also include the GetClassID method of IPersist.

Call methods in the IPersistFile interface to load or save a linked object in a specified file.

When IPersistFile is implemented on an object that supports linking through a file moniker and the application for the linked object is run, OLE calls IPersistFile::Load. Once the file is loaded, OLE calls IPersistFile::QueryInterface to get another interface pointer to the loaded object. The IPersistFile interface is typically part of an aggregate object that offers other interfaces.

In this case, the only IPersistFile method that OLE calls is the Load method to load a file linked to a container, running the application associated with the file. It would also be unusual for applications to call other methods in this case, which support saving an object to a file. Generally, it is left to the end user and the application for the linked object to decide when to save the object.

Methods

IPersist Method | Description
GetClassID | Returns the class identifier (CLSID) for the component object.

IPersistFile Methods | Description
IsDirty | Checks an object for changes since it was last saved to its current file.
Load | Opens the specified file and initializes an object from the file contents.
Save | Saves the object into the specified file.
SaveCompleted | Notifies the object that it can revert from NoScribble mode to Normal mode.
GetCurFile | Gets the current name of the file associated with the object.


IPersistFile::GetCurFile

Retrieves either the absolute path to the object's current working file or, if there is no current working file, the object's default filename prompt.

HRESULT GetCurFile(
  LPOLESTR *ppszFileName  //Pointer to the path for the current file
                          //or the default save prompt
);

Parameter

ppszFileName
[out]Points to the location of a pointer to a zero-terminated string containing the path for the current file or the default filename prompt (such as *.txt). If an error occurs, ppszFileName is set to NULL.

Return Values

S_OK
A valid absolute path was successfully returned.
S_FALSE
The default save prompt was returned.
E_OUTOFMEMORY
The operation failed due to insufficient memory.
E_FAIL
The operation failed due to some reason other than insufficient memory.

Remarks

This method returns the current filename or the default save prompt for the object.

This method allocates memory for the string returned in the ppszFileName parameter using the IMalloc::Alloc method. The caller is responsible for calling the IMalloc::Free method to free the string. Both the caller and this method use the OLE task allocator provided by a call to CoGetMalloc.

The LPOLESTR type indicates a wide character string (two bytes per character); otherwise, the string has one byte per character.

The filename returned in ppszFileName is the name specified in a call to IPersistFile::Load when the document was loaded; or in IPersistFile::SaveCompleted if the document was saved to a different file.

If the object does not have a current working file, it should supply the default filename prompt that it would display in a "Save As" dialog. For example, the default save prompt for a word processor object could be:

*.txt

OLE does not call the IPersistFile::GetCurFile method. Applications would not call this method unless they are also calling the save methods of this interface.

In saving the object, you can call this method before calling IPersistFile:Save to determine whether the object has an associated file. If this method returns S_OK, you can then call IPersistFile::Save with a NULL filename and a TRUE value for the fRemember parameter to tell the object to save itself to its current file. If this method returns S_FALSE, you can use the save prompt returned in the ppszFileName parameter to ask the end user to provide a filename. Then, you can call IPersistFile::Save with the filename that the user entered to perform a "Save As" operation.

See Also

IPersistFile::Load, IPersistFile::Save, IPersistFile::SaveCompleted


IPersistFile::IsDirty

Checks an object for changes since it was last saved to its current file.

HRESULT IsDirty(void);

Return Values

S_OK
The object has changed since it was last saved.
S_FALSE
The object has not changed since the last save.

Notes of current version: This function always returns S_OK.

Remarks

This method checks whether an object has changed since it was last saved. Call it to determine whether an object should be saved before closing it. The dirty flag for an object is conditionally cleared in the IPersistFile::Save method.

OLE does not call IPersistFile::IsDirty. Applications would not call it unless they are also saving an object to a file.

You should treat any error return codes as an indication that the object has changed. Unless this method explicitly returns S_FALSE, assume that the object must be saved.


IPersistFile::Load

Opens the specified file and initializes an object from the file contents.

HRESULT Load(
  LPCOLESTR pszFileName,
                //Pointer to absolute path of the file to open
  DWORD dwMode  //Specifies the access mode from the STGM enumeration
);

Parameters

pszFileName
[in]Points to a zero-terminated string containing the absolute path of the file to open.
dwMode
[in]Specifies some combination of the values from the STGM enumeration to indicate the access mode to use when opening the file. IPersistFile::Load can treat this value as a suggestion, adding more restrictive permissions if necessary. If dwMode is zero, the implementation should open the file using whatever default permissions are used when a user opens the file.

Return Values

S_OK
The object was successfully loaded.
E_OUTOFMEMORY
The object could not be loaded due to a lack of memory.
E_FAIL
The object could not be loaded for some reason other than a lack of memory.
IPersistFile::Load STG_E_* error codes.

Remarks

IPersistFile::Load loads the object from the specified file. This method is for initialization only and does not show the object to the end user. It is not equivalent to what occurs when an end user selects the File Open command.

The BindToObject method in file monikers calls this method to load an object during a moniker binding operation (when a linked object is run). Typically, applications do not call this method directly.


IPersistFile::Save

Saves a copy of the object into the specified file.

HRESULT Save(
  LPCOLESTR pszFileName,   //Pointer to absolute path of the file
                           //where the object is saved
  BOOL fRemember           //Specifies whether the file is to be the
                           //current working file or not
);

Parameters

pszFileName
[in]Points to a zero-terminated string containing the absolute path of the file to which the object should be saved. If pszFileName is NULL, the object should save its data to the current file, if there is one.
fRemember
[in]Indicates whether the pszFileName parameter is to be used as the current working file. If TRUE, pszFileName becomes the current file and the object should clear its dirty flag after the save. If FALSE, this save operation is a "Save A Copy As ..." operation. In this case, the current file is unchanged and the object should not clear its dirty flag. If pszFileName is NULL, the implementation should ignore the fRemember flag.

Return Values

S_OK
The object was successfully saved.
E_FAIL
The file was not saved.
IPersistFile::Save STG_E_* errors.

Notes of current version: This function always returns E_FAIL

Remarks

This method can be called to save an object to the specified file in one of three ways:

Save
Call IPersistFile::GetCurFile first to determine whether the object has an associated filename. If so, call IPersistFile::Save specifying NULL for the pszFileName parameter in this method to indicate that the object should be saved to its current file. Then call IPersistFile::SaveCompleted to indicate completion.
Save As
Call IPersistFile::Save specifying TRUE in the fRemember parameter and a non-NULL value, indicating the name of the new file the object is to be saved to, for the pszFileName parameter . Then call IPersistFile::SaveCompleted to indicate completion.
Save a Copy As
Call IPersistFile::Save specifying FALSE in the fRemember parameter and a non-NULL value, indicating the name of the new file the object is to be copied to, for the pszFileName parameter.

The implementer must detect which type of save operation the caller is requesting. If the pszFileName parameter is NULL, a "Save" is being requested. If the pszFileName parameter is not NULL, use the value of the fRemember parameter to distinguish between a "Save As" and a "Save a Copy As".

In "Save" or "Save As" operations, IPersistFile::Save clears the internal dirty flag after the save and sends IAdviseSink::OnSave notifications to any advisory connections (see also IOleAdviseHolder::SendOnSave). Also, in these operations, the object is in NoScribble mode until it receives an IPersistFile::SaveCompleted call. In NoScribble mode, the object must not write to the file.

In the "Save a Copy As" scenario, the implementation does not clear the internal dirty flag after the save.

OLE does not call IPersistFile::Save. Typically, applications would not call it unless they are saving an object to a file directly, which is generally left to the end-user.

See Also

IPersistFile::GetCurFile, IPersistFile::SaveCompleted


IPersistFile::SaveCompleted

Notifies the object that it can write to its file. It does this by notifying the object that it can revert from NoScribble mode (in which it must not write to its file), to Normal mode (in which it can). The component enters NoScribble mode when it receives an IPersistFile::Save call.

HRESULT SaveCompleted(
  LPCOLESTR pszFileName  //Pointer to absolute path of the file
                         //where the object was saved
);

Parameter

pszFileName
[in]Points to the absolute path of the file where the object was previously saved.

Return Value

S_OK
Returned in all cases.

Notes of current version: This function does nothing.

Remarks

IPersistFile::SaveCompleted is called when a call to IPersistFile::Save is completed, and the file that was saved is now the current working file (having been saved with "Save" or "Save As" operations). The call to Save puts the object into NoScribble mode so it cannot write to its file. When SaveCompleted is called, the object reverts to Normal mode, in which it is free to write to its file.

OLE does not call the IPersistFile::SaveCompleted method. Typically, applications would not call it unless they are saving objects directly to files, an operation which is generally left to the end-user.

See Also

IPersistFile::Save


IRowset

IRowset is the base rowset interface. It provides methods for fetching rows sequentially, getting the data from those rows, and managing rows.

IRowset requires IAccessor and IRowsetInfo.

Consumers use the methods in IRowset for all basic rowset operations, including fetching and releasing rows and getting column values.

When a consumer first gets an interface pointer on a rowset, usually its first step is to determine the rowset's capabilities using IRowsetInfo::GetProperties. This returns information about the interfaces exposed by the rowset as well as those capabilities of the rowset which do not show up as distinct interfaces, such as the maximum number of active rows and how many rows can have pending updates at the same time.

For most consumers, the next step is to determine the characteristics, or metadata, of the columns in the rowset. For this they use either IColumnsInfo or IColumnsRowset, for simple or extended column information, respectively. These interfaces are also available on prepared commands prior to execution, allowing advance planning.

The consumer determines which columns it needs, either from the metadata or on the basis of knowing the text command that generated the rowset. It determines the ordinals of the needed columns from the ordering of the column information returned by IColumnsInfo or from ordinals in the column metadata rowset returned by IColumnsRowset.

Some consumers do not use a command or do not want to browse the column information: they may know the name or property identifier for the columns they want to use. They call IColumnsInfo::MapColumnIDs to retrieve the column ordinals.

The ordinals are used to specify a binding to a column. A binding is a structure that associates an element of the consumer's structure with a column. The binding can bind the column's data value, length, and status value.

A set of bindings is gathered together in an accessor, which is created with IAccessor::CreateAccessor. An accessor can contain multiple bindings so that the data for multiple columns can be retrieved or set in a single call. The consumer can create several accessors to match different usage patterns in different parts of the application. It can create and release accessors at any time while the rowset remains in existence. For more information about accessors, see "Accessors".

To fetch rows from the database, the consumer calls a method such as GetNextRows or IRowsetLocate::GetRowsAt. To create and initialize a new row to be inserted into the data source, the consumer calls IRowsetChange::InsertRow.

The methods that fetch rows do not actually return data to the consumer. Instead, they return the handles to these rows, and a local copy of the rows is stored in the rowset.

After the rows are returned, the consumer can access the data in the rows. The consumer calls GetData and passes it the handle to a row, the handle to an accessor, and a pointer to a consumer-allocated buffer. GetData converts the data (if it does not match the native provider storage) and returns the columns as specified in the bindings used to create the accessor. The consumer can call GetData more than once for a row, using different accessors and buffers; thus, the consumer can have multiple copies of the same data. For example, if a column contains a text document, the consumer might call GetData with an accessor that binds the first 50 bytes of the document. When the user double-clicks on the displayed heading text, the consumer could then call GetData with a different accessor to retrieve the entire document.

Data from variable-length columns may be treated several ways. First, such columns can be bound to a finite section of the consumer's structure, which causes truncation when the length of the data exceeds the length of the buffer. The consumer can determine that truncation has occurred by checking if the status is DBSTATUS_S_TRUNCATED. The returned length is always the true length in bytes, so the consumer also can determine how much data was truncated. Another way to obtain data from such columns is by reference. For example, if a binary column is bound with a type indicator of DBTYPE_BYTES | DBTYPE_BYREF, the provider allocates memory for all of the data in the column and returns this memory to the consumer.

When the consumer is finished fetching or updating rows, it releases them with ReleaseRows. This releases resources from the rowset's copy of the rows and makes room for new rows. The consumer can then repeat its cycle of fetching or creating rows and accessing the data in them.

When the consumer is done with the rowset, it calls IAccessor::ReleaseAccessor to release any accessors. It calls IUnknown::Release on all interfaces exposed by the rowset to release the rowset. When the rowset is released, it forces the release of any remaining rows or accessors the consumer may hold. Such handle objects are subordinate to the rowset. That is, they do not take reference counts upon the rowset and cannot cause the rowset to linger beyond the point where all the interfaces for the rowset have been released. The rowset must clean up all such subordinate objects.

Note If the rowset was generated as a result of executing a command that contained output parameters and the provider populates output parameters when the rowset is released (that is, DBPROP_OUTPUTPARAMETERAVAILABILITY is DBPROP_OA_ATROWRELEASE), the memory for the output parameters bound at Execute time must be valid when the rowset is released. Not doing so is considered a serious programming error and likely will cause a crash.

Method | Description
AddRefRows | Adds a reference count to an existing row handle.
GetData | Retrieves data from the rowset's copy of the row.
GetNextRows | Fetches rows sequentially, remembering the previous position.
ReleaseRows | Releases rows.
RestartPosition | Repositions the next fetch position to its initial position; that is, its position when the rowset was first created.


IRowset::AddRefRows

Adds a reference count to an existing row handle.

HRESULT AddRefRows(
   ULONG            cRows,
   const HROW         rghRows[],
   ULONG            rgRefCounts[],
   DBROWSTATUS   rgRowStatus[]);

Parameters

cRows

[in]
The number of rows for which to increment the reference count.

rghRows

[in]
An array of row handles for which to increment the reference count. The reference count of row handles is incremented by one for each time they appear in the array.

rgRefCounts

[out]
An array with cRows elements in which to return the new reference count for each row handle. The consumer allocates memory for this array. If rgRefCounts is a null pointer, no reference counts are returned.

rgRowStatus

[out]
An array with cRows elements in which to return values indicating the status of each row specified in rghRows. If no errors occur while incrementing the reference count of a row, the corresponding element of rgRowStatus is set to DBROWSTATUS_S_OK. If an error occurs while incrementing the reference count of a row, the corresponding element is set as specified in DB_S_ERRORSOCCURRED. The consumer allocates memory for this array. If rgRowStatus is a null pointer, no row statuses are returned.

Return Code

S_OK
The method succeeded. The reference count of all rows was successfully incremented. The following value can be returned in *prgRowStatus:

  • The reference count of the row was successfully incremented. The corresponding element of *prgRowStatus contains DBROWSTATUS_S_OK.

DB_S_ERRORSOCCURRED
An error occurred while incrementing the reference count of a row, but the reference count of at least one row was incremented. Successes can occur for the reason listed under S_OK. The following errors can occur:

  • A row handle was invalid. The reference count of the row was not incremented and the corresponding element of rgRowStatus contains DBROWSTATUS_E_INVALID.

  • A row handle referred to a row that had a reference count of zero. The reference count of the row was not incremented and the corresponding element of rgRowStatus contains DBROWSTATUS_E_INVALID.

  • A row handle referred to a row for which a deletion had been transmitted to the data source. The reference count of the row was not incremented and the corresponding element of rgRowStatus contains DBROWSTATUS_E_DELETED.

  • The consumer encountered a recoverable, provider-specific error, such as an RPC failure when transmitting the change to a remote server. The corresponding element of rgRowStatus contains DBROWSTATUS_E_FAIL.

E_FAIL
A provider-specific error occurred.

E_INVALIDARG
rghRows was a null pointer and cRows was not zero.

E_UNEXPECTED
ITransaction::Commit or ITransaction::Abort was called and the object is in a zombie state.

DB_E_ERRORSOCCURRED
Errors occurred while incrementing the reference count of all of the rows. Errors can occur for the reasons listed under DB_S_ERRORSOCCURRED.

Comments

AddRefRows must be supported for implementing multiple references to the same row even if the rowset does not support IRowsetIdentity.

It is always possible for a consumer to call AddRefRows while it is processing a method in IRowsetNotify. That is, the rowset must be reentrant through AddRefRows during notification.

If AddRefRows encounters an error while incrementing the reference count of a row, it sets the corresponding element in rgRowStatus to the appropriate DBROWSTATUS value and continues processing.

If a row handle is duplicated in rghRows, the corresponding row will have its reference count incremented by 1 for each time it appears in the array.

See Also

IRowset::ReleaseRows


IRowset::GetData

Retrieves data from the rowset's copy of the row.

HRESULT GetData (
   HROW            hRow,
   HACCESSOR   hAccessor,
   void *            pData);

Parameters

hRow

[in]
The handle of the row from which to get the data.

Caution The consumer must ensure that hRow contains a valid row handle; the provider might not validate hRow before using it. The result of passing the handle of a deleted row is provider-specific, although the provider cannot terminate abnormally. For example, the provider might return DB_E_BADROWHANDLE, DB_E_DELETEDROW, or it might get data from a different row. The result of passing an invalid row handle in hRow is undefined.

hAccessor

[in]
The handle of the accessor to use. If hAccessor is the handle of a null accessor (cBindings in IAccessor::CreateAccessor was zero), then GetData does not get any data values.

Caution The consumer must ensure that hAccessor contains a valid accessor handle; the provider might not validate hAccessor before using it. The result of passing an invalid accessor handle in hAccessor is undefined.

pData

[out]
A pointer to a buffer in which to return the data. The consumer allocates memory for this buffer. This pointer must be a valid pointer to a contiguous block of consumer-owned memory into which the data will be written.

Return Code

S_OK
The method succeeded. The status of all columns bound by the accessor is set to DBSTATUS_S_OK, DBSTATUS_S_ISNULL, or DBSTATUS_S_TRUNCATED.

DB_S_ERRORSOCCURRED
An error occurred while returning data for one or more columns, but data was successfully returned for at least one column. To determine the columns for which data was returned, the consumer checks the status values.

E_FAIL
A provider-specific error occurred.

E_INVALIDARG
pData was a null pointer and the accessor was not a null accessor.

E_UNEXPECTED
ITransaction::Commit or ITransaction::Abort was called and the object is in a zombie state.

DB_E_BADACCESSORHANDLE
hAccessor was invalid. Providers are not required to check for this condition, because doing so might slow the method significantly.

DB_E_BADACCESSORTYPE
The specified accessor was not a row accessor.

DB_E_BADROWHANDLE
hRow was invalid. Providers are not required to check for this condition, because doing so might slow the method significantly.

DB_E_DELETEDROW
hRow referred to a pending delete row or a row for which a deletion had been transmitted to the data source. Providers are not required to check for this condition, because doing so might slow the method significantly.

DB_E_ERRORSOCCURRED
Errors occurred while returning data for all columns. To determine what errors occurred, the consumer checks the status values.

If this method performs deferred accessor validation and that validation takes place before any data is transferred, it can also return any of the following return codes for the reasons listed in the corresponding DBBINDSTATUS values in IAccessor::CreateAccessor:

E_NOINTERFACE
DB_E_BADBINDINFO
DB_E_BADORDINAL
DB_E_BADSTORAGEFLAGS
DB_E_UNSUPPORTEDCONVERSION

Comments

This method makes no logical change to the state of the object.

A consumer calls GetData to retrieve data from rows that have been fetched by prior calls to methods such as GetNextRows.

A consumer can call GetData any number of times. In each call, it can pass a different accessor and the address of a different buffer. This means that the consumer can get as many copies of the data as it wants, and it can get data in different types if alternate conversions are available.

GetData does not enforce any security restrictions. The provider must not create a rowset that includes columns for which the consumer does not have read privileges, so GetData never encounters problems accessing the data for a column. The rowset can contain columns to which the consumer does not have write permission if DBPROP_COLUMNRESTRICT is VARIANT_TRUE. The methods that fetch rows must not return the handles of rows for which the consumer does not have read privileges, so GetData never encounters problems accessing a row. Such rows might exist if the DBPROP_ROWRESTRICT property is VARIANT_TRUE.

If GetData fails, the memory to which pData points is not freed but its contents are undefined. If, before GetData failed, the provider allocated any memory for return to the consumer, the provider frees this memory and does not return it to the consumer.

GetData must be reentrant during notifications. If the provider calls a method from IRowsetNotify in the consumer, the consumer must be able to call GetData while processing the notification method.

See Also

IRowset::GetNextRows, IRowsetChange::SetData


IRowset::GetNextRows

Fetches rows sequentially, remembering the previous position.

HRESULT GetNextRows (
   HCHAPTER   hChapter,
   LONG         lRowsOffset,
   LONG         cRows,
   ULONG *      pcRowsObtained,
   HROW **      prghRows);

Parameters

hChapter

[in]
The chapter handle. For nonchaptered rowsets, hChapter is ignored.

lRowsOffset

[in]
The signed count of rows to skip before fetching rows. Deleted rows that the provider has removed from the rowset are not counted in the skip. If this value is zero and cRows continues in the same direction as the previous call to either GetNextRows, or FindNextRow with a null pBookmark value, then the first row fetched will be the next row after the last one fetched in the previous call. If this value is zero and cRows reverses direction, then the first row fetched will be the last one fetched in the previous call.

lRowsOffset can be a negative number only if the value of the DBPROP_CANSCROLLBACKWARDS property is VARIANT_TRUE.

There is no guarantee that skipping rows is done efficiently on a sequential rowset. If the data source resides on a remote server, there may be remote support for skipping without transferring the intervening records across the network, but this is not guaranteed. For information about how the provider implements skipping, see the documentation for the provider.

cRows

[in]
The number of rows to fetch. A negative number means to fetch backward. cRows can be a negative number only if the value of the DBPROP_CANFETCHBACKWARDS property is VARIANT_TRUE.

If cRows is zero, no rows are fetched; the fetch direction and the next fetch position are unchanged, and the provider performs no processing, returning immediately from the method invocation. Specifically, lRowsOffset is ignored in this situation.

If the provider does not discover any other errors, the method returns S_OK; whether the provider checks for any other errors is provider-specific.

pcRowsObtained

[out]
A pointer to memory in which to return the actual number of fetched rows. If a warning condition occurs, this number may be less than the number of rows available or requested, and is the number of rows actually fetched before the warning condition occurred. If the consumer has insufficient permission to fetch all rows, GetNextRows fetches all rows for which the consumer has sufficient permission and skips all other rows. If the method fails, *pcRowsObtained is
set to zero.

prghRows

[out]
A pointer to memory in which to return an array of handles of the fetched rows. If *prghRows is not a null pointer on input, it must be a pointer to memory large enough to return the handles of the requested number of rows. If *prghRows is a null pointer on input, the rowset allocates memory for the row handles and returns the address to this memory; the consumer releases this memory with IMalloc::Free after it releases the row handles. If *prghRows is a null pointer on input and *pcRowsObtained is zero on output or if the method fails, the provider does not allocate any memory and ensures that *prghRows is a null pointer on output.

Return Code

S_OK
The method succeeded.

DB_S_ENDOFROWSET
GetNextRows reached the start or the end of the rowset or chapter or the start or end of the range on an index rowset and could not fetch all requested rows because the count extended beyond the end. The next fetch position is before the start or after the end of the rowset. The number of rows actually fetched is returned in *pcRowsObtained; this will be less than cRows.

lRowsOffset indicated a position either more than one row before the first row of the rowset or more than one row after the last row, and the provider was a version 2.0 or greater provider. *pcRowsObtained is set to zero and no rows are returned.

DB_S_ROWLIMITEXCEEDED
Fetching the number of rows specified in cRows would have exceeded the total number of active rows supported by the rowset. The number of rows that were actually fetched is returned in *pcRowsObtained. This condition can occur only when there are more rows available than can be handled by the rowset. Thus, this condition never conflicts with those described in DB_S_ENDOFROWSET and DB_S_STOPLIMITREACHED, both of which imply that no more rows were available.

DB_S_STOPLIMITREACHED
Fetching rows required further execution of the command, such as when the rowset uses a server-side cursor. Execution has been stopped because a resource limit has been reached. The number of rows that were actually fetched is returned in *pcRowsObtained.

E_FAIL
A provider-specific error occurred.

E_INVALIDARG
pcRowsObtained or prghRows was a null pointer.

E_OUTOFMEMORY
The provider was unable to allocate sufficient memory to complete the request.

E_UNEXPECTED
ITransaction::Commit or ITransaction::Abort was called and the object is in a zombie state.

DB_E_BADCHAPTER
The rowset was chaptered and hChapter was invalid.

The rowset was single-chaptered and the specified chapter was not the currently open chapter. The consumer must use the currently open chapter or release the currently open chapter before specifying a new chapter.

DB_E_BADSTARTPOSITION
lRowsOffset indicated a position either more than one row before the first row of the rowset or more than one row after the last row, and the provider was a 1.x provider,

DB_E_CANCELED
Fetching rows was canceled during notification. No rows were fetched.

DB_E_CANTFETCHBACKWARDS
cRows was negative and the rowset cannot fetch backward.

DB_E_CANTSCROLLBACKWARDS
lRowsOffset was negative and the rowset cannot scroll backward.

DB_E_NOTREENTRANT
The consumer called this method while it was processing a notification, and it is an error to call this method while processing the specified DBREASON value.

DB_E_ROWSNOTRELEASED
The provider requires release of existing rows before new ones can be fetched. For more information, see DBPROP_CANHOLDROWS in "Rowset Properties".

DB_SEC_E_PERMISSIONDENIED
The consumer did not have sufficient permission to fetch any of the rows; no rows were fetched.

Comments

GetNextRows fetches a sequence of rows. The provider maintains a next fetch position that is used in subsequent calls to either GetNextRows or FindNextRow. The next fetch position is changed either by calling GetNextRows, or by calling FindNextRow with a null pBookmark value. Calling FindNextRow with a non-null pBookmark value has no effect on the next fetch position. If the fetch direction is reversed from the previous call, then the next fetch position in the new direction is the last row that was fetched in the previous direction, otherwise the next fetch position is the row following the last row fetched by GetNextRows, or by FindNextRow with a null pBookmark value.

For a newly created rowset, or any time the next fetch position is prior to the first row of the rowset, the next fetch position is computed as follows, where N is the number of rows in the rowset. lRowsOffset can be less than zero only if DBPROP_CANSCROLLBACKWARDS is VARIANT_TRUE.

Value of lRowsOffset | Next fetch position
lRowsOffset > 0 | After lRowsOffset
lRowsOffset < 0 | After N – abs(lRowsOffset)
lRowsOffset = 0 | Before first row if cRows > 0, after last row if cRows < 0

For example:

GetNextRows call Row fetched New next fetch position
GetNextRows(hReserved, 2, 1,
    pcRowsObtained,
    prghRows);
 3rd row After 3rd row
GetNextRows(hReserved, 2, -1,
    pcRowsObtained,
    prghRows);
 2nd row After 1st row
GetNextRows(hReserved, -2, 1,
    pcRowsObtained,
    prghRows);
 N – 1st row After N – 1st row
 GetNextRows(hReserved, -2, -1,
    pcRowsObtained,
    prghRows);
 N – 2nd row After N – 3rd row

None of the other methods that fetch rows, except for IRowsetFind::FindNextRow with a null pBookmark value, has any effect on the next fetch position.

GetNextRows increments the reference count of each row for which it returns a handle by 1. Thus, if a handle is returned for a row that has already been fetched, the reference count of that row will be greater than 1. ReleaseRows must be called once for each time the handle to a row has been returned.

If the provider encounters a problem fetching a row—for example, data stored in a text file contains a letter in a numeric column—GetNextRows fetches the row normally, returns the row handle, and returns S_OK. However, when the consumer calls GetData for the row, the provider returns DBSTATUS_E_CANTCONVERTVALUE as the status for the offending column.

GetNextRows must always check for the conditions that cause E_INVALIDARG, E_UNEXPECTED, DB_E_CANTFETCHBACKWARDS, DB_E_CANTSCROLLBACKWARDS, DB_E_NOTREENTRANT, and DB_E_ROWSNOTRELEASED before changing the next fetch position. If it returns any other error besides these, the next fetch position is unknown. For example, the provider might have to perform actions that change the next fetch position in order to determine that the error DB_E_BADSTARTPOSITION occurred. When the next fetch position is unknown, the consumer generally calls RestartPosition to return it to a known position.

See Also

IRowset::GetData, IRowsetLocate::GetRowsAt, IRowsetLocate::GetRowsByBookmark, IRowsetScroll::GetRowsAtRatio


IRowset::ReleaseRows

Releases rows.

HRESULT ReleaseRows (
   ULONG               cRows,
   const HROW            rghRows[],
   DBROWOPTIONS   rgRowOptions[]
   ULONG               rgRefCounts[],
   DBROWSTATUS      rgRowStatus[]);

Parameters

cRows

[in]
The number of rows to release. If cRows is zero, ReleaseRows does not do anything.

rghRows

[in]
An array of handles of the rows to be released. The row handles need not form a logical cluster; they may have been obtained at separate times and need not be for contiguous underlying rows. They must belong to the current thread. Row handles are decremented by one reference count for each time they appear in the array.

rgRowOptions

[in]
An array of cRows elements containing bitmasks indicating additional options to be specified when releasing a row. This parameter is reserved for future use and should be set to a null pointer.

typedef DWORD DBROWOPTIONS;

rgRefCounts

[out]
An array with cRows elements in which to return the new reference count of each row. If rgRefCounts is a null pointer, no counts are returned. The consumer allocates, but is not required to initialize, memory for this array and passes the address of this memory to the provider. The provider returns the reference counts in the array.

rgRowStatus

[out]
An array with cRows elements in which to return values indicating the status of each row specified in rghRows. If no errors or warnings occur while releasing a row, the corresponding element of rgRowStatus is set to DBROWSTATUS_S_OK. If an error or warning occurs while releasing a row, the corresponding element is set as specified in DB_S_ERRORSOCCURRED. The consumer allocates memory for this array. If rgRowStatus is a null pointer, no row statuses are returned.

Return Code

S_OK
The method succeeded. All rows were successfully released. The following values can be returned in *prgRowStatus:

  • The row was successfully released. The corresponding element of *prgRowStatus contains DBROWSTATUS_S_OK.

  • A row had a pending change. The row was released and the corresponding element of rgRowStatus contains DBROWSTATUS_S_PENDINGCHANGES.

DB_S_ERRORSOCCURRED
An error occurred while releasing a row, but at least one row was successfully released. Successes and warnings can occur for the reasons listed under S_OK. The following errors can occur:

  • A row handle was invalid. The row was not released and the corresponding element of rgRowStatus contains DBROWSTATUS_E_INVALID.

  • The consumer encountered a recoverable, provider-specific error, such as an RPC failure when transmitting the change to a remote server. The corresponding element of rgRowStatus contains DBROWSTATUS_E_FAIL.

E_FAIL
A provider-specific error occurred.

E_INVALIDARG
rghRows was a null pointer and cRows was not equal to zero.

DB_E_ERRORSOCCURRED
Errors occurred while releasing all of the rows. Errors can occur for the reasons listed under DB_S_ERRORSOCCURRED.

DB_E_NOTREENTRANT
The consumer called this method while it was processing a notification, and it is an error to call this method while processing the specified DBREASON value.

Comments

ReleaseRows decreases the reference count on the specified rows. It must be called once for each time that a row was fetched. For example, if the row was fetched three times, ReleaseRows must be called three times. Furthermore, if a row handle is duplicated in rghRows, the corresponding row will have its reference count decremented by one for each time it appears in the array.

If a provider doesn't support exact reference counts on rows, it should return a reference count of 1 while the row is active. Consumers should be aware of this behavior and should use the returned reference count for debugging purposes only; consumers should not rely on the returned reference count to indicate whether the row would survive another release. In this case, a provider may choose to return S_OK for any and all calls to ReleaseRows until the rowset itself is released.

If a consumer calls ReleaseRows on a row with pending changes, the row remains valid and ReleaseRows returns DBROWSTATUS_S_PENDINGCHANGES in rgRowStatus.

When the reference count for a row decreases to zero, the row is released:

  • Subject to the rules of the current transaction, the rowset is free to discard any resources used by a row that has a reference count of zero. For example, these might include memory, locks, and original values. When the rowset actually discards these resources is provider-specific.

  • If the row has pending changes, the row still remains valid even though its reference count is zero. Consumers should not use the handle of a row that has a reference count of zero, even though the handle might still be valid.

  • Pending changes are not lost when releasing a reference count obtained from GetRowsAt. A provider may take its own reference count on the row handle or store the row internally until pending changes are committed or dismissed (using Update or Undo).

After a row is released, methods called with the handle to that row return DB_E_BADROWHANDLE if the row has pending changes. After the pending changes are transmitted to the data source, methods might continue to return this error. However, the provider might have an implementation that recycles row handles and thereafter cannot detect the misuse. Because provider behavior varies, consumers should not use the handles of released rows.

If ReleaseRows encounters an error while decrementing the reference count of a row or releasing the row, it sets the corresponding element in rgRowStatus to the appropriate DBROWSTATUS value and continues processing.

This method can be called while the rowset is in a zombie state to allow the consumer to clean up after a transaction has been committed or aborted.

See Also

IRowset::AddRefRows


IRowset::RestartPosition

Repositions the next fetch position used by GetNextRows or FindNextRow to its initial position; that is, its position when the rowset was first created.

HRESULT RestartPosition (
   HCHAPTER   hChapter);

Parameters

hChapter

[in]
The chapter handle. For nonchaptered rowsets, hChapter is ignored.

Return Code

S_OK
The method succeeded. The provider did not have to reexecute the command, either because the rowset supports positioning on the first row without reexecuting the command or because the rowset is already positioned on the first row.

DB_S_COLUMNSCHANGED
The order of the columns was not specified in the object that created the rowset. The provider had to reexecute the command to reposition the next fetch position to its initial position, and the order of the columns changed.

The provider had to reexecute the command to reposition the next fetch position to its initial position, and columns were added or removed from the rowset. This is generally due to a change in the underlying schema and is extremely uncommon.

This return code takes precedence over DB_S_COMMANDREEXECUTED. That is, if the conditions described here and in those described in DB_S_COMMANDREEXECUTED both occur, the provider returns this code. A change to the columns generally implies that the command was reexecuted.

DB_S_COMMANDREEXECUTED
The command associated with this rowset was reexecuted. If the properties DBPROP_OWNINSERT and DBPROP_OWNUPDATEDELETE are VARIANT_TRUE, then the consumer will see its own changes. If the properties DBPROP_OWNINSERT or DBPROP_OWNUPDATEDELETE are VARIANT_FALSE, then the rowset may see its changes. The order of the columns remains unchanged.

E_FAIL
A provider-specific error occurred.

E_UNEXPECTED
ITransaction::Commit or ITransaction::Abort was called and the object is in a zombie state.

DB_E_BADCHAPTER
The rowset was chaptered and hChapter was invalid.

The rowset was single-chaptered and the specified chapter was not the currently open chapter. The consumer must use the currently open chapter or release the currently open chapter before specifying a new chapter.

DB_E_CANCELED
RestartPosition was canceled during notification. The next fetch position remains unmodified.

DB_E_CANNOTRESTART
The rowset was built over a live data stream (for example, a stock feed) and the position cannot be restarted.

DB_E_NOTREENTRANT
The provider called a method from IRowsetNotify in the consumer and the method has not yet returned.

DB_E_ROWSNOTRELEASED
The provider requires release of existing rows before restarting because the Rowset will be regenerated. This may be required even if the provider supports a value of VARIANT_TRUE for DBPROP_CANHOLDROWS.

DB_SEC_E_PERMISSIONDENIED
The consumer did not have sufficient permission to reposition the next fetch position.

Comments

For information about the next fetch position when the rowset is first created, see GetNextRows.

If the underlying command contains output parameters, RestartPosition should not reset those parameters.

If the rowset was generated as a result of a procedure call, and the rowset is forward-only, the procedure may be reexecuted in order to satisfy the call to RestartPosition. This may cause other side effects. Additionally, if the stored procedure has been changed, the rowset may have a different schema. If the rowset is able to restart the next fetch position without reexecuting the procedure, RestartPosition should not reexecute it.

How expensive RestartPosition is depends on the provider, the rowset characteristics, and the tables underlying the rowset. If the rowset supports IRowsetLocate, then RestartPosition is always an inexpensive operation.

If the rowset is sequential, then RestartPosition might require reexecution of the underlying command. For some providers, this is always the case. For other providers, a rule of thumb is that rowsets built from a single table are not expensive to restart, but rowsets built by joining two or more tables are expensive to restart. If the provider reexecutes the command to restart the next fetch position, then the new rowset might return a different set of rows, differently ordered columns, and, in extreme cases, a different set of columns. Reexecution of a command by RestartPosition does not reinherit accessors.

A provider that reports DBPROP_QUICKRESTART as VARIANT_FALSE may require that all existing row handles are released prior to successfully processing a call to RestartPosition.

A consumer can determine whether a provider can quickly restart the next fetch position by attempting to set DBPROP_QUICKRESTART to VARIANT_TRUE. Setting this property to VARIANT_TRUE does not guarantee that the rowset can be quickly restarted because the provider is not required to honor the property. This behavior is necessary because the provider cannot evaluate the command at the time the property is set. For example, the consumer can set DBPROP_QUICKRESTART to VARIANT_TRUE and then change the command text.

In implementations that require reexecution of a command to reposition the next fetch position to its initial position, the provider is responsible for caching all parameters required by the command.

If RestartPosition returns DB_S_COLUMNSCHANGED and the consumer subsequently calls methods in IColumnsInfo or IColumnsRowset, these methods must reflect the new metadata. Existing rowset accessors are not updated to reflect the new metadata. That is, IAccessor::GetBindings returns exactly the same information it would have returned before RestartPosition was called. If such accessors are subsequently used, such as in a call to GetData, the provider must revalidate them. If none of the columns bound by the accessor have changed, the accessor can be used successfully. If any of the columns have changed, the appropriate error or warning is returned.

See Also

IRowset::GetNextRows, IRowsetFind::FindNextRow


IRowsetChange

The methods in IRowsetChange are used to update the values of columns in existing rows, delete existing rows, and insert new rows.

IRowsetChange requires IAccessor and IRowset.

The consumer calls methods in IRowsetChange to modify rows as follows.

  • SetData sets column data in an existing row.

  • DeleteRows deletes existing rows.

  • InsertRow creates a new row and sets initial values.

SetData and InsertRow require the use of an accessor. For more information about accessors, see "Accessors".

SetData and InsertRow can fail for a number of reasons. The most common of these is that new data values do not meet the schema or integrity constraints of the column. Furthermore, rowsets can have row-by-row and column-by-column access permissions that override the general permissions of the table or column.

Changes made through IRowsetChange are immediately transmitted to the data source; this is known as immediate update mode.

Method | Description
DeleteRows | Deletes rows.
InsertRow | Creates and initializes a new row.
SetData | Sets data in one or more columns in a row.


IRowsetChange::DeleteRows

Deletes rows.

HRESULT DeleteRows (
   HCHAPTER         hChapter,
   ULONG            cRows,
   const HROW         rghRows[],
   DBROWSTATUS   rgRowStatus[]);

Parameters

hChapter

[in]
The chapter handle. For nonchaptered rowsets, hChapter is ignored.

cRows

[in]
The number of rows to be deleted. If cRows is zero, DeleteRows does not do anything.

rghRows

[in]
An array of handles of the rows to be deleted.

If rghRows includes a duplicate row handle, DeleteRows behaves as follows. If the row handle is valid, it is provider-specific whether the returned row status information for each row or a single instance of the row is set to DBROWSTATUS_S_OK. If the row handle is invalid, the row status information for each occurrence of the row contains the appropriate error.

rgRowStatus

[out]
An array with cRows elements in which to return values indicating the status of each row specified in rghRows. If no errors or warnings occur while deleting a row, the corresponding element of rgRowStatus is set to DBROWSTATUS_S_OK. If a warning occurs while deleting a row, the corresponding element is set as specified in S_OK. If an error occurs while deleting a row, the corresponding element is set as specified in DB_S_ERRORSOCCURRED. The consumer allocates memory for this array. If rgRowStatus is a null pointer, no row statuses are returned.

Return Code

S_OK
The method succeeded. All rows were successfully deleted. The following values can be returned in rgRowStatus:

  • The row was successfully deleted and no warning conditions occurred. The corresponding element of rgRowStatus contains DBROWSTATUS_S_OK.

  • The rowset was in immediate update mode, and deleting a single row caused more than one row to be deleted in the data source. For more information, see the DBPROP_REPORTMULTIPLECHANGES property. The corresponding element of rgRowStatus contains DBROWSTATUS_S_MULTIPLECHANGES.

DB_S_ERRORSOCCURRED
An error occurred while deleting a row, but at least one row was successfully deleted. Successes and warnings can occur for the reasons listed under S_OK. The following errors can occur:

  • An element of rghRows was invalid or was a row handle to which the current thread does not have access rights. The corresponding element of rgRowStatus contains DBROWSTATUS_E_INVALID.

  • Deletion of a row was canceled during notification. The row was not deleted and the corresponding element of rgRowStatus contains DBROWSTATUS_E_CANCELED.

  • An element of rghRows referred to a row with a pending delete or for which a deletion had been transmitted to the data source. The corresponding element of rgRowStatus contains DBROWSTATUS_E_DELETED.

  • Deleting a row referred to by an element of rghRows violated the integrity constraints for the column or table. The corresponding element of rgRowStatus contains DBROWSTATUS_E_INTEGRITYVIOLATION.

  • The rowset was in immediate update mode and the row was not deleted due to reaching a limit on the server, such as a query execution timing out. The error in the corresponding element of rgRowStatus contains DBROWSTATUS_E_LIMITREACHED.

  • Deleting a row would exceed the limit for pending changes specified by the rowset property DBPROP_MAXPENDINGROWS. The corresponding element of rgRowStatus contains DBROWSTATUS_E_MAXPENDCHANGESEXCEEDED.

  • DBPROP_CHANGEINSERTEDROWS was VARIANT_FALSE and an element of rghRows referred to a row for which the insertion has been transmitted to the data source. The corresponding element of rgRowStatus contains DBROWSTATUS_E_NEWLYINSERTED.

  • The consumer did not have sufficient permission to delete a row. This error can be returned only if the value of the DBPROP_ROWRESTRICT property is VARIANT_TRUE. The corresponding element of rgRowStatus contains DBROWSTATUS_E_PERMISSIONDENIED.
  • The consumer encountered a recoverable, provider-specific error, such as an RPC failure when transmitting the change to a remote server. The corresponding element of rgRowStatus contains DBROWSTATUS_E_FAIL.

E_FAIL
A provider-specific error occurred.

E_INVALIDARG
rghRows was a null pointer and cRows was greater than or equal to one.

E_UNEXPECTED
ITransaction::Commit or ITransaction::Abort was called and the object is in a zombie state.

DB_E_BADCHAPTER
The rowset was chaptered and hChapter was invalid.

The rowset was single-chaptered and the specified chapter was not the currently open chapter. The consumer must use the currently open chapter or release the currently open chapter before specifying a new chapter.

DB_E_ERRORSOCCURRED
Errors occurred while deleting all of the rows. Errors can occur for the reasons listed under DB_S_ERRORSOCCURRED.

DB_E_NOTREENTRANT
The consumer called this method while it was processing a notification, and it is an error to call this method while processing the specified DBREASON value.

DB_E_NOTSUPPORTED
The provider does not support this method.

Comments

In delayed update mode, DeleteRows marks rows for deletion, rather than actually deleting them. Rows with pending deletes cannot be used in any methods except IRowset::ReleaseRows. The deletion is not transmitted to the data source until Update is called. In immediate update mode, DeleteRows transmits deletions to the data source immediately.

After a deletion has been transmitted to the data source, it cannot be undone. The row cannot be used with any method except ReleaseRows. Neither DeleteRows nor Update releases rows after transmitting deletions to the data source. The consumer must release the row with ReleaseRows.

If DeleteRows is called for a row with a pending insert, the row is placed in the same state as a row for which a deletion has been transmitted to the data source. That is, if a row is inserted and then deleted in delayed update mode, the deletion cannot be undone. The row cannot be used with any method except ReleaseRows, which must be called to release it.

If an error occurs while deleting a row, DeleteRows continues deleting the other rows in rghRows and returns DB_S_ERRORSOCCURRED or DB_E_ERRORSOCCURRED. It returns status information about each row in rgRowStatus.

If the DBPROP_ROWRESTRICT property is VARIANT_TRUE, the consumer may have permission to delete some rows but not other rows.


IRowsetChange::InsertRow

Creates and initializes a new row.

HRESULT InsertRow (
   HCHAPTER      hChapter,
   HACCESSOR   hAccessor,
   void *            pData,
   HROW   *         phRow);

Parameters

hChapter

[in]
The chapter handle. For nonchaptered rowsets, hChapter is ignored.

hAccessor

[in]
The handle of the accessor to use.

If hAccessor is a null accessor (that is, an accessor for which cBindings in IAccessor::CreateAccessor was zero), then pData is ignored and the rows are initialized as specified in the Comments. Thus, the role of a null accessor is to construct a default row; it is a convenient way for a consumer to obtain a handle for a new row without having to set any values in that row initially.

pData

[in]
A pointer to memory containing the new data values, at offsets that correspond to the bindings in the accessor.

phRow

[out]
A pointer to memory in which to return the handle of the new row. If this is a null pointer, then no reference count is held on the row. Consumers should set this to null if they do not require the ability to make further changes to, or retrieve data from, the newly inserted row. Whether or not default or computed values from the server are available when calling GetData for this row handle depends on the setting of the DBPROP_SERVERDATAONINSERT. If InsertRow returns an error, and phRow is not a null pointer on input, *phRow is set to null on output and no row handle is returned.

Note Passing in a null pointer for phRow, or releasing the row handle returned in *phRow, does not release the row until the change is transmitted to the data source.

Return Code

S_OK
The method succeeded. The status of all columns bound by the accessor is set to DBSTATUS_S_OK or DBSTATUS_S_ISNULL.

DB_S_ERRORSOCCURRED
An error occurred while setting data for one or more columns, but data was successfully set for at least one column. To determine the columns for which values were invalid, the consumer checks the status values.

E_FAIL
A provider-specific error occurred.

E_INVALIDARG
pData was a null pointer and hAccessor was not a null accessor.

E_OUTOFMEMORY
The provider was unable to allocate sufficient memory in which to instantiate the row.

E_UNEXPECTED
ITransaction::Commit or ITransaction::Abort was called and the object is in a zombie state.

DB_E_ABORTLIMITREACHED
The rowset was in immediate update mode and the row was not inserted due to reaching a limit on the server, such as a query execution timing out.

DB_E_BADACCESSORHANDLE
hAccessor was invalid.

DB_E_BADACCESSORTYPE
The specified accessor was not a row accessor or was a reference accessor.

DB_E_BADCHAPTER
The rowset was chaptered and hChapter was invalid.

The rowset was single-chaptered and the specified chapter was not the currently open chapter. The consumer must use the currently open chapter or release the currently open chapter before specifying a new chapter.

DB_E_CANCELED
The insertion was canceled during notification. The row was not inserted.

DB_E_CANTCONVERTVALUE
The data value for one or more columns couldn't be converted for reasons other than sign mismatch or data overflow, and the provider was unable to determine which columns couldn't be converted. Providers that can detect which columns could not be converted return DB_S_ERRORSOCCURRED and set the status flag for the columns that couldn't be converted to DBSTATUS_E_CANTCONVERTVALUE.

DB_E_DATAOVERFLOW
Conversion failed because the data value for one or more columns overflowed the type used by the provider and the provider was unable to determine which columns caused the overflow. Providers that can detect which columns caused the overflow return DB_S_ERRORSOCCURRED and set the status flag for the columns in violation to DBSTATUS_E_DATAOVERFLOW.

DB_E_ERRORSOCCURRED
An error occurred while setting data for one or more columns and data was not successfully set for any columns. To determine the columns for which values were invalid, the consumer checks the status values.

DB_E_INTEGRITYVIOLATION
The data violated the integrity constraints for one or more columns of the rowset and the provider was unable to determine which columns violated the integrity constraints. Providers that can detect which columns violated the integrity constraints return DB_S_ERRORSOCCURRED and set the status flag for the columns in violation to DBSTATUS_E_INTEGRITYVIOLATION.

DB_E_MAXPENDCHANGESEXCEEDED
The number of rows that have pending changes has exceeded the limit specified by the DBPROP_MAXPENDINGROWS property.

DB_E_NOTREENTRANT
The provider called a method from IRowsetNotify in the consumer and the method has not yet returned.

DB_E_NOTSUPPORTED
The provider does not support this method.

DB_E_ROWLIMITEXCEEDED
Creating another row would have exceeded the total number of active rows supported by the rowset.

DB_E_ROWSNOTRELEASED
The consumer attempted to insert a new row before releasing previously retrieved row handles or transmitting pending changes to the data source, and DBPROP_CANHOLDROWS is VARIANT_FALSE.

DB_SEC_E_PERMISSIONDENIED
The consumer did not have sufficient permission to insert a new row. This error can be returned only if the value of the DBPROP_ROWRESTRICT property is VARIANT_TRUE. If the rowset is in delayed update mode, this error might not be returned until IRowsetUpdate::Update is called.

If this method performs deferred accessor validation and that validation takes place before any data is transferred, it can also return any of the following return codes for the applicable reasons listed in the corresponding DBBINDSTATUS values in IAccessor::CreateAccessor:

E_NOINTERFACE
DB_E_BADBINDINFO
DB_E_BADORDINAL
DB_E_BADSTORAGEFLAGS
DB_E_UNSUPPORTEDCONVERSION

Comments

InsertRow creates a new row and initializes its columns. If phRow is not a null pointer, it then returns the handle of this row to the consumer and sets its reference count to one. In immediate update mode, the row is immediately transmitted to the data source.

To the consumer, newly inserted rows are almost indistinguishable from other rows. For example, they can be deleted with DeleteRows and updated with SetData. However, methods that fetch rows might not be able to return them.Furthermore, they might not contain the correct values for computed columns, including bookmark columns on some providers.

The DBPROP_COLUMNRESTRICT and DBPROP_ROWRESTRICT properties affect how security is enforced and how security errors are returned. If DBPROP_COLUMNRESTRICT is VARIANT_TRUE, the consumer might not have write permission on some columns. If the consumer attempts to write to these columns, InsertRows returns a column status of DBSTATUS_E_PERMISSIONDENIED and a return code of DB_S_ERRORSOCCURRED. If the DBPROP_ROWRESTRICT property is VARIANT_TRUE, the consumer might not have permission to insert some rows. If the consumer attempts to insert one of these rows, InsertRows returns a code of DB_SEC_E_PERMISSIONDENIED and no new row is created.

When a row is created, initialization proceeds in an orderly fashion:

  1. The provider sets all columns to their default values. If there is no default value and the column is nullable, it sets the column to NULL. If the column is non-nullable, it sets the column status to DBSTATUS_E_UNAVAILABLE. If the provider is unable or unwilling to determine the default value of a column or whether that column is nullable, it sets the column status to DBSTATUS_E_UNAVAILABLE; the provider might be unwilling to determine default values and nullability if doing so requires a call to the data source.

    If the column status is DBSTATUS_E_UNAVAILABLE, the consumer can still send this value to the data source to use the default. In this case, the default is available after the insertion is transmitted to the data source. To see the default, the consumer must call GetLastVisibleData or RefreshVisibleData. However, if there is no default for the column and it is non-nullable, this will cause a schema violation.

  2. The provider calls IRowsetNotify::OnRowChange with DBREASON_ROW_INSERT if any consumer of the rowset is using notifications. This serves as a hook allowing, among other things, more complex nondeclarative default values to be set in the row.

  3. InsertRow does not further modify the column values if the accessor is a null accessor; it returns the handle to the newly created row.

  4. The provider uses the accessor, if it is not a null accessor, to set columns with the values provided by the consumer in *pData. During this process, the provider does not generate notifications like it does when setting data in SetData. This prevents, for example, DBREASON_COLUMN_SET notifications from being generated for a row that is not yet properly constructed.

Domain and schema validation is enforced as it is with SetData.

If InsertRow returns an error, it does not create a new row.

It is not recommended to use null accessors because some providers may not be able to determine default values and may not be able to identify a row inserted with all default values.

See Also

IRowset::GetData, IRowsetChange::SetData


IRowsetChange::SetData

Sets data values in one or more columns in a row.

HRESULT SetData (
   HROW            hRow,
   HACCESSOR   hAccessor,
   void *            pData);

Parameters

hRow

[in]
The handle of the row in which to set data.

hAccessor

[in]
The handle of the accessor to use. If hAccessor is the handle of a null accessor (cBindings in IAccessor::CreateAccessor was zero), then SetData does not set any data values.

pData

[in]
A pointer to memory containing the new data values, at offsets that correspond to the bindings in the accessor.

Return Code

S_OK
The method succeeded. The status of all columns bound by the accessor is set to DBSTATUS_S_OK or DBSTATUS_S_ISNULL

DB_S_ERRORSOCCURRED
An error occurred while setting data for one or more columns, but data was successfully set for at least one column. To determine the columns for which data was returned, the consumer checks the status values.

DB_S_MULTIPLECHANGES
The rowset was in immediate update mode and updating the row caused more than one row to be updated in the data source.

This return code takes precedence over DB_S_ERRORSOCCURRED. That is, if the conditions described here and in those described in DB_S_ERRORSOCCURRED both occur, the provider returns this code. When the consumer receives this return code, it should also check for the conditions described in DB_S_ERRORSOCCURRED.

E_FAIL
A provider-specific error occurred.

E_INVALIDARG
pData was a null pointer and the accessor was not a null accessor.

E_UNEXPECTED
ITransaction::Commit or ITransaction::Abort was called and the object is in a zombie state.

DB_E_ABORTLIMITREACHED
The rowset was in immediate update mode and the row was not updated due to reaching a limit on the server, such as a query execution timing out.

DB_E_BADACCESSORHANDLE
hAccessor was invalid.

DB_E_BADACCESSORTYPE
The specified accessor was not a row accessor or was a reference accessor.

DB_E_BADROWHANDLE
hRow was invalid.

DB_E_CANCELED
The change was canceled during notification. No columns are changed.

DB_E_CANTCONVERTVALUE
The data value for one or more columns couldn't be converted for reasons other than sign mismatch or data overflow, and the provider was unable to determine which columns couldn't be converted. Providers that can detect which columns could not be converted return DB_S_ERRORSOCCURRED and set the status flag for the columns that couldn't be converted to DBSTATUS_E_CANTCONVERTVALUE.

DB_E_CONCURRENCYVIOLATION
The rowset was using optimistic concurrency and the value of a column has been changed since the containing row was last fetched or resynchronized. SetData returns this error only when the rowset is in immediate update mode.

DB_E_DATAOVERFLOW
Conversion failed because the data value for one or more columns overflowed the type used by the provider and the provider was unable to determine which columns caused the overflow. Providers that can detect which columns caused the overflow return DB_S_ERRORSOCCURRED and set the status flag for the columns in violation to DBSTATUS_E_DATAOVERFLOW.

DB_E_DELETEDROW
hRow referred to a row with a pending delete or for which a deletion had been transmitted to the data source.

DB_E_ERRORSOCCURRED
An error occurred while setting data for one or more columns and data was not successfully set for any columns. To determine the columns for which values were invalid, the consumer checks the status values.

DB_E_INTEGRITYVIOLATION
The data violated the integrity constraints for one or more columns of the rowset and the provider was unable to determine which columns violated the integrity constraints. Providers that can detect which columns violated the integrity constraints return DB_S_ERRORSOCCURRED and set the status flag for the columns in violation to DBSTATUS_E_INTEGRITYVIOLATION.

DB_E_MAXPENDCHANGESEXCEEDED
The number of rows that have pending changes has exceeded the limit specified by the DBPROP_MAXPENDINGROWS property.

DB_E_NEWLYINSERTED
DBPROP_CHANGEINSERTEDROWS was VARIANT_FALSE and hRow referred to a row for which the insertion has been transmitted to the data source.

DB_E_NOTREENTRANT
The consumer called this method while it was processing a notification, and it is an error to call this method while processing the specified DBREASON value.

DB_E_NOTSUPPORTED
The provider does not support this method.

DB_SEC_E_PERMISSIONDENIED
The consumer did not have sufficient permission to update the row. This error can be returned only if the value of the DBPROP_ROWRESTRICT property is VARIANT_TRUE. If the rowset is in delayed update mode, this error might not be returned until IRowsetUpdate::Update is called.

If this method performs deferred accessor validation and that validation takes place before any data is transferred, it can also return any of the following return codes for the applicable reasons listed in the corresponding DBBINDSTATUS values in IAccessor::CreateAccessor:

E_NOINTERFACE
DB_E_BADBINDINFO
DB_E_BADORDINAL
DB_E_BADSTORAGEFLAGS
DB_E_UNSUPPORTEDCONVERSION

Comments

SetData sets data values in one or more columns in a row.

If a computed column depends on a column that is changed with SetData, the provider is not required to compute the new value of the computed column. If the provider computes the new value, it sends a notification to the consumer. If the provider does not compute the new value but lets the data source do so, then the computed value is not available until after the change is transmitted to the data source—that is, after SetData is called in immediate update mode. To retrieve the computed value in this case, the consumer calls RefreshVisibleData or GetLastVisibleData in IRowsetRefresh. Bookmark columns are often computed, such as when the bookmark is the primary key or is a ROWID assigned by the data source.

If SetData changes a column that is used to order the rowset, the DBPROP_IMMOBILEROWS property describes whether the row is moved based on its new value. If this property is VARIANT_TRUE, the row is not moved. If this property is VARIANT_FALSE, the row is moved. If the rowset is not ordered, then the position of updated rows is not changed. Note that, if the rowset is built on a set of key columns (typically a rowset for which DBPROP_OTHERUPDATEDELETE is VARIANT_TRUE but DBPROP_OTHERINSERT is VARIANT_FALSE), changing the value of key column is generally equivalent to deleting the current row and inserting a new one. Thus, the row may appear to move or even disappear from the rowset (if DBPROP_OWNINSERT is VARIANT_FALSE), even though the DBPROP_IMMOBILEROWS property is VARIANT_TRUE.

SetData cannot be called for rows with pending or transmitted deletes.

The DBPROP_COLUMNRESTRICT and DBPROP_ROWRESTRICT properties affect how security is enforced and how security errors are returned. If DBPROP_COLUMNRESTRICT is VARIANT_TRUE, the consumer might not have write permission on some columns. If the consumer attempts to write to these columns, SetData returns a column status of DBSTATUS_E_PERMISSIONDENIED and a return code of DB_S_ERRORSOCCURRED. If the DBPROP_ROWRESTRICT property is VARIANT_TRUE, the consumer might not have permission to update some rows. If the consumer attempts to update one of
these rows, SetData returns a code of DB_SEC_E_PERMISSIONDENIED and no data is set.

If any consumer of the rowset is using notifications, the provider sends notifications. These notifications can be vetoed, in which case the provider sends the DBEVENTPHASE_FAILEDTODO phase of the notification. When the consumer then calls Update, if the update is in delayed mode, the provider does not send additional DBREASON_COLUMN_SET notifications for the rows. However, if Update computes the value of computed columns, it sends DBREASON_COLUMN_RECALCULATED notifications. In this case, the provider must either be prepared to undo all pending changes for the row, and return DBREASON_ROW_UNDOCHANGE, or set the fCantDeny flag to TRUE.

The following sequence of notifications occurs for a rowset operating in delayed update mode:

  1. If the row is being changed for the first time since it was created, or changes were transmitted, the provider sends the DBEVENTPHASE_OKTODO and DBEVENTPHASE_ABOUTTODO phases of the DBREASON_ROW_FIRSTCHANGE notification.

  2. The provider sends the DBEVENTPHASE_OKTODO, DBEVENTPHASE_ABOUTTODO, and DBEVENTPHASE_SYNCHAFTER phases of the DBREASON_COLUMN_SET notification, in that order, provided none of the listeners veto any of the phases. The notification covers all the columns defined by the accessor used in the call to SetData.

  3. The provider sends the DBEVENTPHASE_SYNCHAFTER phase of the DBREASON_ROW_FIRSTCHANGE notification, assuming the provider sent the earlier phases of this notification.

  4. The provider sends the DBEVENTPHASE_DIDEVENT phase of the DBREASON_COLUMN_SET notification.

  5. The provider sends the DBEVENTPHASE_DIDEVENT phase of the ROW_FIRSTCHANGE notification.

See Also

IRowset::GetData, IRowsetChange::InsertRow


IRowsetFind

IRowsetFind is the interface that allows consumers to find a row within the rowset matching a specified value.

Consumers call IRowsetFind to locate the next row in the rowset matching a specified value.

Method | Description
FindNextRow | Returns the next row matching the criteria.


IRowsetFind::FindNextRow

Begin at the specified bookmark and find the next row matching the specified value.

HRESULT FindNextRow (
   HCHAPTER                  hChapter,
   HACCESSOR               hAccessor,
      void *                        pFindValue,
      DBCOMPAREOP            CompareOp,
      ULONG                     cbBookmark,
   const BYTE *                  pBookmark,
      LONG                        IRowsOffset,
   LONG                        cRows,
   ULONG *                     pcRowsObtained,
      HROW **                     prghRows);

Parameters

hChapter

[in]
The chapter handle. For nonchaptered rowsets, hChapter is ignored.

hAccessor

[in]
Accessor describing the value to be matched. This accessor must describe only a single column. If it describes more than one column, FindNextRow returns DB_E_BADBINDINFO.

Valid coercions for FindNextRow are the same as those for SetData.

pFindValue

[in]
Pointer to the value to be matched. If this indicates a null value (a variant of type VT_NULL, or a status value of DBSTATUS_ISNULL), it is compared to other values according to the DBPROP_NULLCOLLATION property returned in the Data Source Information property set. .

CompareOp

[in]
Operation to use in comparing the row values. The consumer should check DBPROP_FINDCOMPAREOPS to determine which comparison operators the provider supports.

Only DBCOMPAREOPS_EQ, DBCOMPAREOPS_NE, and DBCOMPAREOPS_IGNORE are valid for the following CompareOps:

  • DBTYPE_BOOL

  • DBTYPE_ERROR

  • DBTYPE_GUID

  • DBTYPE_IDISPATCH

  • DBTYPE_IUNKNOWN

  • DBTYPE_BTYES

The values in DBCOMPAREOPSENUM have the following meanings.

Value | Description
DBCOMPAREOPS_LT | Match the first value that is less than the search value.
DBCOMPAREOPS_LE | Match the first value that is less than or equal to the search value.
DBCOMPAREOPS_EQ | Match the first value that is equal to the search value.
DBCOMPAREOPS_GE | Match the first value that is greater than or equal to the search value.
DBCOMPAREOPS_GT | Match the first value that is greater than the search value.
DBCOMPAREOPS_BEGINSWITH | Match the first value that has the search value as its first characters. This is only valid for values bound as string data types.
DBCOMPAREOPS_NOTBEGINSWITH | Match the first value that does not have the search value as its first characters. This is only valid for values bound as string data types.
DBCOMPAREOPS_CONTAINS | Match the first value that contains the search value. This is only valid for values bound as string data types.
DBCOMPAREOPS_NOTCONTAINS | Match the first value that does not contain the search value. This is only valid for values bound as string data types.
DBCOMPAREOPS_NE | Match the first value that is not equal to the search value. NULLs evaluate as not equal to any other value, but equal to other NULLs.
DBCOMPAREOPS_IGNORE | Ignore the corresponding value. The provider ignores pFindValue and returns the next cRows rows starting from the row indicated by pBookmark, skipping the number of rows indicated by lRowsOffset.
DBCOMPAREOPS_CASESENSITIVE and DBCOMPAREOPS_CASEINSENSITIVE | Specify whether the search is case sensitive or case insensitive. You can join DBCOMPAREOPS_CASESENSITIVE or DBCOMPAREOPS_CASEINSENSITIVE with any of the other DBCOMPAREOPS values in a bitwise OR operation. If neither one is used, the search is handled according to the provider's implementation. Both DBCOMPAREOPS_CASESENSITIVE and DBCOMPAREOPS_CASEINSENSITIVE are ignored when searching for nonstring values.

cbBookmark

[in]
Length in bytes of the bookmark, or zero in order to start from the next fetch location (see the description of pBookmark).

pBookmark

[in]
Pointer to a bookmark that, in combination with IRowsetOffset, identifies the row from which to start searching for a match. The consumer is not required to have access rights to this row. However, if this row matches the seek criteria, the provider cannot return it unless the consumer has read permission for it.

The consumer can specify a cbBookmark value of zero, and set pBookmark to null, in order to request that the find occur starting with the next fetch location. The next fetch location is the same as the next fetch position used by GetNextRows.

If the rowset does not support IRowsetLocate, then only the special bookmarks DBBMK_FIRST and DBBMK_LAST, and the null value, may be used.

If the rowset does not support scrolling backward, then only the null bookmark value may be used.

If the rowset is chaptered, the identified row must fall within the specified chapter.

IRowsOffset

[in]
The signed count of rows from the origin bookmark to the row at which to start searching for a match. The first row checked is determined by the bookmark and this offset. For example, if IRowsOffset is 0, the first row checked is the bookmarked row; if IRowsOffset is 1, the first row checked is the row after the bookmarked row; if IRowsOffset is -1, the first row checked is the row before the bookmarked row. This can be a negative number only if the value of the DBPROP_CANSCROLLBACKWARDS property is VARIANT_TRUE.

cRows

[in]
The number of rows to fetch from the rowset, starting with the first row found. A negative number means to fetch backward. Check the DBPROP_CANFETCHBACKWARDS property returned in IRowsetInfo::GetProperties to determine whether this is supported.

The search direction is the same as the fetch direction, so a negative count searches backward from the starting position and returns successively earlier rows as subsequent obtained rows.

If cRows is 0 and there are no other errors, no rows are fetched but the fetch position for FindNextRow is moved to the next match. If no match is found, the fetch position is moved before the beginning of the rowset if the previous fetch direction was backward, or after the end of the rowset if the previous fetch direction was forward or if this is the first fetch.

pcRowsObtained

[out]
A pointer to memory in which to return the actual number of fetched rows.

prghRows

[out]
A pointer to memory in which to return an array of handles of the retrieved rows. If *prghRows is not a null pointer on input, it must be a pointer to memory large enough to return the handles of the requested number of rows. If *prghRows is a null pointer on input, the rowset allocates memory for the row handles and returns the address to this memory; the consumer releases this memory with IMalloc::Free after it releases the row handles. If *prghRows was a null pointer on input and *pcRowsObtained is 0 on output, the provider does not allocate any memory and ensures that *prghRows is a null pointer on output.

Return Code

S_OK
The method succeeded.

DB_S_ENDOFROWSET
FindNextRow reached the start or the end of the rowset or (in a hierarchical rowset) the start or the end of the chapter and could not fetch all requested rows because the count extended beyond the end. The next fetch position is before the start or after the end of the rowset. The number of rows actually returned is returned in *pcRowsObtained; this will be less than cRows.

DB_S_ROWLIMITEXCEEDED
Fetching the number of rows specified in cRows would have exceeded the total number of active rows supported by the rowset. The number of rows that were actually fetched is returned in *pcRowsObtained. This condition can occur only when there are more rows available than can be handled by the rowset. Thus, this condition never conflicts with those described in DB_S_ENDOFROWSET and DB_S_STOPLIMITREACHED, both of which imply that no more rows were available.

DB_S_STOPLIMITREACHED
Returning rows required further execution of the command, such as when the rowset uses a server-side cursor. Execution has been stopped because a resource limit has been reached. The number of rows that were actually fetched is returned in *pcRowsObtained. Execution cannot be resumed.

DB_S_BOOKMARKSKIPPED
The following behavior is only supported on rowsets that set the DBPROP_BOOKMARKSKIPPED property to VARIANT_TRUE. If this property is VARIANT_FALSE, this return code is never returned.

The row specified by *pBookmark was deleted, is no longer a member of the rowset, or is a row to which the consumer does not have access rights. FindNextRow skipped that row, and began searching with the next row in the direction indicated by cRows.

If this condition occurs along with another warning condition, the method returns the code for the other warning condition. Thus, whenever a consumer receives the return code for another warning condition, it should check to see whether this condition occurred.

E_FAIL
A provider-specific error occurred.

E_INVALIDARG
pcRowsObtained or prghRows was a null pointer.

cbBookmark was not 0 and pBookmark was a null pointer.

E_OUTOFMEMORY
The provider was unable to allocate sufficient memory in which to instantiate the rows or return the row handles.

E_UNEXPECTED
ITransaction::Commit or ITransaction::Abort was called and the object is in a zombie state.

DB_E_BADBINDINFO
The specified accessor specified binding information for more than one column.

DB_E_BADBOOKMARK
*pBookmark was invalid; for example, it was incorrectly formed.

*pBookmark did not match any rows in the rowset. This includes the case when the row corresponding to the bookmark has been deleted and DBPROP_BOOKMARKSKIPPED was VARIANT_FALSE.

*pBookmark was not a null value and the rowset does not support scrolling backward.

*pBookmark was not DBBMK_FIRST, DBBMK_LAST, or a null value, and the rowset does not support IRowsetLocate.

The rowset was chaptered and *pBookmark did not apply to the specified chapter.

Note Consumers should only attempt to use bookmarks that they have received from the provider. The provider is guaranteed only to handle bookmarks it gives out in a predictable manner. Attempting to use a random value as a bookmark is undefined; the provider may return DB_E_BADBOOKMARK, may return an unexpected row, or may terminate abnormally.

DB_E_BADCHAPTER
The rowset was chaptered and hChapter was invalid.

The rowset was single-chaptered and the specified chapter was not the currently open chapter. The consumer must use the currently open chapter or release the currently open chapter before specifying a new chapter.

DB_E_BADCOMPAREOP
CompareOp was an invalid value.

CompareOp was DBCOMPAREOPS_BEGINSWITH or DBCOMPAREOPS_CONTAINS and pFindValue was not bound as a string value.

Both DBCOMPAREOPS_CASESENSITIVE and DBCOMPAREOPS_CASEINSENSITIVE were used in the same operation.

DB_E_BADSTARTPOSITIONIRowsOffset would position the first row retrieved past either end of the rowset, regardless of the cRows value specified. cRowsObtained is 0.

DB_E_CANTFETCHBACKWARDS
cRows was negative and the rowset cannot fetch backward.

DB_E_CANTSCROLLBACKWARDS
A bookmark value of DBBMK_FIRST or DBBMK_LAST was specified and the rowset cannot scroll backward.

IRowsOffset was negative and the rowset cannot scroll backward.

DB_E_NOTREENTRANT
The consumer called this method while it was processing a notification, and it is an error to call this method while processing the specified DBREASON value.

DB_E_ROWSNOTRELEASED
The provider requires release of prior HROWs before new ones can be obtained (see IDBProperties::GetPropertyInfo, DBPROP_CANHOLDROWS).

DB_SEC_E_PERMISSIONDENIED
The consumer did not have sufficient permission to get the rows.

Comments

See IRowsetLocate::GetRowsAt for a complete description of the results for given values for a bookmark, offset, and number of rows to fetch.

FindNextRow searches the rowset in the direction indicated by cRows for a row that matches pFindValue according to the specified CompareOp. Once a match is found, if cRows is greater than 1, additional rows are returned in rowset order as if the consumer called GetNextRows starting with the first matching row. If no rows match the criteria, FindNextRow returns DB_S_ENDOFROWSET and pcRowsObtained is set to zero.

For a newly created rowset, if pBookmark is null, the search begins starting with the row computed according to the next fetch position as described in GetNextRows for newly created rowsets.

It is not required that the rowset be ordered on the column searched. FindNextRow always finds the next row according to the criteria, regardless of the sort order.

FindNextRow increments the reference count of each row for which it returns a handle by 1. Thus, if a handle is returned for a row that has already been fetched, the reference count of that row will be greater than 1. ReleaseRows must be called once for each time the handle to a row has been returned.

If the provider encounters a problem fetching a row—for example, data stored in a text file contains a letter in a numeric column—FindNextRow fetches the row normally, returns the row handle, and returns S_OK. However, when the consumer calls GetData for the row, the provider returns DBSTATUS_E_CANTCONVERTVALUE as the status for the offending column.

If an error occurs when calling FindNextRow, the fetch position is left unchanged.

If FindNextRow performs deferred accessor validation and that validation takes place before any data is transferred, it can also return any of the following return codes for the applicable reasons listed in the corresponding DBBINDSTATUS values in IAccessor::CreateAccessor: E_NOINTERFACE, DB_E_BADBINDINFO, DB_E_BADORDINAL, DB_E_BADSTORAGEFLAGS, and DB_E_UNSUPPORTEDCONVERSION.

For information about what FindNextRow does when it fetches a row that it already has in its internal buffers, see "Uniqueness of Rows in the Rowset" in Chapter 4. For information about whether FindNextRow can detect changes made to rows in the rowset, see "Visibility of Changes" in Chapter 5. For information about how FindNextRow interprets data from *pFindValue, see "Setting Data" in Chapter 6.

See Also

IRowset::GetData, IRowsetLocate::GetRowsAt, IRowsetLocate::GetRowsByBookmark


IRowsetIdentity

IRowsetIdentity is the interface that indicates row instance identity is implemented on the rowset and enables testing for row identity. If a rowset supports this interface, any two row handles representing the same underlying row will always reflect the same data and state.

IRowsetIdentity depends on IRowset.

Consumers call IsSameRow whenever they need to determine if two row handles represent the same underlying row. For example, if a row handle is returned to the consumer during notification, the consumer can compare it to its own list of row handles to see if it is the handle of a row of interest.

Method | Description
IsSameRow | Compares two row handles to see if they refer to the same row instance.


IRowsetIdentity::IsSameRow

Compares two row handles to see if they refer to the same row instance.

HRESULT IsSameRow (
   HROW   hThisRow,
   HROW   hThatRow);

Parameters

hThisRow

[in]
The handle of an active row.

hThatRow

[in]
The handle of an active row.

Return Code

S_FALSE
The method succeeded and the row handles do not refer to the same row instance.

S_OK
The method succeeded and the row handles do refer to the same row instance.

E_FAIL
A provider-specific error occurred.

E_UNEXPECTED
ITransaction::Commit or ITransaction::Abort was called and the object is in a zombie state.

DB_E_BADROWHANDLE
hRowThis or hRowThat was invalid.

DB_E_DELETEDROW
hRowThis or hRowThat referred to a row for which a deletion had been transmitted to the data source.

DB_E_NEWLYINSERTED
The provider is unable to determine identity for a row for which an insertion had been transmitted to the data source. This condition can occur when DBPROP_STRONGIDENTITY is set to VARIANT_FALSE.

Comments

This method makes no logical change to the state of the object.

The row handles refer to the same row instance if the value set in any column in the row by means of one row handle will be the value returned for that column when gotten through the other row handle.

Rowsets that support this interface must also implement the detection of row identity within their rowset. That is, if they fetch rows at different times, they can detect when the row handles are referring to the same logical row and arrange for both row handles to reflect the same data and state.

The value of the row handles—their bit patterns as handles—is not necessarily the same if the underlying row is the same. This depends on the value of the DBPROP_LITERALIDENTITY property.

The outcome of IsSameRow is not changed when one or both of its parameters correspond to a row with a pending delete.


IRowsetInfo

IRowsetInfo provides information about a rowset.

When a consumer gets an interface pointer on a rowset, its first step usually is to determine the rowset's capabilities using IUnknown::QueryInterface. It may call GetProperties to learn the properties of the rowset that do not show up as distinct interfaces, such as the maximum number of active rows and how many rows can have pending updates at the same time.

IRowsetInfo also provides methods for retrieving objects associated with the rowset. GetSpecification gets the object (command or session) that created the rowset. GetReferencedRowset gets the rowset that is referenced by a bookmark-valued column.

Method | Description
GetProperties | Returns the current setting of all properties supported by the rowset.
GetReferencedRowset | Returns an interface pointer to the rowset to which a bookmark applies.
GetSpecification | Returns an interface pointer on the object (command or session) that created the rowset.


IRowsetInfo::GetProperties

Returns the current settings of all properties supported by the rowset.

HRESULT GetProperties (
   const ULONG            cPropertyIDSets,
   const DBPROPIDSET   rgPropertyIDSets[],
   ULONG *                  pcPropertySets,
   DBPROPSET **         prgPropertySets);

Parameters

cPropertyIDSets

[in]
The number of DBPROPIDSET structures in rgPropertyIDSets.

If cPropertySets is zero, the provider ignores rgPropertyIDSets and returns the values of all properties in the Rowset property group for which values exist, including properties for which values were not set but for which defaults exist, and also including properties for which values were set automatically because values were set for other properties.

If cPropertyIDSets is not zero, the provider returns the values of the requested properties. If a property is not supported, the returned value of dwStatus in the returned DBPROP structure for that property is DBPROPSTATUS_NOTSUPPORTED and the value of dwOptions is undefined.

rgPropertyIDSets

[in]
An array of cPropertyIDSets DBPROPIDSET structures. The properties specified in these structures must belong to the Rowset property group. The provider returns the values of the properties specified in these structures. If cPropertyIDSets is zero, then this parameter is ignored.

pcPropertySets

[out]
A pointer to memory in which to return the number of DBPROPSET structures returned in *prgPropertySets. If cPropertyIDSets is zero, *pcPropertySets is the total number of property sets for which the provider supports at least one property in the Rowset property group. If cPropertyIDSets is greater than zero, *pcPropertySets is set to cPropertyIDSets. If an error other than DB_E_ERRORSOCCURRED occurs, *pcPropertySets is set to zero.

prgPropertySets

[out]
A pointer to memory in which to return an array of DBPROPSET structures. If cPropertyIDSets is zero, then one structure is returned for each property set that contains at least one property belonging to the Rowset property group. If cPropertyIDSets is not zero, then one structure is returned for each property set specified in rgPropertyIDSets.

If cPropertyIDSets is not zero, the DBPROPSET structures in *prgPropertySets are returned in the same order as the DBPROPIDSET structures in rgPropertyIDSets; that is, for corresponding elements of each array, the guidPropertySet elements are the same. If cPropertyIDs, in an element of rgPropertyIDSets, is not zero, the DBPROP structures in the corresponding element of *prgPropertySets are returned in the same order as the DBPROPID values in rgPropertyIDs. Thus, in the case where no column properties are specified in rgPropertyIDSets, corresponding elements of the input rgPropertyIDs and the returned rgProperties have the same property ID. However, if a column property is requested in rgPropertyIDSets, multiple properties may be returned, one for each column, in rgProperties. In this case, corresponding elements of rgPropertyIDs and rgProperties will not have the same property ID, and rgProperties will contain more elements than rgPropertyIDs.

The provider allocates memory for the structures and returns the address to this memory; the consumer releases this memory with IMalloc::Free when it no longer needs the structures. Before calling IMalloc::Free for *prgPropertySets, the consumer should call IMalloc::Free for the rgProperties element within each element of *prgPropertySets. If *pcPropertySets is zero on output or an if error other than DB_E_ERRORSOCCURRED occurs, the provider does not allocate any memory and ensures that *prgPropertySets is a null pointer on output.

Return Code

S_OK
The method succeeded. In all DBPROP structures returned by the method, dwStatus is set to DBPROPSTATUS_OK.

DB_S_ERRORSOCCURRED
No value was returned for one or more properties. The consumer checks dwStatus in the DBPROP structure to determine the properties for which values were not returned. GetProperties can fail to return properties for a number of reasons, including:

  • The property was not supported by the provider.

  • The property was not in the Rowset property group.

  • The property set was not supported by the provider. If cPropertyIDs in the DBPROPIDSET structure for the property set was zero, the provider cannot set dwStatus in the DBPROP structure because it does not know the IDs of any properties in the property set. Instead, it sets cProperties to zero in the DBPROPSET structure returned for the property set.

E_FAIL
A provider-specific error occurred.

E_INVALIDARG
cPropertyIDSets was not equal to zero and rgPropertyIDSets was a null pointer.

pcPropertySets or prgPropertySets was a null pointer.

In an element of rgPropertyIDSets, cPropertyIDs was not zero and rgPropertyIDs was a null pointer.

E_OUTOFMEMORY
The provider was unable to allocate sufficient memory in which to return the DBPROPSET or DBPROP structures.

E_UNEXPECTED
ITransaction::Commit or ITransaction::Abort was called and the object is in a zombie state.

DB_E_ERRORSOCCURRED
Values were not returned for any properties. The provider allocates memory for *prgPropertySets and the consumer checks dwStatus in the DBPROP structures to determine why properties were not returned. The consumer frees this memory when it no longer needs the information.

Comments

This method makes no logical change to the state of the object.

Even though IDBProperties::GetPropertyInfo lists a property as being supported by the provider, GetProperties will not return a value for it if it does not apply to the current circumstances. For example, the provider's ability to support the property might be affected by the current transaction or the current command text.

IRowsetInfo::GetProperties might return a different value for a property than does ICommandProperties::GetProperties. For example, if a consumer requests ordered bookmarks if they are possible, it calls ICommandProperties::SetProperties to set the value of DBPROP_ORDEREDBOOKMARKS to VARIANT_TRUE and specifies a dwOptions value of DBPROPOPTIONS_OPTIONAL. If the provider cannot determine whether this is possible, ICommandProperties::GetProperties returns a value of VARIANT_TRUE and a dwOptions of DBPROPOPTIONS_OPTIONAL for this property. If the provider determines during execution that ordered bookmarks are not possible, IRowsetInfo::GetProperties returns a value of VARIANT_FALSE and a dwOptions of zero.

See Also

ICommandProperties::SetProperties, IDBProperties::GetPropertyInfo


IRowsetInfo::GetReferencedRowset

Returns an interface pointer to the rowset to which a bookmark or chapter applies.

HRESULT GetReferencedRowset (
   ULONG      iOrdinal,
   REFIID         riid,
   IUnknown **   ppReferencedRowset);

Parameters

iOrdinal

[in]
The bookmark or chapter column for which to get the related rowset.

riid

[in]
The IID of the interface pointer to return in *ppReferencedRowset. This interface is conceptually added to the list of required interfaces on the resulting rowset, and the method fails (E_NOINTERFACE) if that interface cannot be supported on the resulting rowset.

ppReferencedRowset

[out]
A pointer to memory in which to return an IUnknown interface pointer on the rowset that interprets values from this column. If this is not a reference column, *ppReferencedRowset is set to a null pointer.

Return Code

S_OK
The method succeeded.

E_FAIL
A provider-specific error occurred.

E_INVALIDARG
ppReferencedRowset was a null pointer.

E_NOINTERFACE
The interface specified in riid was not implicitly or explicitly specified as a rowset property of the rowset. The current rowset remains valid.

E_UNEXPECTED
ITransaction::Commit or ITransaction::Abort was called and the object is in a zombie state.

DB_E_BADORDINAL
The column specified by iOrdinal did not exist.

DB_E_NOTAREFERENCECOLUMN
The column specified by iOrdinal did not contain bookmarks or chapter values.

DB_E_NOTREENTRANT
The provider called a method from IRowsetNotify in the consumer that had not yet returned, and the provider does not support reentrancy in this method.

DB_E_NOTSUPPORTED
The interface was exposed on an index rowset.

Comments

This method makes no logical change to the state of the current rowset.

All of the bookmarks or chapter values in a column reference a single rowset. The references can apply to the current rowset (an example would be genealogy relations on a People table), or they can apply to a different rowset (an example of which would be Customer Orders).

See Also

IColumnsInfo


IRowsetInfo::GetSpecification

Returns an interface pointer on the object (command or session) that created this rowset.

HRESULT GetSpecification (
   REFIID       riid,
   IUnknown **   ppSpecification);

Parameters

riid

[in]
The IID of the interface on which to return a pointer.

ppSpecification

[out]
A pointer to memory in which to return the interface pointer. If the provider does not have an object that created the rowset, it sets *ppSpecification to a null pointer and returns S_FALSE. If GetSpecification fails, it must attempt to set *ppSpecification to a null pointer.

Return Code

S_OK
The method succeeded.

S_FALSE
The provider does not have an object that created the rowset.

E_FAIL
A provider-specific error occurred.

E_INVALIDARG
ppSpecification was a null pointer.

E_NOINTERFACE
The object that created this rowset did not support the interface specified in riid.

E_UNEXPECTED
ITransaction::Commit or ITransaction::Abort was called and the object is in a zombie state.

DB_E_NOTREENTRANT
The provider called a method from IRowsetNotify in the consumer that had not yet returned, and the provider does not support reentrancy in this method.

Comments

This method makes no logical change to the state of the current rowset.

GetSpecification returns an interface pointer on the object that created the rowset. If the rowset was created by ICommand::Execute, this object is a command. If the rowset was created by IOpenRowset::OpenRowset, this object is a session.

If the object is not a command, then it must specify the contents of the rowset. That is, it must expose interfaces that can be used to modify the contents of the rowset before the rowset is created, or be used to gain additional information about the rowset. If the object cannot expose such interfaces, GetSpecification should return a null pointer in *ppSpecification. In a simple provider, such as a provider that creates a rowset over a fixed set of data, there might not be an object that created the rowset; in this case, GetSpecification returns a null pointer in *ppSpecification.

See Also

ICommand::GetDBSession, IGetDataSource::GetDataSource


IRowsetLocate : IRowset

IRowsetLocate is the interface for fetching arbitrary rows of a rowset. A rowset that does not implement this interface is a sequential rowset. IRowsetLocate is a prerequisite for IRowsetScroll.

When IRowsetLocate or one of its direct descendants is present on a rowset, then column 0 is the bookmark for the rows. Reading this column will obtain a bookmark value that can be used to reposition to the same row.

Method | Description
Compare | Compares two bookmarks.
GetRowsAt | Fetches rows, starting with the row specified by an offset from a bookmark.
GetRowsByBookmark | Fetches the rows that match the specified bookmarks.
Hash | Returns hash values for the specified bookmarks.


IRowsetLocate::Compare

Compares two bookmarks.

HRESULT Compare (
   HCHAPTER         hChapter,
   ULONG            cbBookmark1,
   const BYTE *         pBookmark1,
   ULONG            cbBookmark2,
   const BYTE *         pBookmark2,
   DBCOMPARE *   pComparison);

Parameters

hChapter

[in]
The chapter handle. For nonchaptered rowsets, hChapter is ignored.

cbBookmark1

[in]
The length in bytes of the first bookmark.

pBookmark1

[in]
A pointer to the first bookmark. This can be a pointer to DBBMK_FIRST or DBBMK_LAST.

cbBookmark2

[in]
The length in bytes of the second bookmark.

pBookmark2

[in]
A pointer to the second bookmark. This can be a pointer to DBBMK_FIRST or DBBMK_LAST.

pComparison

[out]
A pointer to memory in which to return a flag that specifies the result of the comparison. The returned flag will be one of the following values.

Value | Description
DBCOMPARE_LT | The first bookmark is before the second.
DBCOMPARE_EQ | The two bookmarks are equal.
DBCOMPARE_GT | The first bookmark is after the second.
DBCOMPARE_NE | The bookmarks are not equal and not ordered.
DBCOMPARE_NOTCOMPARABLE | The two bookmarks cannot be compared.

Return Code

S_OK
The method succeeded.

E_FAIL
A provider-specific error occurred.

E_INVALIDARG
cbBookmark1 or cbBookmark2 was zero.

pBookmark1, pBookmark2, or pComparison was a null pointer.

E_UNEXPECTED
ITransaction::Commit or ITransaction::Abort was called and the object is in a zombie state.

DB_E_BADBOOKMARK
*pBookmark1 or *pBookmark2 was invalid, incorrectly formed, or DBBMK_INVALID.

Note Consumers should only attempt to use bookmarks that they have received from the provider. The provider is guaranteed only to handle bookmarks it gives out in a predictable manner. Attempting to use a random value as a bookmark is undefined; the provider may return DB_E_BADBOOKMARK, may return an unexpected row, or may terminate abnormally.

DB_E_BADCHAPTER
The rowset was chaptered and hChapter was invalid.

The rowset was single-chaptered and the specified chapter was not the currently open chapter. The consumer must use the currently open chapter or release the currently open chapter before specifying a new chapter.

DB_E_NOTREENTRANT
The provider called a method from IRowsetNotify in the consumer that had not yet returned, and the provider does not support reentrancy in this method.

Comments

This method makes no logical change to the state of the object.

If bookmarks are ordered, they can be compared to determine the relative position of their associated rows in the rowset. The DBPROP_ORDEREDBOOKMARKS property indicates whether bookmarks are ordered. If bookmarks are not ordered, then the returned comparison value will be DBCOMPARE_EQ or DBCOMPARE_NE. If bookmarks are ordered, then the returned comparison value will be DBCOMPARE_LT, DBCOMPARE_EQ, or DBCOMPARE_GT. The command that creates the rowset does not have to have an ordered text command, such as an SQL statement containing an ORDER BY clause, to have ordered bookmarks.

Compare can compare any valid bookmarks. The consumer is not required to have permission to read the corresponding rows, nor are the rows even required to exist — for example, they might have been deleted.

If the DBPROP_LITERALBOOKMARKS property is VARIANT_TRUE, then consumers can directly compare values.

Specifying the bookmark DBBMK_FIRST or DBBMK_LAST returns DBCOMPARE_EQ when compared with itself and DBCOMPARE_NE when compared with any other bookmark.

See Also

IRowsetLocate::Hash, IRowsetIdentity::IsSameRow


IRowsetLocate::GetRowsAt

Fetches rows starting with the row specified by an offset from a bookmark.

HRESULT GetRowsAt (
   HWATCHREGION   hReserved1,
   HCHAPTER            hChapter
   ULONG               cbBookmark,
   const BYTE *            pBookmark,
   LONG                  lRowsOffset,
   LONG                  cRows,
   ULONG *               pcRowsObtained,
   HROW **               prghRows);

Parameters

hReserved1

[in]
Reserved for future use. Providers ignore this parameter.

hChapter

[in]
The chapter handle. For nonchaptered rowsets, hChapter is ignored.

cbBookmark

[in]
The length in bytes of the bookmark. This must not be zero.

pBookmark

[in]
A pointer to a bookmark that identifies the base row to be used. This can be a pointer to DBBMK_FIRST or DBBMK_LAST. If lRowsOffset is zero, then the provider fetches this row first; otherwise the provider skips this and subsequent rows up to the count specified in the offset, then fetches the following rows.

lRowsOffset

[in]
The signed count of rows from the origin bookmark to the target row. Deleted rows that the provider has removed from the rowset are not counted in the skip. The first row fetched is determined by the bookmark and this offset. For example, if lRowsOffset is zero, the first row fetched is the bookmarked row; if lRowsOffset is 1, the first row fetched is the row after the bookmarked row; if lRowsOffset is –1, the first row fetched is the row before the bookmarked row.

lRowsOffset can be a negative number only if the value of the DBPROP_CANSCROLLBACKWARDS property is VARIANT_TRUE.

cRows

[in]
The number of rows to fetch. A negative number means to fetch backward. cRows can be a negative number only if the value of the DBPROP_CANFETCHBACKWARDS property is VARIANT_TRUE.

If cRows is zero, no rows are fetched; the fetch direction and the next fetch position are unchanged, and the provider performs no processing, returning immediately from the method invocation. Specifically, lRowsOffset is ignored in this situation.

If the provider does not discover any other errors, the method returns S_OK; whether the provider checks for any other errors is provider-specific.

See the Comments section for a full description of the semantics of lRowsOffset and cRows parameters.

pcRowsObtained

[out]
A pointer to memory in which to return the actual number of fetched rows. If the consumer has insufficient permission to fetch all rows, GetRowsAt fetches all rows for which the consumer has sufficient permission and skips all other rows. If the method fails, *pcRowsObtained is set to zero.

prghRows

[in/out]
A pointer to memory in which to return an array of handles of the fetched rows. If *prghRows is not a null pointer on input, it must be a pointer to memory large enough to return the handles of the requested number of rows. If *prghRows is a null pointer on input, the rowset allocates memory for the row handles and returns the address to this memory. The consumer releases this memory with IMalloc::Free after it releases the row handles. If *prghRows was a null pointer on input and *pcRowsObtained is zero on output or if the method fails, the provider does not allocate any memory and ensures that *prghRows is a null pointer on output.

Return Code

S_OK
The method succeeded.

DB_S_BOOKMARKSKIPPED
The following behavior is only supported on rowsets that set the DBPROP_BOOKMARKSKIPPED property to VARIANT_TRUE. If this property is VARIANT_FALSE, this return code is never returned.

lRowsOffset was zero and the row specified by *pBookmark was deleted or is no longer a member of the rowset, or the row specified by the combination of *pBookmark and lRowsOffset is a row to which the consumer does not have access rights. GetRowsAt skipped that row. The full count of actual rows (cRows) will be met if there are enough rows available. The array of returned row handles does not have gaps for missing rows; the returned count is the number of rows actually fetched.

If a row is skipped, it is counted as one of the rows to be skipped for lRowsOffset. For example, if an offset of 1 is requested and the bookmark points to a row which is now missing, the offset is decremented by 1 and the provider begins by fetching the next row.

If this condition occurs along with another warning condition, the method returns the code for the other warning condition. Thus, whenever a consumer receives the return code for another warning condition, it should check to see whether this condition occurred.

DB_S_ENDOFROWSET
GetRowsAt reached the start or the end of the rowset or chapter and could not fetch all of the requested rows because the count extended beyond the end. The number of rows actually fetched is returned in *pcRowsObtained; this will be less than cRows.

The rowset is being populated asynchronously and no additional rows are available at this time. To determine whether additional rows may be available, the consumer should call IDBAsynchStatus::GetStatus or listen for the IDBAsynchNotify::OnStop notification.

lRowsOffset indicated a position either more than one row before the first row of the rowset or more than one row after the last row, and the provider was a version 2.0 or greater provider. *pcRowsObtained is set to zero and no rows are returned.

DB_S_ROWLIMITEXCEEDED
Fetching the number of rows specified in cRows would have exceeded the total number of active rows supported by the rowset. The number of rows that were actually fetched is returned in *pcRowsObtained. This condition can occur only when there are more rows available than can be handled by the rowset. Thus, this condition never conflicts with those described in DB_S_ENDOFROWSET and DB_S_STOPLIMITREACHED, both of which imply that no more rows were available.

DB_S_STOPLIMITREACHED
Fetching rows required further execution of the command, such as when the rowset uses a server-side cursor. Execution has been stopped because a resource limit has been reached. The number of rows that were actually fetched is returned in *pcRowsObtained.

E_FAIL
A provider-specific error occurred.

E_INVALIDARG
cbBookmark was zero or pBookmark was a null pointer.

pcRowsObtained or prghRows was a null pointer.

E_OUTOFMEMORY
The provider was unable to allocate sufficient memory in which to instantiate the rows or return the row handles.

E_UNEXPECTED
ITransaction::Commit or ITransaction::Abort was called and the object is in a zombie state.

DB_E_BADBOOKMARK
*pBookmark was invalid, incorrectly formed, or DBBMK_INVALID.

*pBookmark did not match any rows in the rowset. This includes the case when the row corresponding to the bookmark has been deleted and DBPROP_BOOKMARKSKIPPED was VARIANT_FALSE.

Note Consumers should only attempt to use bookmarks that they have received from the provider. The provider is guaranteed only to handle bookmarks it gives out in a predictable manner. Attempting to use a random value as a bookmark is undefined; the provider may return DB_E_BADBOOKMARK, may return an unexpected row, or may terminate abnormally.

DB_E_BADCHAPTER
The rowset was chaptered and hChapter was invalid.

The rowset was single-chaptered and the specified chapter was not the currently open chapter. The consumer must use the currently open chapter or release the currently open chapter before specifying a new chapter.

DB_E_BADSTARTPOSITION
lRowsOffset indicated a position either more than one row before the first row of the rowset or more than one row after the last row, and the provider was a 1.x provider,

DB_E_CANTFETCHBACKWARDS
cRows was negative and the rowset cannot fetch backward.

DB_E_CANTSCROLLBACKWARDS
lRowsOffset was negative and the rowset cannot scroll backward.

DB_E_NOTREENTRANT
The consumer called this method while it was processing a notification, and it is an error to call this method while processing the specified DBREASON value.

DB_E_ROWSNOTRELEASED
The provider requires release of existing rows before new ones can be fetched.

DB_SEC_E_PERMISSIONDENIED
The consumer did not have sufficient permission to fetch any of the rows; no rows were fetched.

Comments

Given values for a bookmark, offset, and number of rows to fetch:

  • The provider determines a starting position for the fetch as the bookmark plus the offset.

  • If the starting position is off either end of the rowset, the method returns DB_E_BADSTARTPOSITION.

  • If the starting position is in the rowset, the provider fetches rows in the specified direction until it has fetched the requested number of rows or hits the end of the rowset.

  • If it fetches the requested number of rows, it returns S_OK. If it hits the end of the rowset, it stops fetching, returns DB_S_ENDOFROWSET, and returns the rows it has fetched.

  • The rows are returned in rowset traversal order; that is, the direction in which they were fetched. For example, if the consumer passes the bookmark for row 10 to GetRowsAt and specifies cRows equal to – 5 and lRowsOffset equal to 0, GetRowsAt returns rows 10 through 6. That is, *prghRows[0] is the handle for row 10 and *prghRows[4] is the handle for row 6.

The following table defines the behavior of GetRowsAt for all combinations of these parameters.

Variable | Description
N | Total rows in the rowset.
B | Row in the rowset specified by the bookmark parameters cbBookmark and pBookmark. Assume 1 &le; B &le; N, DBBMK_FIRST is equivalent to B = 1, and DBBMK_LAST is equivalent to B = N.
F | lRowsOffset
r | cRows

B + F | r | cRowsObtained | Return code
B + F < 1 or B + F > N | N/A | 0 | DB_E_BADSTARTPOSITION
1 &le; B + F &le; N | 0 | 0 | S_OK
1 &le; B + F &le; N | 1 &le; r &le; N – B – F + 1 | r | S_OK
1 &le; B + F &le; N | r > N – B – F + 1 | N – B – F+1 | DB_S_ENDOFROWSET
1 &le; B + F &le; N | r < 0 and abs(r) &le; B + F | abs(r) | S_OK
1 &le; B + F &le; N | r < 0 and abs(r) > B + F | B + F | DB_S_ENDOFROWSET

Consumers that want to fetch forward, for example, 20 rows at a time, can use the call GetRowsAt( ..., B, 1, 20, ...) which allows for an easy check when reaching the end of the rowset. Similarly, consumers that want to fetch backward can use the call GetRowsAt(..., B, – 1, – 20, ...) to facilitate the detection of the beginning of the rowset. In the latter case, DBPROP_CANFETCHBACKWARDS must be set to VARIANT_TRUE.

The DBPROP_BOOKMARKSKIPPED property defines the behavior for cases in which there is no exact match for the bookmark pointed to by pBookmark. If this property is set to VARIANT_FALSE, then DB_E_BADBOOKMARK will be returned because the corresponding position is not well-defined. The behavior when this property is set to VARIANT_TRUE is as follows:

  • If lRowsOffset is zero, then the row is skipped, the requested number of rows are fetched from subsequent rows, and a DB_S_BOOKMARKSKIPPED warning is returned.

  • If lRowsOffset and cRows are any value except zero, the fetch succeeds, based on the position of the row before it became invalid. For example, suppose row 20 is deleted. If a consumer calls GetRowsAt with lRowsOffset set to 5 and a bookmark that points to row 20, then GetRowsAt moves to row 25.

If the provider encounters a problem fetching a row — for example, data stored in a text file contains a letter in a numeric column — GetRowsAt fetches the row normally, returns the row handle, and returns S_OK. However, when the consumer calls IRowset::GetData for the row, the provider returns DBSTATUS_E_CANTCONVERTVALUE as the status for the offending column.

GetRowsAt increments the reference count of each row for which it returns a handle by 1. Thus, if a handle is returned for a row that has already been fetched, the reference count of that row will be greater than 1. ReleaseRows must be called once for each time the handle to a row has been returned.

In order to use GetRowsAt several times in sequence to obtain successive rows, the consumer should obtain the bookmark of the last row of the previous set and use that, with a skip of 1, to position for fetching the next rows.

See Also

IRowset::GetData, IRowset::GetNextRows, IRowsetLocate::GetRowsByBookmark, IRowsetScroll::GetRowsAtRatio


IRowsetLocate::GetRowsByBookmark

Fetches the rows that match the specified bookmarks.

HRESULT GetRowsByBookmark (
   HCHAPTER         hChapter,
   ULONG            cRows,
   const ULONG      rgcbBookmarks[],
   const BYTE *         rgpBookmarks[],
   HROW                rghRows[],
   DBROWSTATUS   rgRowStatus[]);

Parameters

hChapter

[in]
The chapter handle. For nonchaptered rowsets, hChapter is ignored.

cRows

[in]
The number of rows to fetch.

If cRows is zero, no rows are fetched; the fetch direction and the next fetch position are unchanged, and the provider performs no processing, returning immediately from the method invocation.

If the provider does not discover any other errors, the method returns S_OK; whether the provider checks for any other errors is provider-specific.

rgcbBookmarks

[in]
An array containing the length in bytes of each bookmark.

rgpBookmarks

[in]
An array containing a pointer to the bookmark of each row sought. These cannot be pointers to a standard bookmark (DBBMK_FIRST, DBBMK_LAST, DBBMK_INVALID). If rgpBookmarks contains a duplicate bookmark, the corresponding row is fetched and the reference count incremented once for each occurrence of the bookmark.

rghRows

[out]
An array with cRows elements in which to return the handles of the fetched rows. The consumer allocates this array but is not required to initialize the elements of it. In each element of this array, if the row was fetched, the provider returns the handle of the row identified by the bookmark in the corresponding element of rgpBookmarks. If the row was not fetched, the provider returns DB_NULL_HROW.

rgRowStatus

[out]
An array with cRows elements in which to return values indicating the status of each row specified in rgpBookmarks. If no errors or warnings occur while fetching a row, the corresponding element of rgRowStatus is set to DBROWSTATUS_S_OK. If an error occurs while fetching a row, the corresponding element is set as specified in DB_S_ERRORSOCCURRED. The consumer allocates memory for this array but is not required to initialize it. If rgRowStatus is a null pointer, no row statuses are returned.

Return Code

S_OK
The method succeeded. All rows were successfully fetched. The following value can be returned in rgRowStatus:

  • The row was successfully fetched. The corresponding element of rgRowStatus contains DBROWSTATUS_S_OK.

DB_S_ERRORSOCCURRED
An error occurred while fetching a row, but at least one row was successfully fetched. Successes can occur for the reasons listed under S_OK. The following errors can occur:

  • An element of rgpBookmarks pointed to an invalid or incorrectly formed bookmark. The corresponding element of rgRowStatus contains DBROWSTATUS_E_INVALID.

  • An element of rgpBookmarks pointed to a bookmark that did not match any rows in the rowset. This includes the case when the row corresponding to the bookmark has been deleted. The corresponding element of rgRowStatus contains DBROWSTATUS_E_INVALID.

  • An element of rgcbBookmarks was zero. The corresponding element of rgRowStatus contains DBROWSTATUS_E_INVALID.

  • An element of rgpBookmarks was a null pointer. The corresponding element of rgRowStatus contains DBROWSTATUS_E_INVALID.

  • An element of rgpBookmarks pointed to a standard bookmark (DBBMK_FIRST, DBBMK_LAST, DBBMK_INVALID). The corresponding element of rgRowStatus contains DBROWSTATUS_E_INVALID.

  • The row corresponding to the bookmark was not fetched because fetching it would have exceeded the total number of active rows supported by the rowset. The corresponding element of rgRowStatus contains DBROWSTATUS_E_LIMITREACHED.

  • The row corresponding to the bookmark was not fetched for the following reason. Fetching rows required further execution of the command, such as when the rowset uses a server-side cursor. Execution has been stopped because a resource limit has been reached. Execution cannot be resumed. The corresponding element of rgRowStatus contains DBROWSTATUS_E_LIMITREACHED.

  • The rowset ran out of memory and was unable to fetch the row. The corresponding element of rgRowStatus contains DBROWSTATUS_E_OUTOFMEMORY.

  • The consumer did not have sufficient permission to fetch a row. The corresponding element of rgRowStatus contains DBROWSTATUS_E_PERMISSIONDENIED.

  • The consumer encountered a recoverable, provider-specific error, such as an RPC failure when transmitting the change to a remote server. The corresponding element of rgRowStatus contains DBROWSTATUS_E_FAIL.

E_FAIL
A provider-specific error occurred.

E_INVALIDARG
rghRows was a null pointer.

rgcbBookmarks or rgpBookmarks was a null pointer.

E_OUTOFMEMORY
The provider was unable to allocate sufficient memory in which to return the row handles.

E_UNEXPECTED
ITransaction::Commit or ITransaction::Abort was called and the object is in a zombie state.

DB_E_BADCHAPTER
The rowset was chaptered and hChapter was invalid.

The rowset was single-chaptered and the specified chapter was not the currently open chapter. The consumer must use the currently open chapter or release the currently open chapter before specifying a new chapter.

DB_E_ERRORSOCCURRED
Errors occurred while fetching all of the rows. Errors can occur for the reasons listed under DB_S_ERRORSOCCURRED.

DB_E_NOTREENTRANT
The consumer called this method while it was processing a notification, and it is an error to call this method while processing the specified DBREASON value.

DB_E_ROWSNOTRELEASED
The provider requires release of existing rows before new ones can be fetched.

Comments

GetRowsByBookmark increments the reference count of each row for which it returns a handle by 1. Thus, if a handle is returned for a row that has already been fetched, the reference count of that row will be greater than 1. ReleaseRows must be called once for each time the handle to a row has been returned.

If the provider encounters a problem fetching a row — for example, data stored in a text file contains a letter in a numeric column — GetRowsByBookmark fetches the row normally, returns the row handle, and returns S_OK. However, when the consumer calls IRowset::GetData for the row, the provider returns DBSTATUS_E_CANTCONVERTVALUE as the status for the offending column.

If GetRowsByBookmark encounters an error while attempting to fetch a row, such as a bad bookmark or adeleted row, it notes the error in the rgRowStatus array, continues processing, and returns DB_S_ERRORSOCCURRED or DB_E_ERRORSOCCURRED. Although the rows are fetched in undefined order, the ordering of the error array must match the order of the bookmark array, so the consumer can perform a side-by-side scan of each array to determine which rows were not fetched.

See Also

IRowset::GetData, IRowset::GetNextRows, IRowsetLocate::GetRowsAt, IRowsetScroll::GetRowsAtRatio


IRowsetLocate::Hash

Returns hash values for the specified bookmarks.

HRESULT Hash (
   HCHAPTER         hChapter,
   ULONG            cBookmarks,
   const ULONG      rgcbBookmarks[],
   const BYTE *         rgpBookmarks[],
   DWORD            rgHashedValues[],
   DBROWSTATUS   rgBookmarkStatus[]);

Parameters

hChapter

[in]
The chapter handle. For nonchaptered rowsets, hChapter is ignored.

cBookmarks

The number of bookmarks to hash. If cBookmarks is zero, Hash does not do anything.

rgcbBookmarks

[in]
An array containing the length in bytes for each bookmark.

rgpBookmarks

[in]
An array of pointers to bookmarks. The bookmarks cannot be standard bookmarks (DBBMK_FIRST, DBBMK_LAST, DBBMK_INVALID). If rgpBookmarks contains a duplicate bookmark, a hash value is returned once for each occurrence of the bookmark.

Caution The consumer must ensure that all bookmarks in rgpBookmarks are valid. The provider is not required to validate bookmarks before hashing them. Thus, hash values might be returned for invalid bookmarks.

rgHashedValues

[out]
An array of cBookmarks hash values corresponding to the elements of rgpBookmarks. The consumer allocates, but is not required to initialize, memory for this array and passes the address of this memory to the provider. The provider returns the hash values in the array.

rgBookmarkStatus

[out]
An array with cBookmarks elements in which to return values indicating the status of each bookmark specified in rgpBookmarks. If no errors occur while hashing a bookmark, the corresponding element of rgBookmarkStatus is set to DBROWSTATUS_S_OK. If an error occurs while hashing a bookmark, the corresponding element is set as specified in DB_S_ERRORSOCCURRED. The consumer allocates memory for this array but is not required to initialize it. If rgBookmarkStatus is a null pointer, no bookmark statuses are returned.

Return Code

S_OK
The method succeeded. All bookmarks were successfully hashed. The following value can be returned in rgRowStatus:

  • The bookmark was successfully hashed. The corresponding element of rgRowStatus contains DBROWSTATUS_S_OK.

DB_S_ERRORSOCCURRED
An error occurred while hashing a bookmark, but at least one bookmark was successfully hashed. Successes can occur for the reason listed under S_OK. The following errors can occur:

  • An element of rgpBookmarks pointed to an invalid or incorrectly formed bookmark. The corresponding element of rgBookmarkStatus contains DBROWSTATUS_E_INVALID. Providers are not required to check for this condition, because doing so might slow the method significantly.

  • An element of rgcbBookmarks was zero. The corresponding element of rgBookmarkStatus contains DBROWSTATUS_E_INVALID.

  • An element of rgpBookmarks was a null pointer. The corresponding element of rgBookmarkStatus contains DBROWSTATUS_E_INVALID.

  • An element of rgpBookmarks pointed to a standard bookmark (DBBMK_FIRST, DBBMK_LAST, DBBMK_INVALID). The corresponding element of rgBookmarkStatus contains DBROWSTATUS_E_INVALID.

  • The consumer encountered a recoverable, provider-specific error, such as an RPC failure when transmitting the change to a remote server. The corresponding element of rgRowStatus contains DBROWSTATUS_E_FAIL.

E_FAIL
A provider-specific error occurred.

E_INVALIDARG
cBookmarks was not zero and rgcbBookmarks or rgpBookmarks was a null pointer.

rgHashedValues was a null pointer.

E_UNEXPECTED
ITransaction::Commit or ITransaction::Abort was called and the object is in a zombie state.

DB_E_BADCHAPTER
The rowset was chaptered and hChapter was invalid.

The rowset was single-chaptered and the specified chapter was not the currently open chapter. The consumer must use the currently open chapter or release the currently open chapter before specifying a new chapter.

DB_E_ERRORSOCCURRED
Errors occurred while hashing all of the bookmarks. Errors can occur for the reasons listed under DB_S_ERRORSOCCURRED.

DB_E_NOTREENTRANT
The provider called a method from IRowsetNotify in the consumer that had not yet returned, and the provider does not support reentrancy in this method.

Comments

This method makes no logical change to the state of the object.

If two bookmarks point to the same underlying row, the same hash value is returned for both bookmarks. That is, if Compare returns DBCOMPARE_EQ for two bookmarks, Hash must return the same value for these two bookmarks.

If Hash encounters an error while attempting to hash a bookmark, such as a bad bookmark, it notes the error in the error array, continues processing, and returns DB_S_ERRORSOCCURRED or DB_E_ERRORSOCCURRED. Although the rows are hashed in undefined order, the ordering of the error array must match the order of the bookmark array, so the consumer can perform a side-by-side scan of each array to determine which rows were not hashed.

Hash can hash any valid bookmarks. The consumer is not required to have permission to read the corresponding row, nor is the row even required to exist — for example, it might have been deleted.

Standard bookmarks cannot be hashed.

See Also

IRowsetLocate::Compare


IRowsetScroll : IRowsetLocate

IRowsetScroll enables consumers to fetch rows at approximate positions in the rowset.

IRowsetScroll enables consumers to fetch rows located at approximate positions within a rowset. This method can be used for cases where precise positioning is not critical.

Method | Description
GetApproximatePosition | Gets the approximate position of a row corresponding to a specified bookmark.
GetRowsAtRatio | Fetches rows starting from a fractional position in the rowset.


IRowsetScroll::GetApproximatePosition

Gets the approximate position of a row corresponding to a specified bookmark.

HRESULT GetApproximatePosition (
   HCHAPTER      hChapter,
   ULONG         cbBookmark,
   const BYTE *      pBookmark,
   ULONG *         pulPosition,
   ULONG *         pcRows);

Parameters

hChapter

[in]
The chapter handle. For nonchaptered rowsets, hChapter is ignored.

cbBookmark

[in]
The length in bytes of the bookmark. If this is zero, then pBookmark is ignored, *pcRows is set to the count of rows, and no position is returned in *pulPosition.

pBookmark

[in]
A pointer to a bookmark that identifies the row of which to find the position. This can be a pointer to DBBMK_FIRST or DBBMK_LAST. The consumer is not required to have permission to read the row.

pulPosition

[out]
A pointer to memory in which to return the position of the row identified by the bookmark. The returned number is one-based; that is, the first row in the rowset is 1 and the last row is equal to *pcRows. If *pcRows is zero, the provider sets *pulPosition to zero also, regardless of the bookmark that was passed. If pulPosition is a null pointer, no position is returned. In case of error, *pulPosition is not changed.

pcRows

[out]
A pointer to memory in which to return the total number of rows. This number is zero if there are no rows. If pcRows is a null pointer, no count of rows is returned. In case of error, *pcRows is not changed.

Return Code

S_OK
The method succeeded.

E_FAIL
A provider-specific error occurred.

E_INVALIDARG
cbBookmark was not zero and pBookmark was a null pointer.

E_UNEXPECTED
ITransaction::Commit or ITransaction::Abort was called and the object is in a zombie state.

DB_E_BADBOOKMARK
*pBookmark was invalid, incorrectly formed, or DBBMK_INVALID.

*pBookmark did not match any of the rows in the rowset. This includes the case when the row corresponding to the bookmark was deleted, and DBPROP_BOOKMARKSKIPPED was either VARIANT_FALSE or the provider is a 1.x provider that does not support getting the approximate position of a deleted row.

Note Consumers should only attempt to use bookmarks that they have received from the provider. The provider is guaranteed only to handle bookmarks it gives out in a predictable manner. Attempting to use a random value as a bookmark is undefined; the provider may return DB_E_BADBOOKMARK, may return an unexpected row, or may terminate abnormally.

DB_E_BADCHAPTER
The rowset was chaptered and hChapter was invalid.

The rowset was single-chaptered, and the specified chapter was not the currently open chapter. The consumer must use the currently open chapter or release the currently open chapter before specifying a new chapter.

DB_E_NOTREENTRANT
The provider called a method from IRowsetNotify in the consumer that had not yet returned, and the provider does not support reentrancy in this method.

Comments

This method makes no logical change to the state of the object.

There is no guarantee that the row position will be accurate. The provider is expected to choose the fastest possible estimation technique that is not completely in error. *pcRows must be greater than or equal to *pulPosition. The ratio is intended to be useful for scrolling and similar noncritical uses.

See Also

IRowsetScroll::GetRowsAtRatio


IRowsetScroll::GetRowsAtRatio

Fetches rows starting from a fractional position in the rowset.

HRESULT GetRowsAtRatio (
   HWATCHREGION   hReserved1,
   HCHAPTER            hChapter,
   ULONG               ulNumerator,
   ULONG               ulDenominator,
   LONG                  cRows,
   ULONG *               pcRowsObtained,
   HROW **               prghRows);

Parameters

hReserved1

[in]
Reserved for future use. Providers ignore this parameter.

hChapter

[in]
The chapter handle. For nonchaptered rowsets, hChapter is ignored.

ulNumerator

[in]
See ulDenominator below.

ulDenominator

[in]
The provider determines the first row to fetch from the ratio of ulNumerator to ulDenominator, roughly using the formula:

(ulNumerator x Number of Rows in Rowset) / ulDenominator

If the rowset is being populated asynchronously, ulNumerator and ulDenominator specify the relative position within the rows fetched so far.

How accurately the provider applies this ratio is provider-specific. For example, if ulNumerator is 1 and ulDenominator is 2, some providers will fetch rows starting exactly halfway through the rowset while other providers will fetch rows starting 40 percent of the way through the rowset.

However, all providers must handle the following conditions correctly.

Condition | GetRowsAtRatio action
(ulNumerator = 0) AND (cRows > 0) | Fetches rows starting with the first row in the rowset.
(ulNumerator = 0) AND (cRows < 0) | Returns DB_S_ENDOFROWSET.
(ulNumerator = ulDenominator) AND (cRows > 0) | Returns DB_S_ENDOFROWSET.
(ulNumerator = ulDenominator) AND (cRows < 0) | Fetches rows starting with the last row in the rowset.

cRows

[in]
The number of rows to fetch. A negative number means to fetch backward. cRows can be a negative number only if the value of the DBPROP_CANFETCHBACKWARDS property is VARIANT_TRUE. The rows are returned in rowset-traversal order; that is, the direction in which they were fetched.

If cRows is zero, no rows are fetched. If the provider does not discover any other errors, the method returns S_OK; whether the provider checks for any other errors is provider-specific.

pcRowsObtained

[out]
A pointer to memory in which to return the number of rows fetched. If the consumer has insufficient permissions to return all rows, GetRowsAtRatio fetches all rows for which the consumer has sufficient permission and skips all other rows. If the method fails, *pcRowsObtained is set to 0.

prghRows

[in/out]
A pointer to memory in which to return an array of handles of the fetched rows. If *prghRows is not a null pointer on input, it must be a pointer to memory large enough to return the handles of the requested number of rows. If *prghRows is a null pointer on input, the rowset allocates memory for the row handles and returns the address to this memory; the consumer releases this memory with IMalloc::Free after it releases the row handles. If *prghRows was a null pointer on input and *pcRowsObtained is zero on output or the method fails, the provider does not allocate any memory and ensures that *prghRows is a null pointer on output.

Return Code

S_OK
The method succeeded.

DB_S_ENDOFROWSET
GetRowsAtRatio reached the start or the end of the rowset or chapter and could not fetch all requested rows because the count extended beyond the end. The number of rows actually fetched is returned in *pcRowsObtained; this will be less than cRows.

The rowset is being populated asynchronously and no additional rows are available at this time. To determine whether additional rows may be available, the consumer should call IDBAsynchStatus::GetStatus or listen for the IDBAsynchNotify::OnStop notification.

DB_S_ROWLIMITEXCEEDED
Fetching the number of rows specified in cRows would have exceeded the total number of active rows supported by the rowset. The number of rows that were actually fetched is returned in *pcRowsObtained. This condition can occur only when there are more rows available than can be handled by the rowset. Thus, this condition never conflicts with those described in DB_S_ENDOFROWSET and DB_S_STOPLIMITREACHED, both of which imply that no more rows were available.

DB_S_STOPLIMITREACHED
Fetching rows required further execution of the command, such as when the rowset uses a server-side cursor. Execution was stopped because a resource limit was reached. The number of rows that were actually fetched is returned in *pcRowsObtained.

E_FAIL
A provider-specific error occurred.

E_INVALIDARG
pcRowsObtained or prghRows was a null pointer.

E_OUTOFMEMORY
The provider was unable to allocate sufficient memory in which to instantiate the rows or return the row handles.

E_UNEXPECTED
ITransaction::Commit or ITransaction::Abort was called and the object is in a zombie state.

DB_E_BADCHAPTER
The rowset was chaptered and hChapter was invalid.

The rowset was single-chaptered and the specified chapter was not the currently open chapter. The consumer must use the currently open chapter or release the currently open chapter before specifying a new chapter.

DB_E_BADRATIO
ulNumerator was greater than ulDenominator.

ulDenominator was zero.

DB_E_CANTFETCHBACKWARDS
cRows was negative and the rowset cannot fetch backward.

DB_E_NOTREENTRANT
The consumer called this method while it was processing a notification, and it is an error to call this method while processing the specified DBREASON value.

DB_E_ROWSNOTRELEASED
The provider requires release of existing rows before new ones can be fetched.

DB_SEC_E_PERMISSIONDENIED
The consumer did not have sufficient permission to fetch any of the rows; no rows were fetched.

Comments

GetRowsAtRatio increments the reference count of each row for which it returns a handle by 1. Thus, if a handle is returned for a row that has already been fetched, the reference count of that row will be greater than 1. ReleaseRows must be called once for each time the handle to a row has been returned.

If the provider encounters a problem fetching a row—for example, data stored in a text file contains a letter in what is supposed to be a numeric column—GetRowsAtRatio fetches the row normally, returns the row handle, and returns S_OK. However, when the consumer calls IRowset::GetData for the row, the provider returns DBSTATUS_E_CANTCONVERTVALUE as the status for the offending column.

See Also

IRowset::GetData, IRowset::GetNextRows, IRowsetLocate::GetRowsAt, IRowsetLocate::GetRowsByBookmark, IRowsetScroll::GetApproximatePosition


ISessionProperties

ISessionProperties returns information about the properties a session supports and the current settings of those properties. It is a mandatory interface on sessions.

Method | Description
GetProperties | Returns the list of properties in the Session property group that are currently set on the session.
SetProperties | Sets properties in the Session property group.


ISessionProperties::GetProperties

Returns the list of properties in the Session property group that are currently set on the session.

HRESULT GetProperties (
   ULONG                  cPropertyIDSets,
   const DBPROPIDSET   rgPropertyIDSets[],
   ULONG *                  pcPropertySets,
   DBPROPSET **         prgPropertySets);

Parameters

cPropertyIDSets

[in]
The number of DBPROPIDSET structures in rgPropertyIDSets.

If cPropertySets is zero, the provider ignores rgPropertyIDSets and returns the values of all properties in the Session property group for which values have been set or defaults exist. It does not return the values of properties in the Session property group for which values have not been set and no defaults exist.

If cPropertyIDSets is not zero, the provider returns the values of the requested properties. If a property is not supported, the returned value of dwStatus in the returned DBPROP structure for that property is DBPROPSTATUS_NOTSUPPORTED and the value of dwOptions is undefined.

rgPropertyIDSets

[in]
An array of cPropertyIDSets DBPROPIDSET structures. The properties specified in these structures must belong to the Session property group. The provider returns the values of information about the properties specified in these structures. If cPropertyIDSets is zero, then this parameter is ignored.

pcPropertySets

[out]
A pointer to memory in which to return the number of DBPROPSET structures returned in *prgPropertySets. If cPropertyIDSets is zero, *pcPropertySets is the total number of property sets for which the provider supports at least one property in the Session property group. If cPropertyIDSets is greater than zero, *pcPropertySets is set to cPropertyIDSets. If an error other than DB_E_ERRORSOCCURRED occurs, *pcPropertySets is set to zero.

prgPropertySets

[out]
A pointer to memory in which to return an array of DBPROPSET structures. If cPropertyIDSets is zero, then one structure is returned for each property set that contains at least one property belonging to the Session property group. If cPropertyIDSets is not zero, then one structure is returned for each property set specified in rgPropertyIDSets.

If cPropertyIDSets is not zero, the DBPROPSET structures in *prgPropertySets are returned in the same order as the DBPROPIDSET structures in rgPropertyIDSets; that is, for corresponding elements of each array, the guidPropertySet elements are the same. If cPropertyIDs, in an element of rgPropertyIDSets, is not zero, the DBPROP structures in the corresponding element of *prgPropertySets are returned in the same order as the DBPROPID values in rgPropertyIDs; that is, for corresponding elements of each array, the property IDs are the same.

The provider allocates memory for the structures and returns the address to this memory; the consumer releases this memory with IMalloc::Free when it no longer needs the structures. Before calling IMalloc::Free for *prgPropertySets, the consumer should call IMalloc::Free for the rgProperties element within each element of *prgPropertySets. If *pcPropertySets is zero on output or if an error other than DB_E_ERRORSOCCURRED occurs, the provider does not allocate any memory and ensures that *prgPropertySets is a null pointer on output.

Return Code

S_OK
The method succeeded. In all DBPROP structures returned by the method, dwStatus is set to DBPROPSTATUS_OK.

DB_S_ERRORSOCCURRED
No value was returned for one or more properties. The consumer checks dwStatus in the DBPROP structure to determine the properties for which values were not returned. GetProperties can fail to return properties for a number of reasons, including:

  • The property was not supported by the provider.

  • The property was not in the Session property group.

  • The property set was not supported by the provider. If cPropertyIDs in the DBPROPIDSET structure for the property set was zero, the provider cannot set dwStatus in the DBPROP structure because it does not know the IDs of any properties in the property set. Instead, it sets cProperties to zero in the DBPROPSET structure returned for the property set.

E_FAIL
A provider-specific error occurred.

E_INVALIDARG
cPropertyIDSets was not equal to zero and rgPropertyIDSets was a null pointer.

pcPropertySets or prgPropertySets was a null pointer.

In an element of rgPropertyIDSets, cPropertyIDs was not zero and rgPropertyIDs was a null pointer.

E_OUTOFMEMORY
The provider was unable to allocate sufficient memory in which to return the DBPROPSET or DBPROP structures.

DB_E_ERRORSOCCURRED
Values were not returned for any properties. The provider allocates memory for *prgPropertySets and the consumer checks dwStatus in the DBPROP structures to determine why properties were not returned. The consumer frees this memory when it no longer needs the information.

See Also

IDBProperties::GetPropertyInfo, ISessionProperties::SetProperties


ISessionProperties::SetProperties

Sets properties in the Session property group.

HRESULT SetProperties (
   ULONG         cPropertySets,
   DBPROPSET   rgPropertySets[]);

Parameters

cPropertySets

[in]
The number of DBPROPSET structures in rgPropertySets. If this is zero, the provider ignores rgPropertySets and the method does not do anything.

rgPropertySets

[in/out]
An array of DBPROPSET structures containing properties and values to be set. The properties specified in these structures must belong to the Session property group. If the same property is specified more than once in rgPropertySets, then which value is used is provider-specific. If cPropertySets is zero, this parameter is ignored.

Return Code

S_OK
The method succeeded. In all DBPROP structures passed to the method, dwStatus is set to DBPROPSTATUS_OK.

DB_S_ERRORSOCCURRED
One or more properties were not set. Properties not in error remain set. The consumer checks dwStatus in the DBPROP structures to determine which properties were not set. SetProperties can fail to set properties for a number of reasons, including:

  • The property was not supported by the provider.

  • The property was not in the Session property group.

  • The property set was not supported by the provider.

  • The property is read-only and was not set to its default value.

  • It was not possible to set the property.

  • colid in the DBPROP structure was not DB_NULLID.

  • The value of dwOptions in the DBPROP structure was invalid.

  • The data type in vValue in the DBPROP structure was not the data type of the property or was not VT_EMPTY.

  • The value in vValue in the DBPROP structure was invalid.

  • The property's value conflicted with an existing property.

E_FAIL
A provider-specific error occurred.

E_INVALIDARG
cPropertySets was not equal to zero and rgPropertySets was a null pointer.

In an element of rgPropertySets, cProperties was not zero and rgProperties was a null pointer.

DB_E_ERRORSOCCURRED
All property values were invalid and no properties were set. The consumer checks dwStatus in the DBPROP structures to determine why properties were not set.

See Also

IDBProperties::GetPropertyInfo, ISessionProperties::GetProperties


ISourcesRowset

ISourcesRowset returns a rowset of data sources and enumerators visible from the current enumerator.

Method | Description
GetSourcesRowset | Returns a rowset of the data sources and enumerators visible from the current enumerator.


ISourcesRowset::GetSourcesRowset

Returns a rowset of the data sources and enumerators visible from the current enumerator.

HRESULT GetSourcesRowset(
   IUnknown         pUnkOuter,
   REFIID            riid,
   ULONG         cPropertySets,
   DBPROPSET   rgPropertySets[],
   IUnknown **      ppSourcesRowset);

Parameters

pUnkOuter

A pointer to the controlling IUnknown interface if the sources rowset is being created as part of an aggregate. If the rowset is not part of an aggregate, this must be set to a null pointer.

riid

The IID of the interface on which to return a pointer. This interface is conceptually added to the list of required interfaces on the resulting rowset, and the method fails (E_NOINTERFACE) if that interface cannot be supported on the resulting rowset.

cPropertySets

[in]
The number of DBPROPSET structures in rgPropertySets. If this is zero, the provider ignores rgPropertySets.

rgPropertySets

[in/out]
An array of DBPROPSET structures containing properties and values to be set. The properties specified in these structures must belong to the Rowset property group. If the same property is specified more than once in rgPropertySets, then it is provider-specific which value is used. If cPropertySets is 0, this argument is ignored.

ppSourcesRowset

A pointer to memory in which to return the requested interface pointer on the rowset. If an error occurs, the returned pointer is null.

Return Code

S_OK
The method succeeded. In all DBPROP structures passed to the method, dwStatus is set to DBPROPSTATUS_OK.

DB_S_ERRORSOCCURRED
The rowset was opened but one or more properties—for which the dwOptions element of the DBPROP structure was DBPROPOPTIONS_OPTIONAL—were not set. The consumer checks dwStatus in the DBPROP structures to determine which properties were not set. The method can fail to set properties for a number of reasons, including:

  • The property was not supported by the provider.

  • The property was not in the Rowset property group.

  • The property set was not supported by the provider.

  • It was not possible to set the property.

  • The colid in the DBPROP structure was invalid.

  • The data type in vValue in the DBPROP structure was not the data type of the property or was not VT_EMPTY.

  • The value in vValue in the DBPROP structure was invalid.

  • The property's value conflicted with an existing property.

  • A property was specified to be applied to all columns, but could not be applied to one or more columns.

E_FAIL
A provider-specific error occurred.

E_INVALIDARG
ppSourcesRowset was a null pointer.

cPropertySets was not 0 and rgPropertySets was a null pointer.

In an element of rgPropertySets, cProperties was not 0 and rgProperties was a null pointer.

E_NOINTERFACE
The rowset did not support the interface specified in riid.

E_OUTOFMEMORY
The provider did not have enough memory to create the Rowset object.

E_UNEXPECTED
The Enumerator object was in an uninitialized state.

DB_E_ABORTLIMITREACHED
The method failed because a resource limit has been reached. For example, a query used to implement the method timed out. No rowset is returned.

DB_E_ERRORSOCCURRED
No rowset was returned because one or more properties—for which the dwOptions element of the DBPROP structure was DBPROPOPTIONS_REQUIRED or an invalid value—were not set. The consumer checks dwStatus in the DBPROP structures to determine which properties were not set. None of the satisfiable properties are remembered. The method can fail to set properties for any of the reasons specified in DB_S_ERRORSOCCURRED, except the reason that states that it was not possible to set the property.

DB_E_NOAGGREGATION
pUnkOuter was not a null pointer and the rowset did not support aggregation.

pUnkOuter was non-null and riid was not IID_Unknown.

Comments

GetSourcesRowset returns the following rowset. The rowset is read-only. The columns are returned in the order shown.

Column name | Type indicator | Description
SOURCES_NAME | DBTYPE_WSTR | The name of the data source or enumerator.
SOURCES_PARSENAME | DBTYPE_WSTR | String to pass to IParseDisplayName to obtain a moniker for the data source or enumerator.
SOURCES_DESCRIPTION | DBTYPE_WSTR | The description of the data source or enumerator.
SOURCES_TYPE DBTYPE_UI2 Whether the row describes a data source or an enumerator:
  • DBSOURCETYPE_DATASOURCE

  • DBSOURCETYPE_ENUMERATOR

If a single piece of code is capable of being used both as a data source and as an enumerator, it is listed in the rowset twice, once in each role.

SOURCES_ISPARENT DBTYPE_BOOL If the row describes an enumerator, SOURCES_ISPARENT is VARIANT_TRUE if the enumerator is the parent enumerator; that is, the enumerator whose enumeration contains the enumerator on which ISourcesRowset::GetSourcesRowset was just called. This allows the consumer to go backward through the enumeration. Whether an enumerator is able to enumerate its parent is provider-specific. Otherwise, SOURCES_ISPARENT is VARIANT_FALSE.

If the row describes a data source, SOURCES_ISPARENT is ignored by the consumer.

See Also

IDBProperties::GetPropertyInfo


Properties Table (by Property Groups)

Supported Properties (by Property Groups)

This table lists all properties contained within each property group. For more information about a specific property, click its link below.
RW column describes Read/Write status of properties: R = Read Only, RW = Read and Write, W = Write Only.
Value column describes default values. All strings are wide ones.

Property Group | Property Set | Properties | RW | Values
Data Source DBPROPSET_ DATASOURCE DBPROP_CURRENTCATALOG RW ""
Data Source Information DBPROPSET_ DATASOURCEINFO DBPROP_ACTIVESESSIONS
DBPROP_ALTERCOLUMN
DBPROP_ASYNCTXNABORT
DBPROP_ASYNCTXNCOMMIT
DBPROP_BYREFACCESSORS
DBPROP_CATALOGLOCATION
DBPROP_CATALOGTERM
DBPROP_CATALOGUSAGE
DBPROP_COLUMNDEFINITION
DBPROP_CONCATNULLBEHAVIOR
DBPROP_DATASOURCENAME
DBPROP_DATASOURCEREADONLY
DBPROP_DBMSNAME
DBPROP_DBMSVER
DBPROP_DSOTHREADMODEL
DBPROP_GROUPBY
DBPROP_HETEROGENEOUSTABLES
DBPROP_IDENTIFIERCASE
DBPROP_MAXINDEXSIZE
DBPROP_MAXOPENCHAPTERS
DBPROP_MAXORSINFILTER
DBPROP_MAXROWSIZE
DBPROP_MAXROWSIZEINCLUDESBLOB
DBPROP_MAXSORTCOLUMNS
DBPROP_MAXTABLESINSELECT
DBPROP_MULTIPLEPARAMSETS
DBPROP_MULTIPLERESULTS
DBPROP_MULTIPLESTORAGEOBJECTS
DBPROP_MULTITABLEUPDATE
DBPROP_NULLCOLLATION
DBPROP_OLEOBJECTS
DBPROP_ORDERBYCOLUMNSINSELECT
DBPROP_OUTPUTPARAMETERAVAILABILITY
DBPROP_PERSISTENTIDTYPE
DBPROP_PREPAREABORTBEHAVIOR
DBPROP_PREPARECOMMITBEHAVIOR
DBPROP_PROCEDURETERM
DBPROP_PROVIDERFRIENDLYNAME
DBPROP_PROVIDERNAME
DBPROP_PROVIDEROLEDBVER
DBPROP_PROVIDERVER
DBPROP_QUOTEDIDENTIFIERCASE
DBPROP_ROWSETCONVERSIONSONCOMMAND
DBPROP_SCHEMATERM
DBPROP_SCHEMAUSAGE
DBPROP_SERVERNAME
DBPROP_SORTONINDEX
DBPROP_SQLSUPPORT
DBPROP_STRUCTUREDSTORAGE
DBPROP_SUBQUERIES
DBPROP_SUPPORTEDTXNDDL
DBPROP_SUPPORTEDTXNISOLEVELS
DBPROP_SUPPORTEDTXNISORETAIN
DBPROP_USERNAME
DBPROP_TABLETERM 		R
R
R
R
R
R
R
R
R
R
R
R
R
R
R
R
R
R
R
R
R
R
R
R
R
R
R
R
R
R
R
R
R
R
R
R
R
R
R
R
R
R
R
R
R
R
R
R
R
R
R
R
R
R
R 		8
0
FALSE
FALSE
FALSE
DBPROPVAL_CL_START
"directory"
DBPROPVAL_CU_DML_STATEMENTS
DBPROPVAL_CD_NOTNULL
DBPROPVAL_CB_NON_NULL
""
FALSE
"MySQL"
"07.00.0000"
DBPROPVAL_RT_APTMTTHREAD|DBPROPVAL_RT_SINGLETHREAD
DBPROPVAL_GB_EQUALS_SELECT
0
DBPROPVAL_IC_MIXED
0
0
0
16384
TRUE
0
0
FALSE
DBPROPVAL_MR_NOTSUPPORTED
TRUE
FALSE
DBPROPVAL_NC_START
0
FALSE
DBPROPVAL_OA_NOTSUPPORTED
DBPROPVAL_PT_NAME
DBPROPAL_CB_PRESERVE
DBPROPAL_CB_PRESERVE
"stored procedure"
"MyOLEDB Provider"
"MYSQLPROV.DLL"
"02.00"
"02.00.0000"
DBPROPVAL_IC_MIXED
TRUE
"owner"
DBPROPVAL_SU_DML_STATEMENTS
"."
FALSE
DBPROPVAL_SQL_ANSI92_INTERMEDIATE
0
DBPROPVAL_SQ
DBPROPVAL_TC_NONE
0
0
""
"table"
Initialization DBPROPSET_ DBINIT DBPROP_AUTH_CACHE_AUTHINFO
DBPROP_AUTH_ENCRYPT_PASSWORD
DBPROP_AUTH_INTEGRATED
DBPROP_AUTH_MASK_PASSWORD
DBPROP_AUTH_PASSWORD
DBPROP_AUTH_PERSIST_ENCRYPTED
DBPROP_AUTH_PERSIST_SENSITIVE_AUTHINFO
DBPROP_AUTH_USERID
DBPROP_INIT_DATASOURCE
DBPROP_INIT_HWND
DBPROP_INIT_IMPERSONATION_LEVEL
DBPROP_INIT_LCID
DBPROP_INIT_LOCATION
DBPROP_INIT_MODE
DBPROP_INIT_PROMPT
DBPROP_INIT_PROTECTION_LEVEL
DBPROP_INIT_PROVIDERSTRING
DBPROP_INIT_TIMEOUT 		R
R
RW
R
RW
R
R
RW
RW
RW
R
R
RW
R
RW
R
RW
R 		FALSE
FALSE
""
FALSE
""
FALSE
TRUE
""
""
NULL
DB_IMP_LEVEL_IMPERSONATE
0x0409 (US English)
""
DB_MODE_READWRITE
DBPROMPT_COMPLETE
DB_PROT_LEVEL_NONE
""
0
Rowset DBPROPSET_ ROWSET DBPROP_ABORTPRESERVE
DBPROP_APPENDONLY
DBPROP_BLOCKINGSTORAGEOBJECTS
DBPROP_BOOKMARKS
DBPROP_BOOKMARKSKIPPED
DBPROP_BOOKMARKTYPE
DBPROP_CACHEDEFERRED
DBPROP_CANFETCHBACKWARDS
DBPROP_CANHOLDROWS
DBPROP_CANSCROLLBACKWARDS
DBPROP_CHANGEINSERTEDROWS
DBPROP_COLUMNRESTRICT
DBPROP_COMMANDTIMEOUT
DBPROP_COMMITPRESERVE
DBPROP_DEFERRED
DBPROP_DELAYSTORAGEOBJECTS
DBPROP_IACCESSOR
DBPROP_ICHAPTEREDROWSET
DBPROP_ICOLUMNSINFO
DBPROP_ICOLUMNSROWSET
DBPROP_ICONNECTIONPOINTCONTAINER
DBPROP_ICONVERTTYPE
DBPROP_IDBASYNCHSTATUS
DBPROP_IMULTIPLERESULTS
DBPROP_IROWSET
DBPROP_IROWSETCHANGE
DBPROP_IROWSETFIND
DBPROP_IROWSETIDENTITY
DBPROP_IROWSETINDEX
DBPROP_IROWSETINFO
DBPROP_IROWSETLOCATE
DBPROP_IROWSETREFRESH
DBPROP_IROWSETRESYNCH
DBPROP_IROWSETSCROLL
DBPROP_IROWSETUPDATE
DBPROP_IROWSETVIEW
DBPROP_ISUPPORTERRORINFO
DBPROP_ILOCKBYTES
DBPROP_ISEQUENTIALSTREAM
DBPROP_ISTORAGE
DBPROP_ISTREAM
DBPROP_IMMOBILEROWS
DBPROP_LITERALBOOKMARKS
DBPROP_LITERALIDENTITY
DBPROP_MAXOPENROWS
DBPROP_MAXPENDINGROWS
DBPROP_MAXROWS
DBPROP_MEMORYUSAGE
DBPROP_NOTIFICATIONGRANULARITY
DBPROP_NOTIFICATIONPHASES
DBPROP_NOTIFYCOLUMNSET
DBPROP_NOTIFYROWDELETE
DBPROP_NOTIFYROWFIRSTCHANGE
DBPROP_NOTIFYROWINSERT
DBPROP_NOTIFYROWRESYNCH
DBPROP_NOTIFYROWSETRELEASE
DBPROP_NOTIFYROWSETFETCHPOSITIONCHANGE
DBPROP_NOTIFYROWUNDOCHANGE
DBPROP_NOTIFYROWUNDODELETE
DBPROP_NOTIFYROWUNDOINSERT
DBPROP_NOTIFYROWUPDATE
DBPROP_ORDEREDBOOKMARKS
DBPROP_OTHERINSERT
DBPROP_OTHERUPDATEDELETE
DBPROP_OWNINSERT
DBPROP_OWNUPDATEDELETE
DBPROP_QUICKRESTART
DBPROP_REENTRANTEVENTS
DBPROP_REMOVEDELETED
DBPROP_REPORTMULTIPLECHANGES
DBPROP_RETURNPENDINGINSERTS
DBPROP_ROW_BULKOPS
DBPROP_ROWRESTRICT
DBPROP_ROWTHREADMODEL
DBPROP_SERVERCURSOR
DBPROP_SERVERDATAONINSERT
DBPROP_STRONGIDENTITY
DBPROP_TRANSACTEDOBJECT
DBPROP_UPDATABILITY 		R
R
RW
RW
R
R
R
RW
RW
RW
R
R
R
R
R
R
R
R
R
R
R
R
R
R
R
RW
RW
RW
RW
R
RW
R
R
RW
R
R
R
R
R
R
R
R
R
R
R
R
R
R
R
R
R
R
R
R
R
R
R
R
R
R
R
R
R
R
R
R
R
R
R
R
R
R
R
R
R
R
R
R
R 		FALSE
FALSE
FALSE
TRUE
FALSE
DBPROPVAL_BMK_NUMERIC
FALSE
TRUE (FALSE under PSQL.2000)
TRUE
TRUE (FALSE under PSQL.2000)
TRUE
FALSE
0
FALSE
FALSE
FALSE
TRUE
FALSE
TRUE
FALSE
TRUE
TRUE
FALSE
FALSE
TRUE
TRUE
TRUE
TRUE
TRUE
TRUE
TRUE
FALSE
FALSE
TRUE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
FALSE
TRUE
TRUE
TRUE
200
0
0
0
DBPROPVAL_NT_SINGLEROW
DBPROPVAL_NP_OKTODO|DBPROPVAL_NP_ABOUTTODO|DBPROPVAL_NP_FAILEDTODO|DBPROPVAL_NP_DIDEVENT
DBPROPVAL_NP_OKTODO|DBPROPVAL_NP_ABOUTTODO|DBPROPVAL_NP_FAILEDTODO|DBPROPVAL_NP_DIDEVENT
DBPROPVAL_NP_OKTODO|DBPROPVAL_NP_ABOUTTODO|DBPROPVAL_NP_FAILEDTODO|DBPROPVAL_NP_DIDEVENT
DBPROPVAL_NP_OKTODO|DBPROPVAL_NP_ABOUTTODO|DBPROPVAL_NP_FAILEDTODO|DBPROPVAL_NP_DIDEVENT
DBPROPVAL_NP_OKTODO|DBPROPVAL_NP_ABOUTTODO|DBPROPVAL_NP_FAILEDTODO|DBPROPVAL_NP_DIDEVENT
DBPROPVAL_NP_OKTODO|DBPROPVAL_NP_ABOUTTODO|DBPROPVAL_NP_FAILEDTODO|DBPROPVAL_NP_DIDEVENT
DBPROPVAL_NP_DIDEVENT
DBPROPVAL_NP_OKTODO|DBPROPVAL_NP_ABOUTTODO|DBPROPVAL_NP_FAILEDTODO|DBPROPVAL_NP_DIDEVENT
DBPROPVAL_NP_OKTODO|DBPROPVAL_NP_ABOUTTODO|DBPROPVAL_NP_FAILEDTODO|DBPROPVAL_NP_DIDEVENT
DBPROPVAL_NP_OKTODO|DBPROPVAL_NP_ABOUTTODO|DBPROPVAL_NP_FAILEDTODO|DBPROPVAL_NP_DIDEVENT
DBPROPVAL_NP_OKTODO|DBPROPVAL_NP_ABOUTTODO|DBPROPVAL_NP_FAILEDTODO|DBPROPVAL_NP_DIDEVENT
DBPROPVAL_NP_OKTODO|DBPROPVAL_NP_ABOUTTODO|DBPROPVAL_NP_FAILEDTODO|DBPROPVAL_NP_DIDEVENT
FALSE
TRUE
TRUE
FALSE
TRUE
TRUE
FALSE
TRUE
FALSE
FALSE
0
FALSE
DBPROPVAL_RT_APTMTTHREAD|DBPROPVAL_RT_SINGLETHREAD
TRUE
FALSE
TRUE
FALSE
DBPROPVAL_UP_CHANGE|DBPROPVAL_UP_DELETE|DBPROPVAL_UP_INSERT
Session | DBPROPSET_SESSION | DBPROP_SESS_AUTOCOMMITISOLEVELS | R | 0
Index DBPROPSET_INDEX DBPROP_INDEX_AUTOUPDATE
DBPROP_INDEX_CLUSTERED
DBPROP_INDEX_FILLFACTOR
DBPROP_INDEX_INITIALSIZE
DBPROP_INDEX_NULLCOLLATION
DBPROP_INDEX_NULLS
DBPROP_INDEX_PRIMARYKEY
DBPROP_INDEX_SORTBOOKMARKS
DBPROP_INDEX_TEMPINDEX
DBPROP_INDEX_TYPE
DBPROP_INDEX_UNIQUE 		R
R
R
R
R
R
R
R
R
R
RW 		TRUE
FALSE
100
0
0
0
FALSE
TRUE
FALSE
DBPROPVAL_IT_BTREE
FALSE


Properties Table (Alphabetical)

Property ID Description
DBPROP_ABORTPRESERVE Property group: Rowset
Property set: DBPROPSET_ROWSET
Type: VT_BOOL
Description: Preserve on Abort

VARIANT_TRUE—After aborting a transaction, the rowset remains active. That is, it is possible to fetch new rows, update, delete, and insert rows, and so on.

VARIANT_FALSE—After aborting a transaction, the only operations allowed on a rowset are to release row and accessor handles and to release the rowset.

DBPROP_ACCESSORDER Property group: Rowset
Property set: DBPROPSET_ROWSET
Type: VT_I4
Description: Access Order

The order in which columns must be accessed on the rowset. One of the following values:

DBPROPVAL_AO_RANDOM—Columns can be accessed in any order.

DBPROPVAL_AO_SEQUENTIALSTORAGEOBJECTS—Columns bound as storage objects can only be accessed in sequential order as determined by the column ordinal. Further, storage objects from one row must be retrieved before calling GetData on any columns in any subsequent row. Calling GetData on a column bound as a storage object returns DBSTATUS_E_UNAVAILABLE for any columns bound as storage objects if any of the following are true:

  • Columns beyond the column bound as a storage object are specified in the accessor.

  • Columns beyond the column bound as a storage object have been accessed in a previous call to GetData for that row.

  • GetData has been called for any columns on a row returned after the specified row.

Providers that never impose restrictions on column access ordering return DBPROPSTATUS_S_OK when this value is set. However, they upgrade the property to DBPROPVAL_AO_RANDOM such that calling GetProperty continues to return DBPROPVAL_AO_RANDOM for this property.

DBPROPVAL_AO_SEQUENTIAL—All columns must be accessed in sequential order determined by the column ordinal. Further, all columns from one row must be retrieved before calling GetData on any columns in any subsequent row. Calling GetData returns DBSTATUS_E_UNAVAILABLE for any columns for which any of the following are true:

  • The column is bound as a storage object and columns beyond it are specified in the accessor.

  • Columns beyond the bound column have been accessed in a previous call to GetData for that row.

  • GetData has been called for any columns on a row returned after the specified row.

Providers that never impose restrictions on column access ordering return DBPROPSTATUS_S_OK when this value is set. However, they upgrade the property to DBPROPVAL_AO_RANDOM such that calling GetProperty continues to return DBPROPVAL_AO_RANDOM for this property.

Providers may be able to optimize how data is retrieved if they know it will be read in column order. For instance, the provider may be able to read directly from a stream over the data if it knows the columns will be read in strictly sequential order, but may not be able to do so efficiently if the columns contain BLOBs that may be read in a random order.

DBPROP_ACTIVESESSIONS Property group: Data Source Information
Property set: DBPROPSET_DATASOURCEINFO
Type: VT_I4
Description: Active Sessions

The maximum number of sessions that can exist at the same time. If this property is set to zero, there is no limit on the number of sessions that can exist at one time.

DBPROP_ALTERCOLUMN Property group: Data Source Information
Property set: DBPROPSET_DATASOURCEINFO
Type: VT_I4
Description: Alter Column Support

A bitmask describing which portions of the DBCOLUMNDESC structure can be used in a call to IAlterTable::AlterColumn.

A combination of one or more of the following:

DBCOLUMNDESCFLAG_TYPENAME
DBCOLUMNDESCFLAG_ITYPEINFO
DBCOLUMNDESCFLAG_PROPERTIES
DBCOLUMNDESCFLAG_CLSID
DBCOLUMNDESCFLAG_COLSIZE
DBCOLUMNDESCFLAG_DBCID
DBCOLUMNDESCFLAG_WTYPE
DBCOLUMNDESCFLAG_PRECISION
DBCOLUMNDESCFLAG_SCALE

DBPROP_APPENDONLY Property group: Rowset
Property set: DBPROPSET_ROWSET
Type: VT_BOOL
Description: Append-Only Rowset

A rowset opened with this property set to VARIANT_TRUE will be initially empty. If the rowset was obtained by IOpenRowset::OpenRowset, this is equivalent to positioning the start of the rowset at the end of the table; if it was obtained by executing a command, it is equivalent to placing the start of the rowset at the end of the command's results. A rowset opened with DBPROP_APPENDONLY set to VARIANT_TRUE will be populated only by those rows inserted in it.

DBPROP_APPENDONLY set to VARIANT_TRUE implies:

  • DBPROP_IRowsetChange is VARIANT_TRUE.

  • DBPROP_OWNINSERT is VARIANT_TRUE.

  • DBPROP_UPDATABILITY has the flag DBPROPVAL_UP_INSERT set.

  • DBPROP_OTHERINSERT is VARIANT_FALSE.
DBPROP_ASYNCTXNABORT Property group: Data Source Information
Property set: DBPROPSET_DATASOURCEINFO
Type: VT_BOOL
Description: Asynchable Abort

Whether transactions can be aborted asynchronously.

DBPROP_ASYNCTXNCOMMIT Property group: Data Source Information
Property set: DBPROPSET_DATASOURCEINFO
Type: VT_BOOL
Description: Asynchable Commit

Whether transactions can be committed asynchronously.

DBPROP_AUTH_CACHE_AUTHINFO Property group: Initialization
Property set: DBPROPSET_DBINIT
Type: VT_BOOL
Description: Cache Authentication

VARIANT_TRUE—The data source object or enumerator is allowed to cache sensitive authentication information such as a password in an internal cache.

VARIANT_FALSE—The data source object or enumerator is not allowed to cache sensitive authentication information.

DBPROP_AUTH_ENCRYPT_PASSWORD Property group: Initialization
Property set: DBPROPSET_DBINIT
Type: VT_BOOL
Description: Encrypt Password

VARIANT_TRUE—The consumer requires that the password be sent to the data source or enumerator in an encrypted form. This property specifies a stronger form of masking than DBPROP_AUTH_MASKPASSWORD; it uses cryptographic techniques.

VARIANT_FALSE—The password can be sent in an unencrypted form.

DBPROP_AUTH_INTEGRATED Property group: Initialization
Property set: DBPROPSET_DBINIT
Type: VT_BSTR
Description: Integrated Security

A string containing the name of the authentication service used by the server to identify the user using the identity provided by an authentication domain. For example, for Microsoft® NT® Integrated Security, this is "SSPI" (for Security Support Provider Interface). If the BSTR is a null pointer, the default authentication service should be used. When this property is used, no other DBPROP_AUTH* properties are needed and, if provided, their values are ignored.

DBPROP_AUTH_MASK_PASSWORD Property group: Initialization
Property set: DBPROPSET_DBINIT
Type: VT_BOOL
Description: Mask Password

VARIANT_TRUE—The consumer requires that the password be sent to the data source or enumerator in a masked form.

VARIANT_FALSE—The password can be sent in an unmasked form.

DBPROP_AUTH_PASSWORD Property group: Initialization
Property set: DBPROPSET_DBINIT
Type: VT_BSTR
Description: Password

The password to be used when connecting to the data source or enumerator. When the value of this property is retrieved with IDBProperties::GetProperties, the provider might return a mask such as "******" or an empty string instead of the actual password. Note that the password is still set internally and is used when IDBInitialize::Initialize is called.

DBPROP_AUTH_PERSIST_ENCRYPTED Property group: Initialization
Property set: DBPROPSET_DBINIT
Type: VT_BOOL
Description: Persist Encrypted

VARIANT_TRUE—The consumer requires that the data source object persist sensitive authentication information such as a password in encrypted form.

VARIANT_FALSE—The data source object can persist sensitive authentication information in unencrypted form.

DBPROP_AUTH_PERSIST_SENSITIVE_AUTHINFO Property group: Initialization
Property set: DBPROPSET_DBINIT
Type: VT_BOOL
Description: Persist Security Info

VARIANT_TRUE—The data source object is allowed to persist sensitive authentication information such as a password along with other authentication information.

VARIANT_FALSE—The data source object cannot persist sensitive authentication information.

If DBPROP_AUTH_PERSIST_SENSITIVE_AUTHINFO is set to VARIANT_FALSE at the time the data source is initialized, the data source object cannot persist sensitive authentication information. Furthermore, requesting properties that contain sensitive authentication information, such as password, returns some default value instead of the actual password. Once the data source has been uninitialized, sensitive information that was set when the data source was initialized with the DBPROP_AUTH_PERSIST_SENSITIVE_AUTHINFO property set to VARIANT_FALSE still cannot be obtained through IDBProperties::GetProperties or by persisting the uninitialized data source, but new properties set after the data source has been uninitialized can be persisted or obtained as long as DBPROP_AUTH_PERSIST_SENSITIVE_AUTHINFO is VARIANT_TRUE.

DBPROP_AUTH_USERID Property group: Initialization
Property set: DBPROPSET_DBINIT
Type: VT_BSTR
Description: User ID

The user ID to be used when connecting to the data source or enumerator.

DBPROP_BLOCKINGSTORAGE-OBJECTS Property group: Rowset
Property set: DBPROPSET_ROWSET
Type: VT_BOOL

Description: Blocking Storage Objects

Whether storage objects might prevent use of other methods on the rowset.

VARIANT_TRUE—Instantiated storage objects might prevent the use of other methods on the rowset. That is, after a storage object is created and before it is released, methods other than those on the storage object might return E_UNEXPECTED.

VARIANT_FALSE—Instantiated storage objects do not prevent the use of other methods.

DBPROP_BOOKMARKINFO Property group: Rowset
Property set: DBPROPSET_ROWSET
Type: VT_I4

Description: Bookmark Information

A bitmask specifying additional information about bookmarks over the rowset. A combination of zero or more of the following:

DBPROPVAL_BI_CROSSROWSET—If set, bookmark values returned by this rowset are valid across rowsets with the same metadata. If not set, bookmark values are specific to this rowset and are not guaranteed to return the same values in other rowsets, even those resulting from the same specification.

DBPROP_BOOKMARKS Property group: Rowset
Property set: DBPROPSET_ROWSET
Type: VT_BOOL

Description: Use Bookmarks

Whether the rowset supports bookmarks. One of the following:

VARIANT_TRUE—The rowset supports bookmarks. Column 0 is the bookmark for the rows. Getting this column obtains a bookmark value, which can be used to reposition to the row.

VARIANT_FALSE—The rowset does not support bookmarks. The rowset is sequential and the values of the DBPROP_LITERALBOOKMARKS and DBPROP_ORDEREDBOOKMARKS properties are ignored.

The value of this property is automatically set to VARIANT_TRUE if the value of DBPROP_IRowsetLocate, DBPROP_LITERALBOOKMARKS, or DBPROP_ORDEREDBOOKMARKS is set to VARIANT_TRUE.

DBPROP_BOOKMARKSKIPPED Property group: Rowset
Property set: DBPROPSET_ROWSET
Type: VT_BOOL

Description: Skip Deleted Bookmarks

Whether the rowset allows IRowsetLocate::GetRowsAt, IRowsetScroll::GetApproximatePosition, or IRowsetFind::FindNextRow to continue if a bookmark row was deleted, is a row to which the consumer does not have access rights, or is no longer a member of the rowset. One of the following:

VARIANT_TRUE—GetRowsAt, GetApproximatePosition, or FindNextRow skips the bookmark row and continues with the next row.

VARIANT_FALSE—GetRowsAt, GetApproximatePosition, or FindNextRow returns DB_E_BADBOOKMARK.

DBPROP_BOOKMARKTYPE Property group: Rowset
Property set: DBPROPSET_ROWSET
Type: VT_I4
Description: Bookmark Type

The bookmark type supported by the rowset. One of the following:

DBPROPVAL_BMK_NUMERIC—The bookmark type is numeric. Numeric bookmarks are based upon a row property that is not dependent on the values of the row's columns. For instance, they can be based on the absolute position of the row within a rowset, or on a row ID that the storage engine assigned to a tuple at its creation. The validity of numeric bookmarks is not changed by modifying the row's columns.

DBPROPVAL_BMK_KEY—The bookmark type is key. Key bookmarks are based on the values of one or more of the row's columns; these values form a unique key for each row. A key bookmark may be left dangling if the key values of the corresponding row are changed.

DBPROP_BYREFACCESSORS Property group: Data Source Information
Property set: DBPROPSET_DATASOURCEINFO
Type: VT_BOOL
Description: Pass By Ref Accessors

Whether the provider supports the DBACCESSOR_PASSBYREF flag in IAccessor::CreateAccessor. This applies to both row and parameter accessors.

DBPROP_CACHEDEFERRED Property group: Rowset
Property set: DBPROPSET_ROWSET
Type: VT_BOOL
Description: Cache Deferred Columns

VARIANT_TRUE—The provider caches the value of a deferred column when the consumer first gets a value from that column. When the consumer later gets a value from the column, the provider returns the value in the cache. The contents of the cache can be overwritten by IRowsetChange::SetData or IRowsetRefresh::RefreshVisibleData. The cached value is released when the row is released.

Consumers should set the value of this property to VARIANT_TRUE rather sparingly, because it might require substantial memory use in the provider. Such use might limit the number of rows that can be held at one time. Setting the value of this property to VARIANT_TRUE automatically sets the value of the DBPROP_DEFERRED property to VARIANT_TRUE.

VARIANT_FALSE—The provider does not cache the value of a deferred column, and multiple calls to IRowset::GetData for the column can return different values.

DBPROP_CANFETCHBACKWARDS Property group: Rowset
Property set: DBPROPSET_ROWSET
Type: VT_BOOL
Description: Fetch Backward

Whether the rowset can fetch backward.

VARIANT_TRUE—cRows in IRowset::GetNextRows, IRowsetLocate::GetRowsAt, and IRowsetScroll::GetRowsAtRatio can be negative. When it is negative, these methods fetch rows backward from the specified row.

VARIANT_FALSE—cRows must be non-negative.

DBPROP_CANHOLDROWS Property group: Rowset
Property set: DBPROPSET_ROWSET
Type: VT_BOOL
Description: Hold Rows

VARIANT_TRUE—The rowset allows the consumer to retrieve more rows or change the next fetch position while holding previously fetched rows with pending changes.

VARIANT_FALSE—The rowset requires pending changes to be transmitted to the data source and all rows to be released before fetching additional rows, inserting new rows, or changing the next fetch position.

DBPROP_CANSCROLLBACKWARDS Property group: Rowset
Property set: DBPROPSET_ROWSET
Type: VT_BOOL
Description: Scroll Backward

Whether the rowset can scroll backward.

VARIANT_TRUE—lRowsOffset in IRowset::GetNextRows or IRowsetLocate::GetRowsAt can be negative.

VARIANT_FALSE—lRowsOffset must be non-negative.

If the rowset supports IRowsetLocate, then the value of this property is VARIANT_TRUE, because this method supports backward scrolling by definition.

DBPROP_CATALOGLOCATION Property group: Data Source Information
Property set: DBPROPSET_DATASOURCEINFO
Type: VT_I4
Description: Catalog Location

The position of the catalog name in a qualified table name in a text command. One of the following:

DBPROPVAL_CL_START—The catalog name is at the start of the fully qualified name. For example, a dBASE® provider returns DBPROPVAL_CL_START because the directory (catalog name) is at the start of the table name, as in \EMPDATA\EMP.DBF.

DBPROPVAL_CL_END—The catalog name is at the end of the fully qualified name. For example, an ORACLE server provider returns DBPROPVAL_CL_END because the catalog name is at the end of the table name, as in ADMIN.EMP@EMPDATA.

DBPROP_CATALOGTERM Property group: Data Source Information
Property set: DBPROPSET_DATASOURCEINFO
Type: VT_BSTR
Description: Catalog Term

The name the data source uses for a catalog; for example, "catalog", "database", or "directory". This is used for building user interfaces.

DBPROP_CATALOGUSAGE Property group: Data Source Information
Property set: DBPROPSET_DATASOURCEINFO
Type: VT_I4
Description: Catalog Usage

A bitmask specifying how catalog names can be used in text commands. A combination of zero or more of the following:

DBPROPVAL_CU_DML_STATEMENTS—Catalog names are supported in all Data Manipulation Language statements.

DBPROPVAL_CU_TABLE_DEFINITION—Catalog names are supported in all table definition statements.

DBPROPVAL_CU_INDEX_DEFINITION—Catalog names are supported in all index definition statements.

DBPROPVAL_CU_PRIVILEGE_DEFINITION—Catalog names are supported in all privilege definition statements.

DBPROP_CHANGEINSERTEDROWS Property group: Rowset
Property set: DBPROPSET_ROWSET
Type: VT_BOOL
Description: Change Inserted Rows

VARIANT_TRUE—The consumer can call IRowsetChange::DeleteRows or IRowsetChange::SetData for newly inserted rows.

VARIANT_FALSE—If the consumer calls DeleteRows or SetData for newly inserted rows, DeleteRows returns a status of DBROWSTATUS_E_NEWLYINSERTED for the row and SetData returns DB_E_NEWLYINSERTED.

A newly inserted row is defined to be a row for which the insertion has been transmitted to the data source, as opposed to a pending insert row. For some providers this property may imply other properties.

DBPROP_COL_AUTOINCREMENT Property group: Column
Property set: DBPROPSET_COLUMN
Type: VT_BOOL
Description: Autoincrement

Whether the values of the column are autoincrementing. One of the following:

VARIANT_TRUE—The values of the column are autoincrementing.

VARIANT_FALSE—The values of the column are not autoincrementing.

If this property is read-only, then whether or not a column is autoincrementing is a property of the datatype. If this property is read/write, then DBPROP_COL_AUTOINCREMENT can be specified for the column provided the AUTO_UNIQUE_VALUE property of the underlying datatype is VARIANT_TRUE in the PROVIDER_TYPES schema rowset.

DBPROP_COL_DEFAULT Property group: Column
Property set: DBPROPSET_COLUMN
Type: Any
Description: Default

A VARIANT specifying the default value for an object—typically a domain or column. If the default value is a string, the string must be quoted so it can be distinguished from an object of the same name. For example, 'Salary' is a string, but Salary is an object, such as a column.

DBPROP_COL_DESCRIPTION Property group: Column
Property set: DBPROPSET_COLUMN
Type: VT_BSTR
Description: Description

A string specifying a human-readable description of the specified column.

DBPROP_COL_FIXEDLENGTH Property group: Column
Property set: DBPROPSET_COLUMN
Type: VT_BOOL
Description: Fixed Length

Whether a column is fixed- or variable-length.

If the value of this property is VARIANT_TRUE, the column is fixed length and ulColumnSize in the DBCOLUMNDESC structure contains the fixed-length value. If the value of this property is VARIANT_FALSE or is not specified, the column is variable length and ulColumnSize represents the maximum size of the column.

DBPROP_COL_NULLABLE Property group: Column
Property set: DBPROPSET_COLUMN
Type: VT_BOOL
Description: Nullable

Whether a column can contain a NULL value. One of the following:

VARIANT_TRUE—The column can contain NULL values.

VARIANT_FALSE—The column cannot contain NULL values.

DBPROP_COL_PRIMARYKEY Property group: Column
Property set: DBPROPSET_COLUMN
Type: VT_BOOL
Description: Primary Key

Whether the column is part of the primary key. One of the following:

VARIANT_TRUE—The column is part of the primary key of the table.

VARIANT_FALSE—The column is not part of the primary key of the table.

DBPROP_COL_UNIQUE Property group: Column
Property set: DBPROPSET_COLUMN
Type: VT_BOOL
Description: Unique

Whether values of the column must be unique in the table. One of the following:

VARIANT_TRUE—The values of the column must be unique within the table.

VARIANT_FALSE—The values of the column can be repeated within the table.

DBPROP_COLUMNDEFINITION Property group: Data Source Information
Property set: DBPROPSET_DATASOURCEINFO
Type: VT_I4
Description: Column Definition

A bitmask defining the valid clauses for the definition of a column. A combination of zero or more of the following:

DBPROPVAL_CD_NOTNULL—Columns can be created non-nullable.

DBPROP_COLUMNLCID Property group: Column
Property set: DBPROPSET_COLUMN
Type: VT_I4
Description: Column LCID

The locale ID of the column.

DBPROP_COLUMNRESTRICT Property group: Rowset
Property set: DBPROPSET_ROWSET
Type: VT_BOOL
Description: Column Privileges

VARIANT_TRUE—Access rights are restricted on a column-by-column basis. If the rowset exposes IRowsetChange, IRowsetChange::SetData cannot be called for at least one column. A provider must not execute a query that would specify a column for which the consumer has no read access rights.

VARIANT_FALSE—Access rights are not restricted on a column-by-column basis. If the rowset exposes IRowsetChange, SetData can be called for any column in the rowset.

If access is restricted both by row and by column, then individual columns of particular rows might have their own stricter access rights: the consumer might not even be permitted to read such columns. The column values will be NULL. If a NULL value is contrary to schema rules (NULLs not permitted) then the rowset should not count or return any rows that would have this condition. For more information, see DBPROP_ROWRESTRICT.

DBPROP_COMMANDTIMEOUT Property group: Rowset
Property set: DBPROPSET_ROWSET
Type: VT_I4
Description: Command Time Out

The number of seconds before a command times out. A value of 0 indicates an infinite timeout.

DBPROP_COMMITPRESERVE Property group: Rowset
Property set: DBPROPSET_ROWSET
Type: VT_BOOL
Description: Preserve on Commit

VARIANT_TRUE—After committing a transaction, the rowset remains active. That is, it is possible to fetch new rows, update, delete, and insert rows, and so on.

VARIANT_FALSE—After committing a transaction, the only operations allowed on a rowset are to release row and accessor handles and to release the rowset.

DBPROP_CONCATNULLBEHAVIOR Property group: Data Source Information
Property set: DBPROPSET_DATASOURCEINFO
Type: VT_I4
Description: NULL Concatenation Behavior

How the data source handles the concatenation of NULL-valued character data type columns with non–NULL-valued character data type columns. One of the following:

DBPROPVAL_CB_NULL—The result is NULL valued.

DBPROPVAL_CB_NON_NULL—The result is the concatenation of the non–NULL-valued column or columns.

DBPROP_CONNECTIONSTATUS Property group: Data Source Information
Property set: DBPROPSET_DATASOURCEINFO
Type: VT_I4
Description: Connection Status

The status of the current connection. One of the following:

DBPROPVAL_CS_UNINITIALIZED—The DSO is in an uninitialized state.

DBPROPVAL_CS_INITIALIZED—The DSO is in an initialized state and able to communicate with the data store.

DBPROPVAL_CS_COMMUNICATIONFAILURE—The DSO is unable to communicate with the data store.

Some providers may have to silently spawn multiple connections to the database in order to support multiple concurrent Commands, Sessions, and Rowsets, according to DBPROP_MULTIPLECONNECTIONS. For such providers, DBPROP_CONNECTIONSTATUS refers to the status of the primary connection, which was created when the user called Initialize.

DBPROP_CURRENTCATALOG Property group: Data Source
Property set: DBPROPSET_DATASOURCE
Type: VT_BSTR
Description: Current Catalog

The name of the current catalog. The consumer can use the CATALOGS schema rowset to enumerate catalogs.

DBPROP_DATASOURCENAME Property group: Data Source Information
Property set: DBPROPSET_DATASOURCEINFO
Type: VT_BSTR
Description: Data Source Name

The name of the data source. This might be used during the connection process.

DBPROP_DATASOURCEREADONLY Property group: Data Source Information
Property set: DBPROPSET_DATASOURCEINFO
Type: VT_BOOL
Description: Read-Only Data Source

VARIANT_TRUE—The data source is read-only.

VARIANT_FALSE—The data source is updatable.

DBPROP_DBMSNAME Property group: Data Source Information
Property set: DBPROPSET_DATASOURCEINFO
Type: VT_BSTR
Description: DBMS Name

The name of the product accessed by the provider. For example, "ORACLE Server" or, for Microsoft® Excel®, "Excel".

DBPROP_DBMSVER Property group: Data Source Information
Property set: DBPROPSET_DATASOURCEINFO
Type: VT_BSTR
Description: DBMS Version

The version of the product accessed by the provider. The version is of the form ##.##.####, where the first two digits are the major version, the next two digits are the minor version, and the last four digits are the release version. The provider must render the product version in this form but can also append the product-specific version. For example, "04.01.0000 Rdb 4.1".

DBPROP_DEFERRED Property group: Rowset
Property set: DBPROPSET_ROWSET
Type: VT_BOOL
Description: Defer Column

VARIANT_TRUE—The data in the column is not fetched until an accessor is used on the column.

VARIANT_FALSE—The data in the column is fetched when the row containing it is fetched.

The value of this property is automatically set to VARIANT_TRUE if the value of the DBPROP_CACHEDEFERRED property is set to VARIANT_TRUE.

DBPROP_DELAYSTORAGEOBJECTS Property group: Rowset
Property set: DBPROPSET_ROWSET
Type: VT_BOOL
Description: Delay Storage Object Updates

In delayed update mode, if the value of this property is VARIANT_TRUE then storage objects are also used in delayed update mode. In particular:

  • Changes to the object are not transmitted to the data source until IRowsetUpdate::Update is called,

  • IRowsetUpdate::Undo undoes any pending changes, and

  • IRowsetUpdate::GetOriginalData retrieves the original value of the object; that is, the object's value when the row was last fetched or updated and excluding any changes made since then.

In delayed update mode, if the value of this property is VARIANT_FALSE, then storage objects are used in immediate update mode. In particular:

  • Changes to the object are immediately transmitted to the data source.

  • Update has no effect on the object.

  • Undo does not undo changes made to the object since the row was last fetched or updated.

  • GetOriginalData retrieves the current value of the object, including changes made since the row was last fetched or updated.

  • In immediate update mode, this property has no effect on storage objects.
DBPROP_DSOTHREADMODEL Property group: Data Source Information
Property set: DBPROPSET_DATASOURCEINFO
Type: VT_I4
Description: Data Source Object Threading Model

A bitmask specifying the threading models supported by the data source object. A combination of one or more of the following:

DBPROPVAL_RT_FREETHREAD
DBPROPVAL_RT_APTMTTHREAD
DBPROPVAL_RT_SINGLETHREAD

Note that the threading model returned in this property may be stricter than the thread model registered under the provider's CLSID in the case where additional threading limitations are imposed by underlying components.

DBPROP_FILTERCOMPAREOPS Property group: Rowset
Property set: DBPROPSET_ROWSET
Type: VT_I4
Description: Filter Operations

A bitmask describing the comparison operations supported by IViewFilter for a particular column. If no column is specified, this is the full set of comparison operators that may be supported:

DBPROPVAL_CO_EQUALITY — Provider supports the following comparison operators:
DBCOMPAREOPS_LT
DBCOMPAREOPS_LE
DBCOMPAREOPS_EQ
DBCOMPAREOPS_GE
DBCOMPAREOPS_GT
DBCOMPAREOPS_NE

DBPROPVAL_CO_STRING — Provider supports the following comparison operator:
DBCOMPAREOPS_BEGINSWITH

DBPROPVAL_CO_CONTAINS—Provider supports the following comparison operators:
DBCOMPAREOPS_CONTAINS
DBCOMPAREOPS_NOTCONTAINS

DBPROPVAL_CO_BEGINSWITH—Provider supports the following comparison operators:
DBCOMPAREOPS_BEGINSWITH
DBCOMPAREOPS_NOTBEGINSWITH

DBPROPVAL_CO_CASESENSITIVE — Provider supports the DBCOMPAREOPS_CASESENSITIVE modifier.

DBPROPVAL_CO_CASEINSENSITIVE — Provider supports the DBCOMPAREOPS_CASEINSENSITIVE modifier.

  • Providers may support one, or the other, or both of DBPROPVAL_CO_CASESENSITIVE and DBPROPVAL_CO_CASEINSENSITIVE.
DBPROP_FINDCOMPAREOPS Property group: Rowset
Property set: DBPROPSET_ROWSET
Type: VT_I4
Description: Find Operations

A bitmask describing the comparison operations supported by IRowsetFind for a particular column. If no column is specified, this is the full set of comparison operators that may be supported:

DBPROPVAL_CO_EQUALITY — Provider supports the following comparison operators:
DBCOMPAREOPS_LT
DBCOMPAREOPS_LE
DBCOMPAREOPS_EQ
DBCOMPAREOPS_GE
DBCOMPAREOPS_GT
DBCOMPAREOPS_NE

DBPROPVAL_CO_STRING — Provider supports the following comparison operators:
DBCOMPAREOPS_BEGINSWITH

DBPROPVAL_CO_CONTAINS—Provider supports the following comparison operators:
DBCOMPAREOPS_CONTAINS
DBCOMPAREOPS_NOTCONTAINS

DBPROPVAL_CO_BEGINSWITH—Provider supports the following comparison operators:
DBCOMPAREOPS_BEGINSWITH
DBCOMPAREOPS_NOTBEGINSWITH

DBPROPVAL_CO_CASESENSITIVE — Provider supports the DBCOMPAREOPS_CASESENSITIVE modifier.

DBPROPVAL_CO_CASEINSENSITIVE — Provider supports the DBCOMPAREOPS_CASEINSENSITIVE modifier.

All providers that support IRowsetFind must support DBPROPVAL_CO_EQUALITY and DBPROPVAL_CO_STRING.

Providers may support one, or the other, or both of DBPROPVAL_CO_CASESENSITIVE and DBPROPVAL_CO_CASEINSENSITIVE.

DBPROP_GROUPBY Property group: Data Source Information
Property set: DBPROPSET_DATASOURCEINFO
Type: VT_I4
Description: GROUP BY Support

The relationship between the columns in a GROUP BY clause and the nonaggregated columns in the select list. One of the following:

DBPROPVAL_GB_EQUALS_SELECT—The GROUP BY clause must contain all nonaggregated columns in the select list. It cannot contain any other columns. For example, SELECT DEPT, MAX(SALARY) FROM EMPLOYEE GROUP BY DEPT.

DBPROPVAL_GB_COLLATE—A COLLATE clause can be specified at the end of each grouping column.

DBPROPVAL_GB_CONTAINS_SELECT—The GROUP BY clause must contain all nonaggregated columns in the select list. It can contain columns that are not in the select list. For example, SELECT DEPT, MAX(SALARY) FROM EMPLOYEE GROUP BY DEPT, AGE.

DBPROPVAL_GB_NO_RELATION—The columns in the GROUP BY clause and the select list are not related. The meaning of nongrouped, nonaggregated columns in the select list is data source–dependent. For example, SELECT DEPT, SALARY FROM EMPLOYEE GROUP BY DEPT, AGE.

DBPROP_HETEROGENEOUSTABLES Property group: Data Source Information
Property set: DBPROPSET_DATASOURCEINFO
Type: VT_I4
Description: Heterogeneous Table Support

A bitmask specifying whether the provider can join tables from different catalogs or providers. A combination of zero or more of the following:

DBPROPVAL_HT_DIFFERENT_CATALOGS
DBPROPVAL_HT_DIFFERENT_PROVIDERS

DBPROP_IACCESSOR
DBPROP_ICHAPTEREDROWSET
DBPROP_ICOLUMNSINFO
DBPROP_ICOLUMNSROWSET
DBPROP_ICONNECTIONPOINTCONTAINER
DBPROP_ICONVERTTYPE
DBPROP_IDBASYNCHSTATUS
DBPROP_IMULTIPLERESULTS
DBPROP_IROWSET
DBPROP_IROWSETCHANGE
DBPROP_IROWSETFIND
DBPROP_IROWSETIDENTITY
DBPROP_IROWSETINDEX
DBPROP_IROWSETINFO
DBPROP_IROWSETLOCATE
DBPROP_IROWSETREFRESH
DBPROP_IROWSETRESYNCH
DBPROP_IROWSETSCROLL
DBPROP_IROWSETUPDATE
DBPROP_IROWSETVIEW
DBPROP_ISUPPORTERRORINFO 		Property group: Rowset
Property set: DBPROPSET_ROWSET

Type: VT_BOOL
(except as noted below)
Description:IAccessor
IChapteredRowset
IColumnsInfo
IColumnsRowset
IConnectionPointContainer
IConvertType
IDBAsynchStatus
IMultipleResults
IRowset
IRowsetChange
IRowsetFind
IRowsetIdentity
IRowsetIndex
IRowsetInfo
IRowsetLocate
IRowsetRefresh
IRowsetResynch
IRowsetScroll
IRowsetUpdate
IRowsetView
ISupportErrorInfo

If the value of any of these properties is set to VARIANT_TRUE, the rowset supports the specified interface. Providers that support an interface must support the property associated with that interface with a value of VARIANT_TRUE. These properties are primarily used to request interfaces through ICommandProperties::SetProperties.

The values of the DBPROP_IRowset, DBPROP_IAccessor, DBPROP_IColumnsInfo, DBPROP_IConvertType, and DBPROP_IRowsetInfo properties are read-only and are always VARIANT_TRUE. They cannot be set to VARIANT_FALSE. If the consumer does not set the value of any of these properties to true, the resulting rowset supports IRowset, IAccessor, IColumnsInfo, IConvertType, and IRowsetInfo.

Setting DBPROP_IRowsetLocate to VARIANT_TRUE implicitly causes the created rowset to support bookmarks and IRowsetInfo::GetProperties will return VARIANT_TRUE for the property DBPROP_BOOKMARKS. Setting DBPROP_IRowsetUpdate to VARIANT_TRUE automatically sets DBPROP_IRowsetChange to VARIANT_TRUE.

DBPROP_IDENTIFIERCASE Property group: Data Source Information
Property set: DBPROPSET_DATASOURCEINFO
Type: VT_I4
Description: Identifier Case Sensitivity

How identifiers treat case. One of the following:

DBPROPVAL_IC_UPPER—Identifiers in SQL are case insensitive and are stored in uppercase in system catalog.

DBPROPVAL_IC_LOWER—Identifiers in SQL are case insensitive and are stored in lowercase in system catalog.

DBPROPVAL_IC_SENSITIVE—Identifiers in SQL are case sensitive and are stored in mixed case in system catalog.

DBPROPVAL_IC_MIXED—Identifiers in SQL are case insensitive and are stored in mixed case in system catalog.

DBPROP_ILOCKBYTES
DBPROP_ISEQUENTIALSTREAM
DBPROP_ISTORAGE
DBPROP_ISTREAM 		Property group: Rowset
Property set: DBPROPSET_ROWSET
Type: VT_BOOL

Description:ILockBytes
ISequentialStream
IStorage
IStream

If the value of this property is set to VARIANT_TRUE, then the rowset is capable of manipulating the contents of columns as a storage object supporting the specified interface. The provider reports its ability to enable this property on a per-column basis by setting the flag DBPROPFLAGS_COLUMNOK. A provider that does not have the ability to turn the property on/off on a per-column basis, does not set DBPROPFLAGS_COLUMNOK. Regardless of whether the property is supported in the rowset as a whole or on a per-column basis, the ability to manipulate a column value as a storage object depends on whether the provider supports the coercion from the column's native type (BLOB or non-BLOB) to the particular storage interface.

DBPROP_IMMOBILEROWS Property group: Rowset
Property set: DBPROPSET_ROWSET
Type: VT_BOOL
Description: Immobile Rows

VARIANT_TRUE—The rowset will not reorder inserted or updated rows. For IRowsetChange::InsertRow, rows will appear at the end of the rowset.

VARIANT_FALSE—If the rowset is ordered, then inserted rows and updated rows (where one or more of the columns in the ordering criteria are updated) obey the ordering criteria of the rowset. If the rowset is not ordered, then inserted rows are not guaranteed to appear in a determinate position, and the position of updated rows is not changed.

This property is meaningful only if DBPROP_OWNINSERT is VARIANT_TRUE.

DBPROP_INDEX_AUTOUPDATE Property group: Index
Property set: DBPROPSET_INDEX
Type: VT_BOOL
Description: Auto-Update

Whether the index is maintained automatically when changes are made to the corresponding base table. One of the following:

VARIANT_TRUE—The index is automatically maintained.

VARIANT_FALSE—The index must be maintained by the consumer through explicit calls to IRowsetChange.

Ensuring consistency of the index as a result of updates to the associated base table is the responsibility of the consumer.

VARIANT_TRUE is always returned when using integrated indexes.

DBPROP_INDEX_CLUSTERED Property group: Index
Property set: DBPROPSET_INDEX
Type: VT_BOOL
Description: Clustered

Whether an index is clustered.

VARIANT_TRUE—The leaf nodes of the index contain full rows, not bookmarks. This is a way to represent a table clustered by key value.

VARIANT_FALSE—The leaf nodes of the index contain bookmarks of the base table rows whose key value matches the key value of the index entry.

DBPROP_INDEX_FILLFACTOR Property group: Index
Property set: DBPROPSET_INDEX
Type: VT_I4
Description: Fill Factor

For a B+-tree index, this property represents the storage utilization factor of page nodes during the creation of the index. The value is an integer from 1 to 100 representing the percentage of use of an index node. For a linear hash index, this property represents the storage utilization of the entire hash structure (the ratio of the used area to the total allocated area) before a file structure expansion occurs.

DBPROP_INDEX_INITIALSIZE Property group: Index
Property set: DBPROPSET_INDEX
Type: VT_I4
Description: Initial Size

The total number of bytes allocated to this structure at creation time.

DBPROP_INDEX_NULLCOLLATION Property group: Index
Property set: DBPROPSET_INDEX
Type: VT_I4
Description: NULL Collation

How NULLs are collated in the index. One of the following:

DBPROPVAL_NC_END—NULLs are collated at the end of the list, regardless of the collation order.

DBPROPVAL_NC_START—NULLs are collated at the start of the list, regardless of the collation order.

DBPROPVAL_NC_HIGH—NULLs are collated at the high end of the list.

DBPROPVAL_NC_LOW—NULLs are collated at the low end of the list.

DBPROP_INDEX_NULLS Property group: Index
Property set: DBPROPSET_INDEX
Type: VT_I4
Description: NULL Keys

Whether NULL keys are allowed. One of the following values:

DBPROPVAL_IN_DISALLOWNULL—The index does not allow entries where the key columns are NULL. If the consumer attempts to insert an index entry with a NULL key, then the provider returns an error.

DBPROPVAL_IN_IGNORENULL—The index does not insert entries containing NULL keys. If the consumer attempts to insert an index entry with a NULL key, then the provider ignores that entry and no error code is returned.

DBPROPVAL_IN_IGNOREANYNULL—The index does not insert entries where some column key has a NULL value. For an index having a multi-column search key, if the consumer inserts an index entry with NULL value in some column of the search key, then the provider ignores that entry and no error code is returned.

DBPROP_INDEX_PRIMARYKEY Property group: Index
Property set: DBPROPSET_INDEX
Type: VT_BOOL
Description: Primary Key

Whether the index represents the primary key on the table.

DBPROP_INDEX_SORTBOOKMARKS Property group: Index
Property set: DBPROPSET_INDEX
Type: VT_BOOL
Description: Sort Bookmarks

How the index treats repeated keys. One of the following:

VARIANT_TRUE—The index sorts repeated keys by bookmark.

VARIANT_FALSE—The index does not sort repeated keys by bookmark.

DBPROP_INDEX_TEMPINDEX Property group: Index
Property set: DBPROPSET_INDEX
Type: VT_BOOL
Description: Temporary Index

Whether the index is temporary. One of the following:

VARIANT_TRUE—The index is destroyed when the session is released.

VARIANT_FALSE—The index is created permanently.

DBPROP_INDEX_TYPE Property group: Index
Property set: DBPROPSET_INDEX
Type: VT_I4
Description: Index Type

The type of the index. One of the following:

DBPROPVAL_IT_BTREE—The index is a B+-tree.

DBPROPVAL_IT_HASH—The index is a hash file using linear or extensible hashing.

DBPROPVAL_IT_CONTENT—The index is a content index.

DBPROPVAL_IT_OTHER—The index is some other type of index.

DBPROP_INDEX_UNIQUE Property group: Index
Property set: DBPROPSET_INDEX
Type: VT_BOOL
Description: Unique

Whether index keys must be unique.

VARIANT_TRUE: The index keys must be unique.

VARIANT_FALSE: Duplicate keys are allowed.

DBPROP_INIT_ASYNCH Property group: Initialization
Property set: DBPROPSET_DBINIT
Type: VT_I4
Description: Asynchronous Processing

A bitmask specifying the asynchronous processing performed on the data source. A combination of zero or more of the following

DBPROPVAL_ASYNCH_INITIALIZE: IDBInitialize::Initialize returns immediately, but the actual initialization of the data source is done asynchronously. The data source behaves as an unititialized data source prior to completing the initialization process, except that any call to IDBInitialize returns E_UNEXPECTED.

If no bits are set (the default), IDBInitialize::Initialize does not return until the data source is completely initialized.

DBPROP_INIT_CATALOG Property group: Initialization
Property set: DBPROPSET_DBINIT
Description: Initial Catalog

The name of the initial, or default, catalog to use when connecting to the data source. If the provider supports changing the catalog for an initialized data source, the consumer can specify a different catalog name through the DBPROP_CURRENCATALOG property in the DBPROPSET_DATASOURCE property set after initialization.

DBPROP_INIT_DATASOURCE Property group: Initialization
Property set: DBPROPSET_DBINIT
Type: VT_BSTR
Description: Data Source

The name of the database or enumerator to connect to. DBPROP_INIT_DATASOURCE is used to identify the data source to connect to, for instance a relational database server or a local file. If the provider uses two-part naming to identify the data source, then the data source name is qualified with the location specified in DBPROP_INIT_DATASOURCE.

DBPROP_INIT_HWND Property group: Initialization
Property set: DBPROPSET_DBINIT
Type: VT_I4
Description: Window Handle

The window handle to be used if the data source object or enumerator needs to prompt for additional information.

DBPROP_INIT_IMPERSONATION_LEVEL Property group: Initialization
Property set: DBPROPSET_DBINIT
Type: VT_I4
Description: Impersonation Level

The level of impersonation that the server is allowed to use when impersonating the client. This property applies only to network connections other than Remote Procedure Call (RPC) connections; these impersonation levels are similar to those provided by RPC. The values of this property correspond directly to the levels of impersonation that can be specified for authenticated RPC connections, but can be applied to connections other than authenticated RPC. One of the following:

DB_IMP_LEVEL_ANONYMOUS—The client is anonymous to the server. The server process cannot obtain identification information about the client and cannot impersonate the client.

DB_IMP_LEVEL_IDENTIFY—The server can obtain the client's identity. The server can impersonate the client for ACL checking but cannot access system objects as the client.

DB_IMP_LEVEL_IMPERSONATE—The server process can impersonate the client's security context while acting on behalf of the client. This information is obtained when the connection is established, not on every call.

DB_IMP_LEVEL_DELEGATE—The process can impersonate the client's security context while acting on behalf of the client. The server process can also make outgoing calls to other servers while acting on behalf of the client.

DBPROP_INIT_LCID Property group: Initialization
Property set: DBPROPSET_DBINIT
Type: VT_I4
Description: Locale Identifier

The locale ID of preference for the consumer. Consumers specify the LCID at initialization. This provides a method for the server to determine the consumer's LCID of choice in cases where it can use this information. This property does not guarantee that all text returned to the consumer will be translated according to the LCID.

Providers may wish to set the dwOptions of the DBPROP structure for this property to DBPROPOPTIONS_OPTIONAL.

DBPROP_INIT_LOCATION Property group: Initialization
Property set: DBPROPSET_DBINIT
Type: VT_BSTR
Description: Location

The location of the data source or enumerator to connect to. Typically, this will be a server name. DBPROP_INIT_LOCATION is used as the first part of a two-part name to qualify the data source specified in the DBPROP_INIT_DATASOURCE property. For example, if the data source is defined on a different machine, this might be the machine name on which to look for the data source definition. This is typically not used if the provider can identify the data source using a single name, such as the name of an RDBMS server, that the consumer can use to identify the data source directly.

DBPROP_INIT_MODE Property group: Initialization
Property set: DBPROPSET_DBINIT
Type: VT_I4
Description: Mode

A bitmask specifying access permissions. A combination of zero or more of the following:

DB_MODE_READ—Read-only.

DB_MODE_WRITE—Write-only.

DB_MODE_READWRITE—Read/write (DB_MODE_READ | DB_MODE_WRITE).

DB_MODE_SHARE_DENY_READ—Prevents others from opening in read mode.

DB_MODE_SHARE_DENY_WRITE—Prevents others from opening in write mode.

DB_MODE_SHARE_EXCLUSIVE—Prevents others from opening in read/write mode (DB_MODE_SHARE_DENY_READ | DB_MODE_SHARE_DENY_WRITE).

DB_MODE_SHARE_DENY_NONE—Neither read nor write access can be denied to others.

DBPROP_INIT_OLEDBSERVICES Property group: Initialization
Property set: DBPROPSET_DBINIT
Type: VT_I4
Description: OLE DB Services

A bitmask specifying OLE DB services to enable. A combination of zero or more of the following:

DBPROPVAL_OS_RESOURCEPOOLING—Resources should be pooled.

DBPROPVAL_OS_TXNENLISTMENT—Sessions in an MTS environment should automatically be enlisted in a global transaction where required (implies DBPROPVAL_OS_RESOURCEPOOLING).

DBPROPVAL_OS_ENABLEALL (default)—All services should be invoked. By default, all services are enabled and invoked as requested. Individual services can be deselected by specifying the bitwise-OR of DBPROPVAL_OS_ENABLEALL along with the bitwise complement of any services to be deselected. For example, DBPROPVAL_OS_ENABLEALL | ~DBPROPVAL_OS_TXNENLISTMENT enables all services except automatic transaction enlistment in an MTS environment.

DBPROP_INIT_PROMPT Property group: Initialization
Property set: DBPROPSET_DBINIT
Type: VT_I2
Description: Prompt

Whether to prompt the user during initialization. One of the following values:

DBPROMPT_PROMPT—Always prompt the user for initialization information.

DBPROMPT_COMPLETE—Prompt the user only if more information is needed.

DBPROMPT_COMPLETEREQUIRED—Prompt the user only if more information is needed. Do not allow the user to enter optional information.

DBPROMPT_NOPROMPT—Do not prompt the user.

Information obtained from the user during prompting is available following initialization by calling GetProperties for the appropriate initialization properties.

DBPROP_INIT_PROTECTION_LEVEL Property group: Initialization
Property set: DBPROPSET_DBINIT
Type: VT_I4
Description: Protection Level

The level of protection of data sent between client and server. This property applies only to network connections other than RPC connections; these protection levels are similar to those provided by RPC. The values of this property correspond directly to the levels of protection that can be specified for authenticated RPC connections, but can be applied to connections other than authenticated RPC. One of the following:

DB_PROT_LEVEL_NONE—Performs no authentication of data sent to the server.

DB_PROT_LEVEL_CONNECT—Authenticates only when the client establishes the connection with the server.

DB_PROT_LEVEL_CALL—Authenticates the source of the data at the beginning of each request from the client to the server.

DB_PROT_LEVEL_PKT—Authenticates that all data received is from the client.

DB_PROT_LEVEL_PKT_INTEGRITY—Authenticates that all data received is from the client and that it has not been changed in transit.

DB_PROT_LEVEL_PKT_PRIVACY—Authenticates that all data received is from the client, that it has not been changed in transit, and protects the privacy of the data by encrypting it.

DBPROP_INIT_PROVIDERSTRING Property group: Initialization
Property set: DBPROPSET_DBINIT
Type: VT_BSTR
Description: Extended Properties

A string containing provider-specific, extended connection information. Use of this property implies that the consumer knows how this string will be interpreted and used by the provider. Consumers should use this property only for provider-specific connection information that cannot be explicitly described through the property mechanism.

DBPROP_INIT_TIMEOUT Property group: Initialization
Property set: DBPROPSET_DBINIT
Type: VT_I4
Description: Connect Timeout

The amount of time (in seconds) to wait for initialization to complete.

For maximum user concurrency and component interoperability, providers for whom initialization is a potentially lengthy operation, such as connection across a network, are strongly encouraged to support this property.

DBPROP_IVIEWCHAPTER
DBPROP_IVIEWFILTER
DBPROP_IVIEWROWSET
DBPROP_IVIEWSORT
DBPROP_IACCESSOR
DBPROP_ICOLUMNSINFO
DBPROP_ISUPPORTERRORINFO
 Property group: View
Property set: DBPROPSET_VIEW
Type: VT_BOOL

Description:IViewChapter
IViewFilter
IViewRowset
IViewSort
IAccessor
IColumnsInfo
ISupportErrorInfo

For all methods returning a Rowset or View object, in addition to Rowset properties, DBPROPSET_VIEW should be set before creating a view.

DBPROP_LITERALBOOKMARKS Property group: Rowset
Property set: DBPROPSET_ROWSET
Type: VT_BOOL
Description: Literal Bookmarks

VARIANT_TRUE—Bookmarks can be compared literally. That is, they can be compared as a sequence of bytes. Furthermore, if the bookmarks are ordered (as specified by the DBPROP_ORDEREDBOOKMARKS property), the bytes are guaranteed to be ordered so that an arithmetic comparison as their scalar type yields the same result as a call to IRowsetLocate::Compare. Setting the value of this property to VARIANT_TRUE automatically sets the value of DBPROP_BOOKMARKS to VARIANT_TRUE.

VARIANT_FALSE—Bookmarks can only be compared with IRowsetLocate::Compare.

DBPROP_LITERALIDENTITY Property group: Rowset
Property set: DBPROPSET_ROWSET
Type: VT_BOOL
Description: Literal Row Identity

VARIANT_TRUE—The consumer can perform a binary comparison of two row handles to determine whether they point to the same row.

VARIANT_FALSE—The consumer must call IRowsetIdentity::IsSameRow to determine whether two row handles point to the same row.

Whether the handle of a newly inserted row can be successfully compared to another handle is specified by the DBPROP_STRONGIDENTITY property.

DBPROP_LOCKMODE Property group: Rowset
Property set: DBPROPSET_ROWSET
Type: VT_I4
Description: Lock Mode

The level of locking peformed by the rowset. One of the following:

DBPROPVAL_LM_NONE—The provider is not required to lock rows at any time to ensure successful updates. Updates may fail when sent to the server for reasons of concurrency (for example, if someone else has updated the row).

DBPROPVAL_LM_SINGLEROW—The provider uses the minimum level of locking necessary to ensure that changes successfully written to a single row returned by the most recent fetch will not fail due to a concurrency violation if Update is called before any additional rows are retrieved. Typically this means that the provider takes a lock on the row when SetData is first called on the row, but the provider may lock the row as early as when it is read in order to guarantee that calling Update will succeed.

Lock Mode and Isolation Level are closely related, but distinct. A consumer's isolation level specifies the isolation of that consumer from changes made by other users to the underlying data. Lock mode defines when underlying data is locked in order to ensure updates succeed. The provider may use locking in order to enforce higher levels of isolation, in which case a higher level of locking may occur than required to enforce the specified lock mode. Lock mode specifies the minimum level of locking.

DBPROP_MAXINDEXSIZE Property group: Data Source Information
Property set: DBPROPSET_DATASOURCEINFO
Type: VT_I4
Description: Maximum Index Size

The maximum number of bytes allowed in the combined columns of an index. If there is no specified limit or the limit is unknown, this value is set to zero.

DBPROP_MAXOPENCHAPTERS Property group: Data Source Information
Property set: DBPROPSET_DATASOURCEINFO
Type: VT_I4
Description: Maximum Open Chapters

The maximum number of of chapters that can be open at any time.

If a chapter must be released before a new chapter can be opened, this value is one; if the provider does not support chapters, this value is zero.

DBPROP_MAXOPENROWS Property group: Rowset
Property set: DBPROPSET_ROWSET
Type: VT_I4
Description: Maximum Open Rows

The maximum number of rows that can be active at the same time. This limit does not reflect resource limitations such as RAM, but does apply if the rowset implementation uses some strategy that results in a limit. If there is no limit, the value of this property is zero. The provider is free to support a greater number of active rows than the maximum specified by the consumer. In this case, the provider will return its actual maximum number of active rows instead of the value specified by the consumer.

DBPROP_MAXORSINFILTER Property group: Data Source Information
Property set: DBPROPSET_DATASOURCEINFO
Type: VT_I4
Description: Maximum OR Conditions

The maximum number of disjunct conditions that can be supported in a view filter. Multiple conditions (rows) of a view filter are joined in a logical OR. Providers that do not support joining multiple conditions return a value of 1. Providers that do not support view filters return a value of 0.

This value applies only to the conditions that can be joined in a logical OR in a call to SetFilter; it does not imply the maximum number of OR conditions that may exist in a command.

DBPROP_MAXPENDINGROWS Property group: Rowset
Property set: DBPROPSET_ROWSET
Type: VT_I4
Description: Maximum Pending Rows

The maximum number of rows that can have pending changes at the same time. This limit does not reflect resource limitations such as Random Access Memory (RAM), but does apply if the rowset implementation uses some strategy that results in a limit. If there is no limit, this value is zero. The provider is free to support a greater number of pending rows than the maximum specified by the consumer. In this case, the provider will return its actual maximum number of pending rows instead of the value specified by the consumer.

DBPROP_MAXROWS Property group: Rowset
Property set: DBPROPSET_ROWSET
Type: VT_I4
Description: Maximum Rows

The maximum number of rows that can be returned in a rowset. If there is no limit, this value is zero. If the provider supports setting DBPROP_MAXROWS the provider must ensure that the rowset never contains more than the specified number of rows.

DBPROP_MAXROWSIZE Property group: Data Source Information
Property set: DBPROPSET_DATASOURCEINFO
Type: VT_I4
Description: Maximum Row Size

The maximum length of a single row in a table. If there is no specified limit or the limit is unknown, this value is set to zero.

DBPROP_MAXROWSIZEINCLUDESBLOB Property group: Data Source Information
Property set: DBPROPSET_DATASOURCEINFO
Type: VT_BOOL
Description: Maximum Row Size Includes BLOB

VARIANT_TRUE—The maximum row size returned for the DBPROP_MAXROWSIZE property includes the length of all BLOB data.

VARIANT_FALSE—The maximum row size does not include the length of all BLOB data.

DBPROP_MAXSORTCOLUMNS Property group: Data Source Information
Property set: DBPROPSET_DATASOURCEINFO
Type: VT_I4
Description: Maximum Sort Columns

The maximum number of columns that can be supported in a View Sort. If there is no specified limit or the limit is unknown, this value is set to zero.

This value applies only to the number of sort columns that can be specified in a call to SetSortOrder; it does not imply the maximum number of columns that can be used to sort in a command.

DBPROP_MAXTABLESINSELECT Property group: Data Source Information
Property set: DBPROPSET_DATASOURCEINFO
Type: VT_I4
Description: Maximum Tables in SELECT

The maximum number of tables allowed in the FROM clause of a SELECT statement. If there is no specified limit or the limit is unknown, this value is set to zero.

DBPROP_MAYWRITECOLUMN Property group: Rowset
Property set: DBPROPSET_ROWSET
Type: VT_BOOL
Description: Column Writable

Whether a particular column is writable or not. This property can be set implicitly through the command used to create the rowset. For example, if the rowset is created by the SQL statement SELECT A, B FROM MyTable FOR UPDATE OF A, then this property is VARIANT_TRUE for column A and VARIANT_FALSE for column B.

DBPROP_MEMORYUSAGE Property group: Rowset
Property set: DBPROPSET_ROWSET
Type: VT_I4
Description: Memory Usage

This property estimates the amount of memory that can be used by the rowset. If it is 0, the rowset can use unlimited memory. If it is between 1 and 99 inclusive, the rowset can use the specified percentage of total available virtual memory (physical and page file). If it is greater than or equal to 100, the rowset can use up to the specified number of kilobytes of memory.

DBPROP_MULTIPLECONNECTIONS Property group: Data Source
Property set: DBPROPSET_DATASOURCE
Type: VT_BOOL
Description: Multiple Connections

Some providers may have to spawn multiple connections to the database in order to support multiple concurrent Commands, Sessions, and Rowsets. Such providers may expose DBPROP_MULTIPLECONNECTIONS in order to let the consumer disable making additional connections under the covers. Providers that can support multiple concurrent Commands, Sessions, and Rowsets without spawning multiple connections do not support this property.

VARIANT_TRUE (default)—The provider silently creates additional connections as required in order to support concurrent Command, Session, and Rowset objects.

VARIANT_FALSE—The provider returns DB_E_OBJECTOPEN if a method would require spawning an additional connection to the database.

DBPROP_MULTIPLEPARAMSETS Property group: Data Source Information
Property set: DBPROPSET_DATASOURCEINFO
Type: VT_BOOL
Description: Multiple Parameter Sets

VARIANT_TRUE—The provider supports multiple parameter sets.

VARIANT_FALSE—The provider supports only a single set of parameters per execution.

All providers that support parameters must support this property. Providers that do not support parameters must not support this property.

DBPROP_MULTIPLERESULTS Property group: Data Source Information
Property set: DBPROPSET_DATASOURCEINFO
Type: VT_I4
Description: Multiple Results

A bitmask specifying whether the provider supports multiple results objects and what restrictions it places on these objects. A combination of zero or more of the following:

DBPROPVAL_MR_SUPPORTED—The provider supports multiple results objects.

DBPROPVAL_MR_CONCURRENT—More than one rowset created by the same multiple results object can exist concurrently. If this bit is not set, the consumer must release the current rowset before calling IMultipleResults::GetResult to get the next result.

If multiple results objects are not supported, DBPROPVAL_MR_NOTSUPPORTED is returned.

DBPROP_MULTIPLESTORAGEOBJECTS Property group: Data Source Information
Property set: DBPROPSET_DATASOURCEINFO
Type: VT_BOOL
Description: Multiple Storage Objects

VARIANT_TRUE—The provider supports multiple, open storage objects at the same time.

VARIANT_FALSE—The provider supports only one open storage object at a time. Any method that attempts to open a second storage object returns a status of DBSTATUS_E_CANTCREATE for the column on which it attempted to open the second storage object, regardless of whether the objects are constructed over the same column, different columns in the same row, or different rows.

DBPROP_MULTITABLEUPDATE Property group: Data Source Information
Property set: DBPROPSET_DATASOURCEINFO
Type: VT_BOOL
Description: Multi-Table Update

VARIANT_TRUE—The provider can update rowsets derived from multiple tables.

VARIANT_FALSE—The provider cannot update rowsets derived from multiple tables.

DBPROP_NOTIFICATIONGRANULARITY Property group: Rowset
Property set: DBPROPSET_ROWSET
Type: VT_I4
Description: Notification Granularity

DBPROPVAL_NT_SINGLEROW—For methods that operate on multiple rows, the provider calls IRowsetNotify::OnRowChange separately for each phase for each row. A cancellation affects a single row; it does not affect the other rows, and notifications are still sent for these rows.

DBPROPVAL_NT_MULTIPLEROWS—For methods that operate on multiple rows, then for each phase, the provider calls OnRowChange once for all rows that succeed and once for all rows that fail. This separation can occur at each phase where a change can fail. For example, if IRowsetChange::DeleteRows deletes some rows and fails to delete others during the Preliminary Work phase, it calls OnRowChange twice: once with DBEVENTPHASE_SYNCHAFTER and the array of handles of rows that it deleted, and once with DBEVENTPHASE_FAILEDTODO and the array of handles of rows it failed to delete. A cancellation affects all rows with handles that were passed to OnRowChange.

DBPROP_NOTIFICATIONGRANULARITY does not affect how providers return notifications about events that affect columns or the entire rowset.

DBPROP_NOTIFICATIONPHASES Property group: Rowset
Property set: DBPROPSET_ROWSET
Type: VT_I4
Description: Notification Phases

A bitmask specifying the notification phases supported by the provider. A combination of two or more of the following:

DBPROPVAL_NP_OKTODO
DBPROPVAL_NP_ABOUTTODO
DBPROPVAL_NP_SYNCHAFTER
DBPROPVAL_NP_FAILEDTODO
DBPROPVAL_NP_DIDEVENT

The DBPROPVAL_NP_FAILEDTODO and DBPROPVAL_NP_DIDEVENT bits must be returned by all providers that support notifications.

DBPROP_NOTIFYCOLUMNSET
DBPROP_NOTIFYROWDELETE
DBPROP_NOTIFYROWFIRSTCHANGE
DBPROP_NOTIFYROWINSERT
DBPROP_NOTIFYROWRESYNCH
DBPROP_NOTIFYROWSETRELEASE
DBPROP_NOTIFYROWSETFETCH-POSITIONCHANGE
DBPROP_NOTIFYROWUNDOCHANGE
DBPROP_NOTIFYROWUNDODELETE
DBPROP_NOTIFYROWUNDOINSERT
DBPROP_NOTIFYROWUPDATE 		Property group: Rowset
Property set: DBPROPSET_ROWSET
Type: VT_I4

Description:Column Set Notification
Row Delete Notification
Row First Change Notification
Row Insert Notification
Row Resynchronization Notification
Rowset Release Notification
Rowset Fetch Position Change Notification
Row Undo Change Notification
Row Undo Delete Notification
Row Undo Insert Notification
Row Update Notification

A bitmask specifying whether the notification phase is cancelable. A combination of zero or more of the following:

DBPROPVAL_NP_OKTODO
DBPROPVAL_NP_ABOUTTODO
DBPROPVAL_NP_SYNCHAFTER

DBPROP_NULLCOLLATION Property group: Data Source Information
Property set: DBPROPSET_DATASOURCEINFO
Type: VT_I4
Description: NULL Collation Order

Where NULLs are sorted in a list. One of the following:

DBPROPVAL_NC_END—NULLs are sorted at the end of the list, regardless of the sort order.

DBPROPVAL_NC_HIGH—NULLs are sorted at the high end of the list.

DBPROPVAL_NC_LOW—NULLs are sorted at the low end of the list.

DBPROPVAL_NC_START—NULLs are sorted at the start of the list, regardless of the sort order.

DBPROP_OLEOBJECTS Property group: Data Source Information
Property set: DBPROPSET_DATASOURCEINFO
Type: VT_I4
Description: OLE Object Support

A bitmask specifying the ways in which the provider supports access to BLOBs and OLE objects stored in columns. A combination of zero or more of the following:

DBPROPVAL_OO_BLOB—The provider supports access to BLOBs as structured storage objects. A consumer determines what interfaces are supported through DBPROP_STRUCTUREDSTORAGE.

DBPROPVAL_OO_IPERSIST—The provider supports access to OLE objects through IPersistStream, IPersistStreamInit, or IPersistStorage.

DBPROP_ORDERBYCOLUMNSINSELECT Property group: Data Source Information
Property set: DBPROPSET_DATASOURCEINFO
Type: VT_BOOL
Description: ORDER BY Columns in Select List

VARIANT_TRUE—Columns in an ORDER BY clause must be in the select list.

VARIANT_FALSE—Columns in an ORDER BY clause are not required to be in the select list.

DBPROP_ORDEREDBOOKMARKS Property group: Rowset
Property set: DBPROPSET_ROWSET
Type: VT_BOOL
Description: Bookmarks Ordered

VARIANT_TRUE—Bookmarks can be compared to determine the relative position of their associated rows in the rowset. Setting the value of this property to VARIANT_TRUE automatically sets the value of DBPROP_BOOKMARKS to VARIANT_TRUE.

VARIANT_FALSE—Bookmarks can only be compared for equality.

Whether bookmarks can be compared byte-by-byte or must be compared with IRowsetLocate::Compare depends on the value of the DBPROP_LITERALBOOKMARKS property.

DBPROP_OTHERINSERT Property group: Rowset
Property set: DBPROPSET_ROWSET
Type: VT_BOOL
Description: Others' Inserts Visible

VARIANT_TRUE—The rowset can see rows inserted by someone other than a consumer of the rowset. That is, if someone other than a consumer of the rowset inserts a row, any consumer of the rowset can see that row the next time it fetches a set of rows containing it. This includes rows inserted by other parties in the same transaction, as well as rows inserted by parties outside the transaction.

The transaction isolation level does not affect the ability of the rowset to see rows inserted by other parties in the same transaction, such as other rowsets in the same session. However, it does restrict the ability of the rowset to see rows inserted by parties outside the transaction.

VARIANT_FALSE—The rowset cannot see rows inserted by others.

For programmers accustomed to the cursor model in ODBC, the DBPROP_OTHERUPDATEDELETE and DBPROP_OTHERINSERT properties correspond to ODBC cursors as follows:

Static cursor:
DBPROP_OTHERINSERT = VARIANT_FALSE
DBPROP_OTHERUPDATEDELETE =
VARIANT_FALSE

Keyset-driven cursor:
DBPROP_OTHERINSERT = VARIANT_FALSE
DBPROP_OTHERUPDATEDELETE =
VARIANT_TRUE

Dynamic cursor:
DBPROP_OTHERINSERT = VARIANT_TRUE
DBPROP_OTHERUPDATEDELETE =
VARIANT_TRUE

Furthermore, the DBPROP_OWNUPDATEDELETE and DBPROP_OWNINSERT properties correspond to the values returned by the SQL_STATIC_SENSITIVITY information type in SQLGetInfo in ODBC.

DBPROP_OTHERUPDATEDELETE Property group: Rowset
Property set: DBPROPSET_ROWSET
Type: VT_BOOL
Description: Others' Changes Visible

VARIANT_TRUE—The rowset can see updates and deletes made by someone other than a consumer of the rowset. That is, suppose someone other than a consumer of the rowset updates the data underlying a row or deletes the row. If the row is released completely, any consumer of the rowset will see that change the next time it fetches the row. This includes updates and deletes made by other parties in the same transaction, as well as updates and deletes made by parties outside the transaction.

The transaction isolation level does not affect the ability of the rowset to see updates or deletes made by other parties in the same transaction, such as other rowsets in the same session. However, it does restrict the ability of the rowset to see updates or deletes made by parties outside the transaction.

VARIANT_FALSE—The rowset cannot see updates and deletes made by others.

For information about how this relates to the cursor types in ODBC, see the DBPROP_OTHERINSERT property.

DBPROP_OUTPUTPARAMETERAVAILABILITY Property group: Data Source Information
Property set: DBPROPSET_DATASOURCEINFO
Type: VT_I4
Description: Output Parameter Availability

The time at which output parameter values become available. One of the following:

DBPROPVAL_OA_NOTSUPPORTED—Output parameters are not supported.

DBPROPVAL_OA_ATEXECUTE—Output parameter data is available immediately after ICommand::Execute returns.

DBPROPVAL_OA_ATROWRELEASE—If a command returns a single result that is a rowset, output parameter data is available at the time the rowset is completely released. If a command returns multiple results, output parameter data is available when IMultipleResults::GetResult returns DB_S_NORESULT or the multiple results object is completely released, whichever occurs first. Before the output parameter data is available, the consumer's bound memory is in an indeterminate state.

DBPROP_OWNINSERT Property group: Rowset
Property set: DBPROPSET_ROWSET
Type: VT_BOOL
Description: Own Inserts Visible

VARIANT_TRUE—The rowset can see its own inserts. That is, if a consumer of a rowset inserts a row, any consumer of the rowset can see that row the next time it fetches a set of rows containing it.

This ability is independent of the transaction isolation level, because all consumers of the rowset share the same transaction.

VARIANT_FALSE—The rowset cannot see rows inserted by consumers of the rowset unless the command is re-executed.

For information about how this relates to the SQL_STATIC_SENSITIVITY information type in ODBC, see the DBPROP_OTHERINSERT property.

DBPROP_OWNUPDATEDELETE Property group: Rowset
Property set: DBPROPSET_ROWSET
Type: VT_BOOL
Description: Own Changes Visible

VARIANT_TRUE—The rowset can see its own updates and deletes. That is, suppose a consumer of the rowset updates or deletes a row. If the row is released completely, any consumer of the rowset will see the update or delete the next time it fetches that row.

This ability is independent of the transaction isolation level because all consumers of the rowset share the same transaction.

VARIANT_FALSE—The rowset cannot see updates and deletes made by consumers of the rowset unless the command is re-executed.

For information about how this relates to the SQL_STATIC_SENSITIVITY information type in ODBC, see the DBPROP_OTHERINSERT property.

DBPROP_PERSISTENTIDTYPE Property group: Data Source Information
Property set: DBPROPSET_DATASOURCEINFO
Type: VT_I4
Description: Persistent ID Type

An integer specifying the type of DBID that the provider uses when persisting DBIDs for tables, indexes, and columns. This is generally the type of DBID that the provider considers to be the most permanent under schema changes and physical data reorganizations. One of the following:

DBPROPVAL_PT_NAME
DBPROPVAL_PT_PROPID
DBPROPVAL_PT_GUID
DBPROPVAL_PT_GUID_NAME
DBPROPVAL_PT_GUID_PROPID
DBPROPVAL_PT_PGUID_NAME
DBPROPVAL_PT_PGUID_PROPID

DBPROP_PREPAREABORTBEHAVIOR Property group: Data Source Information
Property set: DBPROPSET_DATASOURCEINFO
Type: VT_I4
Description: Prepare Abort Behavior

How aborting a transaction affects prepared commands. One of the following:

DBPROPVAL_CB_DELETE—Aborting a transaction deletes prepared commands. The application must reprepare commands before executing them.

DBPROPAL_CB_PRESERVE—Aborting a transaction preserves prepared commands. The application can re-execute commands without repreparing them.

DBPROP_PREPARECOMMITBEHAVIOR Property group: Data Source Information
Property set: DBPROPSET_DATASOURCEINFO
Type: VT_I4
Description: Prepare Commit Behavior

How committing a transaction affects prepared commands. One of the following:

DBPROPVAL_CB_DELETE—Committing a transaction deletes prepared commands. The application must reprepare commands before executing them.

DBPROPAL_CB_PRESERVE—Committing a transaction preserves prepared commands. The application can re-execute commands without repreparing them.

DBPROP_PROCEDURETERM Property group: Data Source Information
Property set: DBPROPSET_DATASOURCEINFO
Type: VT_BSTR
Description: Procedure Term

A character string with the data source vendor's name for a procedure; for example, "database procedure", "stored procedure", or "procedure". This is used for building user interfaces.

DBPROP_PROVIDERFRIENDLYNAME Property group: Data Source Information
Property set: DBPROPSET_DATASOURCEINFO
Type: VT_BSTR
Description: Provider Friendly Name

The friendly name of the provider, for example "Microsoft OLE DB Provider for ODBC Drivers".

DBPROP_PROVIDERNAME Property group: Data Source Information
Property set: DBPROPSET_DATASOURCEINFO
Type: VT_BSTR
Description: Provider Name

The filename of the provider; for example, "MYPRVDR.DLL".

DBPROP_PROVIDEROLEDBVER Property group: Data Source Information
Property set: DBPROPSET_DATASOURCEINFO
Type: VT_BSTR
Description: OLE DB Version

The version of OLE DB supported by the provider. The version is of the form ##.##, where the first two digits are the major version and the next two digits are the minor version. For example, OLE DB providers conforming to the 1.5 specification would return "01.50".

DBPROP_PROVIDERVER Property group: Data Source Information
Property set: DBPROPSET_DATASOURCEINFO
Type: VT_BSTR
Description: Provider Version

The version of the provider. The version is of the form ##.##.####, where the first two digits are the major version, the next two digits are the minor version, and the last four digits are the release version. The provider can append a description of the provider.

This is the same as DBPROP_DBMSVER if the DBMS is the same as the provider; that is, if the DBMS supports OLE DB interfaces directly. It is different if the provider is separate from the DBMS, such as when the provider accesses the DBMS through ODBC.

DBPROP_QUICKRESTART Property group: Rowset
Property set: DBPROPSET_ROWSET
Type: VT_BOOL

Description: Quick Restart

VARIANT_TRUE—IRowset::RestartPosition is relatively quick to execute. In particular, it does not reexecute the command that created the rowset.

VARIANT_FALSE—RestartPosition is expensive to execute and requires reexecuting the command that created the rowset.

Although the value of this property can be set to VARIANT_TRUE, the provider is not required to honor it. The reason for this is that the provider does not know what the command is at the time the property is set; in particular, the consumer can set this property and then change the command text. However, the provider can fail this property if it is never able to quickly restart the next fetch position. Thus, if a consumer successfully sets this property, it must still check this flag on the rowset to determine if the next fetch position can be quickly set.

DBPROP_QUOTEDIDENTIFIERCASE Property group: Data Source Information
Property set: DBPROPSET_DATASOURCEINFO
Type: VT_I4
Description: Quoted Identifier Sensitivity

How quoted identifiers treat case. One of the following:

DBPROPVAL_IC_UPPER—Quoted identifiers in SQL are case insensitive and are stored in uppercase in system catalog.

DBPROPVAL_IC_LOWER—Quoted identifiers in SQL are case insensitive and are stored in lowercase in system catalog.

DBPROPVAL_IC_SENSITIVE—Quoted identifiers in SQL are case sensitive and are stored in mixed case in system catalog.

DBPROPVAL_IC_MIXED—Quoted identifiers in SQL are case insensitive and are stored in mixed case in system catalog.

DBPROP_REENTRANTEVENTS Property group: Rowset
Property set: DBPROPSET_ROWSET
Type: VT_BOOL
Description: Reentrant Events

VARIANT_TRUE—The provider supports reentrancy during callbacks to the IRowsetNotify interface. The provider might not support reentrancy on all rowset methods. These methods return DB_E_NOTREENTRANT.

VARIANT_FALSE—The provider does not support such reentrancy. The provider returns DB_E_NOTREENTRANT on methods called during the notification.

Regardless of this flag, all providers must support IRowset::GetData and IRowset::ReleaseRows calls during notifications, so long as the columns being accessed do not include deferred columns.

DBPROP_REMOVEDELETED Property group: Rowset
Property set: DBPROPSET_ROWSET
Type: VT_BOOL
Description: Remove Deleted Rows

If the value of this property is VARIANT_TRUE, the provider removes rows it detects as having been deleted from the rowset. That is, fetching a block of rows that formerly included a deleted row does not return a handle to that row.

Which rows the rowset detects as having been deleted is determined by the DBPROP_OWNUPDATEDELETE and DBPROP_OTHERUPDATEDELETE properties; whether the rowset removes these rows is determined by this property.

This property is independent of the transaction isolation level. While the transaction isolation level in some cases determines whether the rowset can detect a row as having been deleted, it has no effect on whether or not the rowset removes that row.

For programmers accustomed to the cursor model in ODBC, the value of this property is always VARIANT_TRUE for rowsets implemented through dynamic cursors; that is, dynamic cursors always remove deleted rows. Whether static and keyset-driven cursors remove deleted rows depends on the value of this property.

DBPROP_REPORTMULTIPLECHANGES Property group: Rowset
Property set: DBPROPSET_ROWSET
Type: VT_BOOL
Description: Report Multiple Changes

VARIANT_TRUE—An update or delete can affect multiple rows and the provider can detect that multiple rows have been updated or deleted. This happens when a provider cannot uniquely identify a row. For example, the provider might use the values of all the columns in the row to identify the row; if these columns do not include a unique key, an update or delete might affect more than one row.

VARIANT_FALSE—An update or delete always affects a single row or the provider cannot detect whether it affects multiple rows.

DBPROP_RESETDATASOURCE Property group: Data Source
Property set: DBPROPSET_DATASOURCE
Type: VT_I4
Description: Reset Datasource

A bitmask specifying the data source state to be reset. A combination of zero or more of the following:

DBPROPVAL_RD_RESETALL—The provider should reset all states associated with the data source, such that the DSO appears as if it were newly initialized, with the exception that any open object is not released.

DBPROP_RESETDATASOURCE is generally used by a consumer in order to reuse an existing data source object without paying the cost of uninitializing and reinitializing the DSO.

DBPROP_RETURNPENDINGINSERTS Property group: Rowset
Property set: DBPROPSET_ROWSET
Type: VT_BOOL
Description: Return Pending Inserts

VARIANT_TRUE—The methods that fetch rows, such as IRowset::GetNextRows, can return pending insert rows; that is, rows that have been inserted in delayed update mode but for which IRowsetUpdate::Update has not yet been called.

VARIANT_FALSE—The methods that fetch rows cannot return pending insert rows.

DBPROP_ROW_BULKOPS Property group: Rowset
Property set: DBPROPSET_ROWSET
Type: VT_14
Description: Bulk Operations

A bitmask describing optimizations that a provider may take for updates to the rowset. These optimizations are usually used for things like bulk loading of a table. The following values can be specified, and are usually set as OPTIONAL properties because they are hints to the provider. Additional bits may be defined in the future; providers should be prepared to handle new bits in this bitmask by ignoring them if the property is set as optional, or returning an error if the property is set as required.

DBPROPVAL_BO_NOLOG—The provider is not required to log inserts or changes to the rowset.

DBPROPVAL_BO_NOINDEXUPDATE—The provider is not required to update indexes based on inserts or changes to the rowset. Any indexes need to be re-created following changes made through the rowset.

DBPROPVAL_BO_REFINTEGRITY—Referential Integrity constraints do not need to be checked or enforced for changes made through the rowset.

DBPROP_ROWRESTRICT Property group: Rowset
Property set: DBPROPSET_ROWSET
Type: VT_BOOL
Description: Row Privileges

VARIANT_TRUE—Access rights are restricted on a row-by-row basis. If the rowset supports IRowsetChange, IRowsetChange::SetData can be called for some but not all rows. A rowset must never count or return a handle for a row for which the consumer does not have read access rights.

VARIANT_FALSE—Access rights are not restricted on a row-by-row basis. If the rowset supports IRowsetChange, SetData can be called for any row.

For more information, see DBPROP_COLUMNRESTRICT.

DBPROP_ROWSET_ASYNCH Property group: Rowset
Property set: DBPROPSET_ROWSET
Type: VT_I4
Description: Asynchronous Rowset Processing

A bitmask specifying the asynchronous processing performed on the rowset. A combination of zero or more of the following:

DBPROPVAL_ASNYCH_INITIALIZE: The rowset is initialized asynchronously. The method requesting the rowset returns immediately, but attempting to call any interface other than IConnectionPointContainer to obtain the IID_IDBAsynchNotify connection point may fail and the full set of interfaces may not be available on the rowset until asynchronous initialization has completed.

DBPROPVAL_ASNYCH_SEQUENTIALPOPULATION: The rowset is sequentially asynchronously populated; requests for rows may return DB_S_ENDOFROWSET before the end of the rowset is actually reached. Asynchronously populated rows are always added to the end of the rowset.

DBPROPVAL_ASNYCH_RANDOMPOPULATION: The rowset is randomly asynchronously populated; requests for rows may return DB_S_ENDOFROWSET before the end of the rowset is actually reached. Asynchronously populated rows may be inserted anywhere in the rowset.

The consumer may set both DBPROPVAL_ASNYCH_SEQUENTIALPOPULATION and DBPROPVAL_ASNYCH_RANDOMPOPULATION bits to request that the rowset be asynchronously populated either sequentially or randomly. The consumer is prepared for asynchronous notifications in OnRowChange as well as from IDBAsynchStatus. Only one property is returned by the rowset; if the rowset is asynchronously populated it returns either DBPROPVAL_ASNYCH_RANDOM or DBPROPVAL_ASNYCH_SEQUENTIAL.

If no bits are set (the default) the rowset is initialized and populated synchronously. All requested interfaces are available when the method requesting the rowset returns and requesting rows block until the requested number of hRows are obtained or the end of the rowset is reached.

DBPROPVAL_ASYNCH_BACKGROUNDPOPULATION: The rowset is to be populated asynchronously in the background. The rowset supports IDBAsynchStatus in order to get information about the population of the rowset or abort background population, and may support the connection point for IDBAsynchNotify to give status of the background population. DBPROPVAL_ASYNCH_BACKGROUNDPOPULATION is implied by DBPROPVAL_ASYNCH_SEQUENTIALPOPLUATION and DBPROPVAL_ASYNCH_RANDOMPOPULATION, however, if DBPROPVAL_ASYNCH_SEQUENTIALPOPLUATION or DBPROPVAL_ASYNCH_RANDOMPOPLUATION are not also set, the rowset appears to the consumer as if it were being populated synchronously in that requesting rows will always block until the requested number of hRows are obtained or the end of the rowset is reached.

DBPROPVAL_ASYNCH_PREPOPULATE: The consumer prefers to optimize for retrieving all data when the rowset is materialized. This is a hint to the provider to fetch all of the data up-front. DBPROPVAL_ASYNCH_PREPOPULATE is only a hint to the provider, the provider should never fail opening the rowset based on the setting of this flag, and need not return it to the consumer, even if the rowset is prepopulated.

DBPROPVAL_ASYNCH_POPULATEONDEMAND: The consumer prefers to optimize for getting each individual request for data returned as quickly as possible. This is a hint to the provider to populate the rowset as the data is fetched. DBPROPVAL_ASYNCH_POPULATEONDEMAND is only a hint to the provider, the provider should never fail opening the rowset based on the setting of this flag, and need not return it to the consumer, even if the rowset is populated on demand.

Since DBPROPVAL_ASYNCH_PREPOPULATE and DBPROPVAL_ANSYCH_POPULATEONDEMAND are just hints to the provider, if the consumer sets one or both of these properties in addition to the asychronous population properties DBPROPVAL_ASYNCH_SEQUENTIALPOPULATION or DBPROPVAL_ASYNCH_RANDOMPOPULATION, then the provider should attempt to populate asynchronously according to DBPROPVAL_ASYNCH_SEQUENTIALPOPULATION and DBPROPVAL_ASYNCH_RANDOMPOPULATION. If the asynchronous population specified by DBPROPVAL_ASYNCH_SEQUENTIALPOPULATION or DBPROPVAL_ASYNCH_RANDOMPOPULATION can not be supported, the provider should fail if DBPROPOPTIONS_REQUIRED was specified for the property, or attempt to populate synchronously according to DBPROPVAL_ASYNCH_PREPOPULATE or DBPROPVAL_ASYNCH_POPULATEONDEMAND if the property was set with DBPROPOPTIONS_OPTIONAL.

DBPROP_ROWSETCONVERSIONSONCOMMAND Property group: Data Source Information
Property set: DBPROPSET_DATASOURCEINFO
Type: VT_BOOL
Description: Rowset Conversions on Command

VARIANT_TRUE—Callers to IConvertType::CanConvert can inquire on a command about conversions supported on rowsets generated by the command.

VARIANT_FALSE—Callers can inquire on a command only about conversions supported by the command.

DBPROP_ROWTHREADMODEL Property group: Rowset
Property set: DBPROPSET_ROWSET
Type: VT_I4
Description: Row Threading Model

A bitmask specifying the threading models supported by the rowset. A combination of one or more of the following:

DBPROPVAL_RT_FREETHREAD
DBPROPVAL_RT_APTMTTHREAD
DBPROPVAL_RT_SINGLETHREAD

DBPROP_SCHEMATERM Property group: Data Source Information
Property set: DBPROPSET_DATASOURCEINFO
Type: VT_BSTR
Description: Schema Term

The name the data source uses for a schema; for example, "schema" or "owner". This is used for building user interfaces.

DBPROP_SCHEMAUSAGE Property group: Data Source Information
Property set: DBPROPSET_DATASOURCEINFO
Type: VT_I4
Description: Schema Usage

A bitmask specifying how schema names can be used in text commands. A combination of zero or more of the following:

DBPROPVAL_SU_DML_STATEMENTS—Schema names are supported in all Data Manipulation Language statements.

DBPROPVAL_SU_TABLE_DEFINITION—Schema names are supported in all table definition statements.

DBPROPVAL_SU_INDEX_DEFINITION—Schema names are supported in all index definition statements.

DBPROPVAL_SU_PRIVILEGE_DEFINITION—Schema names are supported in all privilege definition statements.

DBPROP_SERVERCURSOR Property group: Rowset
Property set: DBPROPSET_ROWSET
Type: VT_BOOL
Description: Server Cursor

If the value of this property is set to VARIANT_TRUE with ICommandProperties::SetProperties, the cursor underlying the rowset (if any) must be materialized on the server.

If the value of this property is not set to VARIANT_TRUE with ICommandProperties::SetProperties, it is up to the provider to decide where to materialize the cursor.

The consumer can determine where the cursor was materialized by checking the value of this property on the rowset.

DBPROP_SERVERDATAONINSERT Property group: Rowset
Property set: DBPROPSET_ROWSET
Type: VT_BOOL
Description: Server Data on Insert

VARIANT_TRUE—At the time an insert is transmitted to the server (when InsertRow is called in immediate mode, or when Update is called for an inserted row in deferred update mode), the provider retrieves data from the server to update the local row cache.

VARIANT_FALSE—The provider does not retrieve server values for newly inserted rows. The consumer can only retrieve data values explicitly set in the call to InsertRow, or by calls to SetData for the hRow returned by InsertRow.

Consumers should be aware that setting DBPROP_SERVERDATAONINSERT is potentially expensive, and may not be supported for certain types of rowsets.

DBPROP_SERVERNAME Property group: Datasource Information
Property set: DBPROPSET_DATASOURCEINFO
Type:VT_BSTR
Description: Server Name

The name of the server. This may be the same as the DBPROP_INIT_DATASOURCE property if the server name is used to define the data source that the user specifies when connecting, or may be the actual name of the server if the provider connects through "friendly" data source names.

DBPROP_SESS_AUTOCOMMITISOLEVELS Property group: Session
Property set: DBPROPSET_SESSION
Type: VT_I4
Description: Autocommit Isolation Levels

A bitmask specifying the transaction isolation level while in auto-commit mode. The values that can be set in this bitmask are the same as those that can be set for DBPROP_SUPPORTEDTXNISOLEVELS.

DBPROP_SORTONINDEX Property group: Data Source Information
Property set: DBPROPSET_DATASOURCEINFO
Type: VT_BOOL
Description: Sort on Index

VARIANT_TRUE: The provider supports SetSortOrder only for columns contained in an index.

VARIANT_FALSE: The provider does not require columns to be indexed in order to be specified in SetSortOrder, or the provider does not support SetSortOrder.

This value applies only to the ability to specify a column in SetSortOrder; it does not imply whether or not nonindexed columns can be used in the order clause of a command.

DBPROP_SQLSUPPORT Property group: Data Source Information
Property set: DBPROPSET_DATASOURCEINFO
Type: VT_I4
Description: SQL Support

A bitmask specifying the level of support for SQL. A combination of zero or more of the following:

DBPROPVAL_SQL_NONE—SQL is not supported.

DBPROPVAL_SQL_ODBC_MINIMUM
DBPROPVAL_SQL_ODBC_CORE
DBPROPVAL_SQL_ODBC_EXTENDED—These levels correspond to the levels of SQL conformance defined in ODBC version 2.5. These levels are cumulative. That is, if the provider supports one level, it also sets the bits for all lower levels. For example, if the provider sets the DBPROPVAL_SQL_ODBC_CORE bit, it also sets the DBPROPVAL_SQL_ODBC_MINIMUM bit.

DBPROPVAL_SQL_ESCAPECLAUSES—The provider supports the ODBC escape clause syntax.

DBPROPVAL_SQL_ANSI92_ENTRY
DBPROPVAL_SQL_FIPS_TRANSITIONAL
DBPROPVAL_SQL_ANSI92_INTERMEDIATE
DBPROPVAL_SQL_ANSI92_FULL—These levels correspond to the levels in ANSI SQL92. These levels are cumulative. That is, if the provider supports one level, it also sets the bits for all lower levels.

DBPROPVAL_SQL_ANSI89_IEF—The provider supports the ANSI89 Integrity Enhancement Facility.

DBPROPVAL_SQL_SUBMINIMUM—The provider supports the DBGUID_SQL dialect and parses the command text according to SQL rules, but does not support either the minimum ODBC level nor the ANSI SQL92 Entry level. This level is not accumulative; providers that support at least the minimal ODBC Level or ANSI SQL92 Entry Level do not set this bit. OLE DB consumers can determine whether or not the provider supports the DBGUID_SQL dialect by verifying that the DBPROPVAL_SQL_NONE bit is not set.

DBPROP_STRONGIDENTITY Property group: Rowset
Property set: DBPROPSET_ROWSET
Type: VT_BOOL
Description: Strong Row Identity

VARIANT_TRUE—The handles of newly inserted rows can be compared as specified by DBPROP_LITERALIDENTITY.

VARIANT_FALSE—There is no guarantee that the handles of newly inserted rows can be compared successfully. In this case, IRowsetIdentity::IsSameRow might return DB_E_NEWLYINSERTED.

A newly inserted row is defined as a row for which an insertion has been transmitted to the data source, as opposed to a pending insert row.

DBPROP_STRUCTUREDSTORAGE Property group: Data Source Information
Property set: DBPROPSET_DATASOURCEINFO
Type: VT_I4
Description: Structured Storage

A bitmask specifying what interfaces the rowset supports on storage objects. If a provider can support any of these interfaces it is also required to support ISequentialStream. A combination of zero or more of the following:

DBPROPVAL_SS_ISEQUENTIALSTREAM
DBPROPVAL_SS_ISTREAM
DBPROPVAL_SS_ISTORAGE
DBPROPVAL_SS_ILOCKBYTES

DBPROP_SUBQUERIES Property group: Data Source Information
Property set: DBPROPSET_DATASOURCEINFO
Type: VT_I4
Description: Subquery Support

A bitmask specifying the predicates in text commands that support subqueries. A combination of zero or more of the following:

DBPROPVAL_SQ_CORRELATEDSUBQUERIES
DBPROPVAL_SQ_COMPARISON
DBPROPVAL_SQ_EXISTS
DBPROPVAL_SQ_IN
DBPROPVAL_SQ_QUANTIFIED

The DBPROPVAL_SQ_CORRELATEDSUBQUERIES bit indicates that all predicates that support subqueries support correlated subqueries.

DBPROP_SUPPORTEDTXNDDL Property group: Data Source Information
Property set: DBPROPSET_DATASOURCEINFO
Type: VT_I4
Description: Transaction DDL

Whether Data Definition Language (DDL) statements are supported in transactions. One of the following:

DBPROPVAL_TC_NONE—Transactions are not supported.

DBPROPVAL_TC_DML—Transactions can only contain Data Manipulation Language (DML) statements. DDL statements within a transaction cause an error.

DBPROPVAL_TC_DDL_COMMIT—Transactions can only contain DML statements. DDL statements within a transaction cause the transaction to be committed.

DBPROPVAL_TC_DDL_IGNORE—Transactions can only contain DML statements. DDL statements within a transaction are ignored.

DBPROPVAL_TC_ALL—Transactions can contain DDL and DML statements in any order.

DBPROP_SUPPORTEDTXNISOLEVELS Property group: Data Source Information
Property set: DBPROPSET_DATASOURCEINFO
Type: VT_I4
Description: Isolation Levels

A bitmask specifying the supported transaction isolation levels. A combination of zero or more of the following:

DBPROPVAL_TI_CHAOS
DBPROPVAL_TI_READUNCOMMITTED
DBPROPVAL_TI_BROWSE
DBPROPVAL_TI_CURSORSTABILITY
DBPROPVAL_TI_READCOMMITTED
DBPROPVAL_TI_REPEATABLEREAD
DBPROPVAL_TI_SERIALIZABLE
DBPROPVAL_TI_ISOLATED

DBPROP_SUPPORTEDTXNISORETAIN Property group: Data Source Information
Property set: DBPROPSET_DATASOURCEINFO
Type: VT_I4
Description: Isolation Retention

A bitmask specifying the supported transaction isolation retention levels. A combination of zero or more of the following:

DBPROPVAL_TR_COMMIT_DC—The transaction may either preserve or dispose of isolation context across a retaining commit.

DBPROPVAL_TR_COMMIT—The transaction preserves its isolation context (that is, it preserves its locks, if that is how isolation is implemented) across a retaining commit.

DBPROPVAL_TR_COMMIT_NO—The transaction is explicitly not to preserve isolation across a retaining commit.

DBPROPVAL_TR_ABORT_DC—The transaction may either preserve or dispose of isolation context across a retaining abort.

DBPROPVAL_TR_ABORT—The transaction preserves its isolation context across a retaining abort.

DBPROPVAL_TR_ABORT_NO—The transaction is explicitly not to preserve isolation across a retaining abort.

DBPROPVAL_TR_DONTCARE—The transaction may preserve or dispose of isolation context across a retaining commit or abort. This is the default.

DBPROPVAL_TR_BOTH—Isolation is preserved across both a retaining commit and a retaining abort.

DBPROPVAL_TR_NONE—Isolation is explicitly not to be retained across either a retaining commit or abort.

DBPROPVAL_TR_OPTIMISTIC—Optimistic concurrency control is to be used. If DBPROPVAL_TR_OPTIMISTIC is specified, then whatever isolation technology is in place (such as locking), it must be the case that other transactions' ability to make changes to the data and resources manipulated by this transaction is not in any way affected by the data read or updated by this transaction. That is, optimistic control is to be used for all data in the transaction.

DBPROP_TABLETERM Property group: Data Source Information
Property set: DBPROPSET_DATASOURCEINFO
Type: VT_BSTR
Description: Table Term

The name the data source uses for a table; for example, "table" or "file". This is used for building user interfaces.

DBPROP_TBL_TEMPTABLE Property group: Table
Property set: DBPROPSET_TABLE
Type: VT_BOOL
Description: Temporary Table

Whether the table is temporary. One of the following:

VARIANT_TRUE—The table is destroyed when the session is released.

VARIANT_FALSE—The table is created permanently.

DBPROP_TRANSACTEDOBJECT Property group: Rowset
Property set: DBPROPSET_ROWSET
Type: VT_BOOL
Description: Objects Transacted

VARIANT_TRUE—Any object created on the specified column is transacted. That is, data made visible to the data source through the object can be committed with ITransaction::Commit or aborted with ITransaction::Abort.

VARIANT_FALSE—Any object created on the specified column is not transacted. That is, all changes to the object are permanent once they are made visible to the data source.

If this property is set on a column that does not contain an object, it is ignored.

DBPROP_UNIQUEROWS Property group: Rowset
Property set: DBPROPSET_ROWSET
Type: VT_BOOL
Description: UniqueRows

VARIANT_TRUE—Each row is uniquely identified by its column values.

VARIANT_FALSE—Rows in the rowset may or may not be uniquely identified by their column values.

If this property is set to VARIANT_TRUE when opening the rowset, the provider adds additional columns, if necessary, in order to ensure that each row is uniquely identified by its values. These additional columns appear at the end of the rowset, have a DBID of type DBKIND_GUID_PROPID, DBKIND_PGUID_PROPID, DBKIND_GUID_NAME, or DBKIND_PGUID_NAME, and the guid (or pguid) element is (or points to) DBCOL_SPECIALCOL. These columns are typically not displayed to the user, but are used by components such as update services to uniquely identify a row.

The provider may, but is not required to, duplicate existing columns in the rowset in order to make sure key columns are included.

If this property is set to VARIANT_TRUE, and the provider supports the optional IColumnsRowset metadata column DBCOLUMN_KEYCOLUMN, then the set of columns which uniquely identify the row have a value of VARIANT_TRUE in the DBCOLUMN_KEYCOLUMN column returned by IColumnsRowset. This may be a subset of the columns in the row, or all of the columns if the provider cannot determine a proper subset that uniquely identifies the row. If this property is not VARIANT_TRUE, then DBCOLUMN_KEYCOLUMN may or may not be set to VARIANT_TRUE for key columns, but there is no guarantee that the set of columns that are flagged with this value are sufficient in order to uniquely identify the row.

DBPROP_UPDATABILITY Property group: Rowset
Property set: DBPROPSET_ROWSET
Type: VT_I4
Description: Updatability

A bitmask specifying the supported methods on IRowsetChange. A combination of zero or more of the following:

DBPROPVAL_UP_CHANGE—SetData is supported.

DBPROPVAL_UP_DELETE—DeleteRows is supported.

DBPROPVAL_UP_INSERT—InsertRow is supported.

DBPROP_UPDATABILITY should be used in conjunction with DBPROP_IRowsetChange. If DBPROP_IRowsetChange is VARIANT_TRUE and DBPROP_UPDATABILITY is not set, then it is provider-specific what methods are supported on IRowsetChange.

If DBPROP_UPDATABILITY is specified, then the provider must not support any methods whose bits are not set.

DBPROP_USERNAME Property group: Data Source Information
Property set: DBPROPSET_DATASOURCEINFO
Type: VT_BSTR
Description: User Name

A character string with the name used in a particular database, which can be different than a login name.


Schemas Overview

Supported Schemas

Schema rowsets are identified by GUIDs. The following table lists these GUIDs and the columns for which restrictions can be specified on the schema rowset. The number of restriction columns for each schema rowset are defined as constants prefixed with CRESTRICTIONS_ in the header files. Restriction values are treated as literals rather than as search patterns. For example, the restriction value "A_C" matches "A_C" but not "ABC".

GUID | Number of restrictions | Restriction columns
DBSCHEMA_CATALOGS | 1 | CATALOG_NAME
DBSCHEMA_COLUMNS | 4 | TABLE_CATALOG TABLE_SCHEMA TABLE_NAME COLUMN_NAME
DBSCHEMA_CONSTRAINT_ COLUMN_USAGE | 7 | TABLE_CATALOG TABLE_SCHEMA TABLE_NAME COLUMN_NAME CONSTRAINT_CATALOG CONSTRAINT_SCHEMA CONSTRAINT_NAME
DBSCHEMA_CONSTRAINT_ TABLE_USAGE | 6 | TABLE_CATALOG TABLE_SCHEMA TABLE_NAME CONSTRAINT_CATALOG CONSTRAINT_SCHEMA CONSTRAINT_NAME
DBSCHEMA_FOREIGN_KEYS | 6 | PK_TABLE_CATALOG PK_TABLE_SCHEMA PK_TABLE_NAME FK_TABLE_CATALOG FK_TABLE_SCHEMA FK_TABLE_NAME
DBSCHEMA_INDEXES | 5 | TABLE_CATALOG TABLE_SCHEMA INDEX_NAME TYPE TABLE_NAME
DBSCHEMA_PRIMARY_KEYS | 3 | TABLE_CATALOG TABLE_SCHEMA TABLE_NAME
DBSCHEMA_PROVIDER_TYPES | 2 | DATA_TYPE BEST_MATCH
DBSCHEMA_REFERENTIAL_ CONSTRAINTS | 3 | CONSTRAINT_CATALOG CONSTRAINT_SCHEMA CONSTRAINT_NAME
DBSCHEMA_SCHEMATA | 3 | CATALOG_NAME SCHEMA_NAME SCHEMA_OWNER
DBSCHEMA_STATISTICS | 3 | TABLE_CATALOG TABLE_SCHEMA TABLE_NAME
DBSCHEMA_TABLE_CONSTRAINTS | 7 | CONSTRAINT_CATALOG CONSTRAINT_SCHEMA CONSTRAINT_NAME TABLE_CATALOG TABLE_SCHEMA TABLE_NAME CONSTRAINT_TYPE
DBSCHEMA_TABLES | 4 | TABLE_CATALOG TABLE_SCHEMA TABLE_NAME TABLE_TYPE


COLUMNS Rowset

The COLUMNS rowset identifies the columns of tables defined in the catalog that are accessible to a given user.

The COLUMNS rowset contains the following columns.

Column name | Type indicator | Description
TABLE_CATALOG | DBTYPE_WSTR | Catalog name. NULL if the provider does not support catalogs.
TABLE_SCHEMA | DBTYPE_WSTR | Unqualified schema name. NULL if the provider does not support schemas.
TABLE_NAME | DBTYPE_WSTR | Table name. This column cannot contain a NULL.
COLUMN_NAME DBTYPE_WSTR The name of the column; this might not be unique. If this cannot be determined, a NULL is returned.

This column, together with the COLUMN_GUID and COLUMN_PROPID columns, forms the column ID. One or more of these columns will be NULL depending on which elements of the DBID structure the provider uses.

If possible, the resulting column ID should be persistent. However, some providers do not support persistent identifiers for columns.

The column ID of a base table should be invariant under views.

COLUMN_GUID | DBTYPE_GUID | Column GUID. Providers that do not use GUIDs to identify columns should return NULL in this column.
COLUMN_PROPID | DBTYPE_UI4 | Column property ID. Providers that do not associate PROPIDs with columns should return NULL in this column.
ORDINAL_POSITION | DBTYPE_UI4 | The ordinal of the column. Columns are numbered starting from one. NULL if there is no stable ordinal value for the column.
COLUMN_HASDEFAULT DBTYPE_BOOL VARIANT_TRUE—The column has a default value.

VARIANT_FALSE—The column does not have a default value or it is unknown whether the column has a default value.

COLUMN_DEFAULT DBTYPE_WSTR Default value of the column. A provider may expose DBCOLUMN_DEFAULTVALUE but not DBCOLUMN_HASDEFAULT (for SQL92 tables) in the rowset returned by IColumnsRowset::GetColumnsRowset.

If the default value is the NULL value, COLUMN_HASDEFAULT is VARIANT_TRUE, and the COLUMN_DEFAULT column is a NULL value.

COLUMN_FLAGS | DBTYPE_UI4 | A bitmask that describes column characteristics. The DBCOLUMNFLAGS enumerated type specifies the bits in the bitmask. For information about DBCOLUMNFLAGS, see IColumnsInfo::GetColumnInfo. This column cannot contain a NULL value.
IS_NULLABLE DBTYPE_BOOL VARIANT_TRUE—The column might be nullable.

VARIANT_FALSE—The column is known not to be nullable.

DATA_TYPE | DBTYPE_UI2 | The indicator of the column's data type. If the data type of the column varies from row to row, this must be DBTYPE_VARIANT. This column cannot contain NULL.
TYPE_GUID | DBTYPE_GUID | The GUID of the column's data type. Providers that do not use GUIDs to identify data types should return NULL in this column.
CHARACTER_
MAXIMUM_LENGTH 		DBTYPE_UI4 The maximum possible length of a value in the column. For character, binary, or bit columns, this is one of the following:
  • The maximum length of the column in characters, bytes, or bits, respectively, if one is defined. For example, a CHAR(5) column in an SQL table has a maximum length of 5.

  • The maximum length of the data type in characters, bytes, or bits, respectively, if the column does not have a defined length.

  • Zero (0) if neither the column nor the data type has a defined maximum length.

NULL for all other types of columns.

CHARACTER_OCTET_
LENGTH 		DBTYPE_UI4 Maximum length in octets (bytes) of the column, if the type of the column is character or binary. A value of zero means the column has no maximum length. NULL for all other types of columns.
NUMERIC_PRECISION DBTYPE_UI2 If the column's data type is numeric, this is the maximum precision of the column. The precision of columns with a data type of DBTYPE_DECIMAL or DBTYPE_NUMERIC depends on the definition of the column.

If the column's data type is not numeric, this is NULL.

NUMERIC_SCALE | DBTYPE_I2 | If the column's type indicator is DBTYPE_DECIMAL or DBTYPE_NUMERIC, this is the number of digits to the right of the decimal point. Otherwise, this is NULL.
DATETIME_PRECISION | DBTYPE_UI4 | Datetime precision (number of digits in the fractional seconds portion) of the column if the column is a datetime or interval type. If the column's data type is not datetime, this is NULL.
CHARACTER_SET_
CATALOG 		DBTYPE_WSTR Catalog name in which the character set is defined. NULL if the provider does not support catalogs or different character sets.
CHARACTER_SET_
SCHEMA 		DBTYPE_WSTR Unqualified schema name in which the character set is defined. NULL if the provider does not support schemas or different character sets.
CHARACTER_SET_NAME | DBTYPE_WSTR | Character set name. NULL if the provider does not support different character sets.
COLLATION_CATALOG | DBTYPE_WSTR | Catalog name in which the collation is defined. NULL if the provider does not support catalogs or different collations.
COLLATION_SCHEMA | DBTYPE_WSTR | Unqualified schema name in which the collation is defined. NULL if the provider does not support schemas or different collations.
COLLATION_NAME | DBTYPE_WSTR | Collation name. NULL if the provider does not support different collations.
DOMAIN_CATALOG | DBTYPE_WSTR | Catalog name in which the domain is defined. NULL if the provider does not support catalogs or domains.
DOMAIN_SCHEMA | DBTYPE_WSTR | Unqualified schema name in which the domain is defined. NULL if the provider does not support schemas or domains.
DOMAIN_NAME | DBTYPE_WSTR | Domain name. NULL if the provider does not support domains.
DESCRIPTION | DBTYPE_WSTR | Human-readable description of the column. For example, the description for a column named Name in the Employee table might be "Employee name." Null if there is no description associated with the column.

Default Sort Order: TABLE_CATALOG, TABLE_SCHEMA, TABLE_NAME


PROVIDER_TYPES Rowset

The PROVIDER_TYPES rowset identifies the (base) data types supported by the data provider.

The PROVIDER_TYPES rowset contains the following columns.

Column name | Type indicator | Description
TYPE_NAME | DBTYPE_WSTR | Provider-specific data type name.
DATA_TYPE | DBTYPE_UI2 | The indicator of the data type.
COLUMN_SIZE DBTYPE_UI4 The length of a non-numeric column or parameter refers to either the maximum or the defined length for this type by the provider. For character data, this is the maximum or defined length in characters. For datetime data types, this is the length of the string representation (assuming the maximum allowed precision of the fractional seconds component).

If the data type is numeric, this is the upper bound on the maximum precision of the data type.

LITERAL_PREFIX | DBTYPE_WSTR | Character or characters used to prefix a literal of this type in a text command.
LITERAL_SUFFIX | DBTYPE_WSTR | Character or characters used to suffix a literal of this type in a text command.
CREATE_PARAMS DBTYPE_WSTR The creation parameters are specified by the consumer when creating a column of this data type. For example, the SQL data type DECIMAL needs a precision and a scale. In this case, the creation parameters might be the string "precision,scale". In a text command to create a DECIMAL column with a precision of 10 and a scale of 2, the value of the TYPE_NAME column might be DECIMAL() and the complete type specification would be DECIMAL(10,2).

The creation parameters appear as a comma-separated list of values, in the order they are to be supplied, with no surrounding parentheses. If a creation parameter is length, maximum length, precision, or scale, "length", "max length", "precision", and "scale" should be used, respectively. If the creation parameters are some other value, it is provider-specific what text is used to describe the creation parameter.

If the data type requires creation parameters, "()" generally appears in the type name. This indicates the position at which to insert the creation parameters. If the type name does not include "()", the creation parameters are enclosed in parentheses and appended to the end of the data type name.

IS_NULLABLE DBTYPE_BOOL VARIANT_TRUE—The data type is nullable.

VARIANT_FALSE—The data type is not nullable.

NULL—It is not known whether the data type is nullable.

CASE_SENSITIVE DBTYPE_BOOL VARIANT_TRUE—The data type is a character type and is case sensitive.

VARIANT_FALSE—The data type is not a character type or is not case sensitive.

SEARCHABLE DBTYPE_UI4 If the provider supports ICommandText, then this column is an integer indicating the searchability of a data type; otherwise, this column is NULL. One of the following:

DB_UNSEARCHABLE—The data type cannot be used in a WHERE clause.

DB_LIKE_ONLY—The data type can be used in a WHERE clause only with the LIKE predicate.

DB_ALL_EXCEPT_LIKE—The data type can be used in a WHERE clause with all comparison operators except LIKE.

DB_SEARCHABLE—The data type can be used in a WHERE clause with any comparison operator.
UNSIGNED_ATTRIBUTE DBTYPE_BOOL VARIANT_TRUE—The data type is unsigned.

VARIANT_FALSE—The data type is signed.

NULL—Not applicable to data type.

FIXED_PREC_SCALE DBTYPE_BOOL VARIANT_TRUE—The data type has a fixed precision and scale.

VARIANT_FALSE—The data type does not have a fixed precision and scale.

AUTO_UNIQUE_VALUE DBTYPE_BOOL VARIANT_TRUE—Values of this type can be autoincrementing.

VARIANT_FALSE—Values of this type cannot be autoincrementing.

If this value is VARIANT_TRUE, then whether a column of this type is always autoincrementing or not depends on the provider's DBPROP_COL_AUTOINCREMENT column property. If the DBPROP_COL_AUTOINCREMENT property is read/write, then whether or not a column of this type is autoincrementing depends on the setting of the DBPROP_COL_AUTOINCREMENT property. If DBPROP_COL_AUTOINCREMENT is a read-only property, then either all columns of this type are autoincrementing or they are all not.

LOCAL_TYPE_NAME | DBTYPE_WSTR | Localized version of TYPE_NAME. NULL is returned if a localized name is not supported by the data provider.
MINIMUM_SCALE | DBTYPE_I2 | If the type indicator is DBTYPE_DECIMAL or DBTYPE_NUMERIC, this is the minimum number of digits allowed to the right of the decimal point. Otherwise, this is NULL.
MAXIMUM_SCALE | DBTYPE_I2 | If the type indicator is DBTYPE_DECIMAL or DBTYPE_NUMERIC, this is the maximum number of digits allowed to the right of the decimal point. Otherwise, this is NULL.
GUID | DBTYPE_GUID | The GUID of the type. All types supported by a provider are described in a type library, so each type has a corresponding GUID.
TYPELIB | DBTYPE_WSTR | The type library containing the description of this type. All types supported by a provider, including those in Appendix A, are described in one or more type libraries.
VERSION | DBTYPE_WSTR | The version of the type definition. Providers may wish to version type definitions. Different providers may use different version schemes, such as a timestamp or number (integer or float). NULL if not supported.
IS_LONG DBTYPE_BOOL VARIANT_TRUE—The data type is a BLOB that contains very long data; the definition of very long data is provider-specific.

VARIANT_FALSE—The data type is a BLOB that does not contain very long data or is not a BLOB.

This value determines the setting of the DBCOLUMNFLAGS_ISLONG flag returned by GetColumnInfo in IColumnsInfo and GetParameterInfo in ICommandWithParameters.

BEST_MATCH DBTYPE_BOOL VARIANT_TRUE—The data type is the best match between all data types in the data source and the OLE DB data type indicated by the value in the DATA_TYPE column.

VARIANT_FALSE—The data type is not the best match.

For each set of rows in which the value of the DATA_TYPE column is the same, the BEST_MATCH column is set to VARIANT_TRUE in only one row.

IS_FIXEDLENGTH DBTYPE_BOOL VARIANT_TRUE—Columns of this type created by the DDL will be of fixed length.

VARIANT_FALSE—Columns of this type created by the DDL will be of variable length.

If the field is NULL, it is not known whether the provider will map this field with a fixed or variable length.

Default Sort Order: DATA_TYPE


TABLES Rowset

The TABLES rowset identifies the tables defined in the catalog that are accessible to a given user.

The TABLES rowset contains the following columns.

Column name | Type indicator | Description
TABLE_CATALOG | DBTYPE_WSTR | Catalog name. NULL if the provider does not support catalogs.
TABLE_SCHEMA | DBTYPE_WSTR | Unqualified schema name. NULL if the provider does not support schemas.
TABLE_NAME | DBTYPE_WSTR | Table name. This column cannot contain a NULL.
TABLE_TYPE | DBTYPE_WSTR | Table type. One of the following or a provider-specific value. "ALIAS" "TABLE" "SYNONYM" "SYSTEM TABLE" "VIEW" "GLOBAL TEMPORARY" "LOCAL TEMPORARY" This column cannot contain a Null.
TABLE_GUID | DBTYPE_GUID | GUID that uniquely identifies the table. Providers that do not use GUIDs to identify tables should return NULL in this column.
DESCRIPTION | DBTYPE_WSTR | Human-readable description of the table. Null if there is no description associated with the column.
TABLE_PROPID | DBTYPE_UI4 | Property ID of the table. Providers which do not use PROPIDs to identify columns should return NULL in this column.
DATE_CREATED | DBTYPE_DATE | Date when the table was created or NULL if the provider does not have this information. Note that 1.x providers do not return this column.
DATE_MODIFIED | DBTYPE_DATE | Date when the table definition was last modified or NULL if the provider does not have this information. Note that 1.x providers do not return this column.

Default Sort Order: TABLE_TYPE, TABLE_CATALOG, TABLE_SCHEMA, TABLE_NAME


CATALOGS Rowset

The CATALOGS rowset identifies the physical attributes associated with catalogs accessible from the DBMS. For some systems, such as Microsoft Access, there may be only one catalog. For Microsoft SQL Server, this rowset would enumerate all catalogs (databases) defined in the system database.

The CATALOGS rowset contains the following columns.

Column name | Type indicator | Description
CATALOG_NAME | DBTYPE_WSTR | Catalog name.
DESCRIPTION | DBTYPE_WSTR | Human-readable description of the table.

Default Sort Order: CATALOG_NAME


SCHEMATA Rowset

The SCHEMATA rowset identifies the schemas that are owned by a given user.

The SCHEMATA rowset contains the following columns.

Column name | Type indicator | Description
CATALOG_NAME | DBTYPE_WSTR | Catalog name. NULL if the provider does not support catalogs.
SCHEMA_NAME | DBTYPE_WSTR | Unqualified schema name.
SCHEMA_OWNER | DBTYPE_WSTR | User that owns the schemas.
DEFAULT_CHARACTER_ SET_CATALOG | DBTYPE_WSTR | Catalog name of the default character set for columns and domains in the schemas. NULL if the provider does not support catalogs or different character sets.
DEFAULT_CHARACTER_ SET_SCHEMA | DBTYPE_WSTR | Unqualified schema name of the default character set for columns and domains in the schemas. NULL if the provider does not support different character sets.
DEFAULT_CHARACTER_ SET_NAME | DBTYPE_WSTR | Default character set name. NULL if the provider does not support different character sets.

Default Sort Order: CATALOG_NAME, SCHEMA_NAME, SCHEMA_OWNER


STATISTICS Rowset

The STATISTICS rowset identifies the statistics defined in the catalog that are owned by a given user.

The STATISTICS rowset contains the following columns.

Column name | Type indicator | Description
TABLE_CATALOG | DBTYPE_WSTR | Catalog name. NULL if the provider does not support catalogs.
TABLE_SCHEMA | DBTYPE_WSTR | Unqualified schema name. NULL if the provider does not support schemas.
TABLE_NAME | DBTYPE_WSTR | Table name.
CARDINALITY | DBTYPE_UI8 | Cardinality (number of rows) of the table.

Default Sort Order: TABLE_CATALOG, TABLE_SCHEMA, TABLE_NAME


INDEXES Rowset

The INDEXES rowset identifies the indexes defined in the catalog that are owned by a given user.

The INDEXES rowset contains the following columns

Column name | Type indicator | Description
TABLE_CATALOG | DBTYPE_WSTR | Catalog name. NULL if the provider does not support catalogs.
TABLE_SCHEMA | DBTYPE_WSTR | Unqualified schema name. NULL if the provider does not support schemas.
TABLE_NAME | DBTYPE_WSTR | Table name.
INDEX_CATALOG | DBTYPE_WSTR | Catalog name. NULL if the provider does not support catalogs.
INDEX_SCHEMA | DBTYPE_WSTR | Unqualified schema name. NULL if the provider does not support schemas.
INDEX_NAME | DBTYPE_WSTR | Index name.
PRIMARY_KEY | DBTYPE_BOOL | Whether the index represents the primary key on the table. NULL if this is not known.
UNIQUE DBTYPE_BOOL Whether index keys must be unique. One of the following:

VARIANT_TRUE—The index keys must be unique.

VARIANT_FALSE—Duplicate keys are allowed.
CLUSTERED DBTYPE_BOOL Whether an index is clustered. One of the following:

VARIANT_TRUE—The leaf nodes of the index contain full rows, not bookmarks. This is a way to represent a table clustered by key value.

VARIANT_FALSE—The leaf nodes of the index contain bookmarks of the base table rows whose key value matches the key value of the index entry.
INTEGRATED DBTYPE_BOOL Whether the index is integrated (all base table columns are available from the index). One of the following:

VARIANT_TRUE—The index is integrated. For clustered indexes, this value must always be VARIANT_TRUE.

VARIANT_FALSE—The index is not integrated.
TYPE DBTYPE_UI2 The type of the index. One of the following:

DBPROPVAL_IT_BTREE—The index is a B+-tree.

DBPROPVAL_IT_HASH—The index is a hash file using, for example, linear or extensible hashing.

DBPROPVAL_IT_CONTENT—The index is a content index.

DBPROPVAL_IT_OTHER—The index is some other type of index.
FILL_FACTOR | DBTYPE_I4 | For a B+-tree index, this property represents the storage utilization factor of page nodes during the creation of the index. The value is an integer from 1 to 100 representing the percentage of use of an index node. For a linear hash index, this property represents the storage utilization of the entire hash structure (the ratio of used area to total allocated area) before a file structure expansion occurs.
INITIAL_SIZE | DBTYPE_I4 | The total amount of bytes allocated to this structure at creation time.
NULLS DBTYPE_I4 Whether null keys are allowed. One of the following:

DBPROPVAL_IN_DISALLOWNULL—The index does not allow entries where the key columns are NULL. If the consumer attempts to insert an index entry with a NULL key, then the provider returns an error.

DBPROPVAL_IN_IGNORENULL—The index does not insert entries containing NULL keys. If the consumer attempts to insert an index entry with a NULL key, then the provider ignores that entry and no error code is returned.

DBPROPVAL_IN_IGNOREANYNULL—The index does not insert entries where some column key has a NULL value. For an index having a multi-column search key, if the consumer inserts an index entry with NULL value in some column of the search key, then the provider ignores that entry and no error code is returned.
SORT_BOOKMARKS DBTYPE_BOOL How the index treats repeated keys. One of the following:

VARIANT_TRUE—The index sorts repeated keys by bookmark.

VARIANT_FALSE—The index does not sort repeated keys by bookmark.
AUTO_UPDATE DBTYPE_BOOL Whether the index is maintained automatically when changes are made to the corresponding base table. One of the following:

VARIANT_TRUE—The index is automatically maintained.

VARIANT_FALSE—The index must be maintained by the consumer through explicit calls to IRowsetChange. Ensuring consistency of the index as a result of updates to the associated base table is the responsibility of the consumer.
NULL_COLLATION DBTYPE_I4 How NULLs are collated in the index. One of the following:

DBPROPVAL_NC_END—NULLs are collated at the end of the list, regardless of the collation order.

DBPROPVAL_NC_START—NULLs are collated at the start of the list, regardless of the collation order.

DBPROPVAL_NC_HIGH—NULLs are collated at the high end of the list.

DBPROPVAL_NC_LOW—NULLs are collated at the low end of the list.
ORDINAL_POSITION | DBTYPE_UI4 | Ordinal position of the column in the index, starting with one.
COLUMN_NAME | DBTYPE_WSTR | Column name. This column, together with the COLUMN_GUID and COLUMN_PROPID columns, forms the column ID. One or more of these columns will be NULL depending on which elements of the DBID structure the provider uses.
COLUMN_GUID | DBTYPE_GUID | Column GUID.
COLUMN_PROPID | DBTYPE_UI4 | Column property ID.
COLLATION DBTYPE_I2 One of the following:

DB_COLLATION_ASC—The sort sequence for the column is ascending.

DB_COLLATION_DESC—The sort sequence for the column is descending.

NULL—A column sort sequence is not supported.
CARDINALITY | DBTYPE_UI8 | Number of unique values in the index.
PAGES | DBTYPE_I4 | Number of pages used to store the index.
FILTER_CONDITION | DBTYPE_WSTR | The WHERE clause identifying the filtering restriction.
INTEGRATED DBTYPE_BOOL Whether the index is integrated. That is, all base table columns are available from the index. One of the following:

VARIANT_TRUE—The index is integrated. For clustered indexes this value must always be VARIANT_TRUE.

VARIANT_FALSE—The index is not integrated.

This column is not returned by 1.x providers.

Default Sort Order: UNIQUE, TYPE, INDEX_CATALOG, INDEX_SCHEMA, INDEX_NAME, ORDINAL_POSITION


CONSTRAINT_COLUMN_USAGE Rowset

The CONSTRAINT_COLUMN_USAGE rowset identifies the columns used by referential constraints, unique constraints, check constraints, and assertions, defined in the catalog and owned by a given user.

The CONSTRAINT_COLUMN_USAGE rowset contains the following columns.

Column name | Type indicator | Description
TABLE_CATALOG | DBTYPE_WSTR | Catalog name in which the table is defined. NULL if the provider does not support catalogs.
TABLE_SCHEMA | DBTYPE_WSTR | Unqualified schema name in which the table is defined. NULL if the provider does not support schemas.
TABLE_NAME | DBTYPE_WSTR | Table name.
COLUMN_NAME | DBTYPE_WSTR | Column name. This column, together with the COLUMN_GUID and COLUMN_PROPID columns, forms the column ID. One or more of these columns will be NULL depending on which elements of the DBID structure the provider uses.
COLUMN_GUID | DBTYPE_GUID | Column GUID.
COLUMN_PROPID | DBTYPE_UI4 | Column property ID.
CONSTRAINT_CATALOG | DBTYPE_WSTR | Catalog name. NULL if the provider does not support catalogs.
CONSTRAINT_SCHEMA | DBTYPE_WSTR | Unqualified schema name. NULL if the provider does not support schemas.
CONSTRAINT_NAME | DBTYPE_WSTR | Constraint name.

Default Sort Order: TABLE_CATALOG, TABLE_SCHEMA, TABLE_NAME, COLUMN_NAME, COLUMN_GUID, COLUMN_PROPID, CONSTRAINT_CATALOG, CONSTRAINT_SCHEMA, CONSTRAINT_NAME


CONSTRAINT_TABLE_USAGE Rowset

The CONSTRAINT_TABLE_USAGE rowset identifies the tables that are used by referential constraints, unique constraints, check constraints, and assertions defined in the catalog and owned by a given user.

The CONSTRAINT_TABLE_USAGE rowset contains the following columns.

Column name | Type indicator | Description
TABLE_CATALOG | DBTYPE_WSTR | Catalog name in which the table is defined. NULL if the provider does not support catalogs.
TABLE_SCHEMA | DBTYPE_WSTR | Unqualified schema name in which the table is defined. NULL if the provider does not support schemas.
TABLE_NAME | DBTYPE_WSTR | Table name.
CONSTRAINT_CATALOG | DBTYPE_WSTR | Catalog name. NULL if the provider does not support catalogs.
CONSTRAINT_SCHEMA | DBTYPE_WSTR | Unqualified schema name. NULL if the provider does not support schemas.
CONSTRAINT_NAME | DBTYPE_WSTR | Constraint name.

Default Sort Order: TABLE_CATALOG, TABLE_SCHEMA, TABLE_NAME, CONSTRAINT_CATALOG, CONSTRAINT_SCHEMA, CONSTRAINT_NAME


TABLE_CONSTRAINTS Rowset

The TABLE_CONSTRAINTS rowset identifies the table constraints defined in the catalog that are owned by a given user.

The TABLE_CONSTRAINTS rowset contains the following columns.

Column name | Type indicator | Description
CONSTRAINT_CATALOG | DBTYPE_WSTR | Catalog name. NULL if the provider does not support catalogs.
CONSTRAINT_SCHEMA | DBTYPE_WSTR | Unqualified schema name. NULL if the provider does not support schemas.
CONSTRAINT_NAME | DBTYPE_WSTR | Constraint name.
TABLE_CATALOG | DBTYPE_WSTR | Catalog name in which the table is defined. NULL if the provider does not support catalogs.
TABLE_SCHEMA | DBTYPE_WSTR | Unqualified schema name in which the table is defined. NULL if the provider does not support schemas.
TABLE_NAME | DBTYPE_WSTR | Table name.
CONSTRAINT_TYPE | DBTYPE_WSTR | Constraint type. One of the following: "UNIQUE" "PRIMARY KEY" "FOREIGN KEY" "CHECK"
IS_DEFERRABLE | DBTYPE_BOOL | VARIANT_TRUE—The table constraint is deferrable. VARIANT_FALSE—The table constraint is not deferrable.
INITIALLY_DEFERRED | DBTYPE_BOOL | VARIANT_TRUE—The table constraint is initially deferred. VARIANT_FALSE—The table constraint is initially immediate.
DESCRIPTION | DBTYPE_WSTR | Human-readable description of the column

Default Sort Order: CONSTRAINT_CATALOG, CONSTRAINT_SCHEMA, CONSTRAINT_NAME, TABLE_CATALOG, TABLE_SCHEMA, TABLE_NAME, CONSTRAINT_TYPE


REFERENTIAL_CONSTRAINTS Rowset

The REFERENTIAL_CONSTRAINTS rowset identifies the referential constraints defined in the catalog that are owned by a given user.

The REFERENTIAL_CONSTRAINTS rowset contains the following columns.

Column name | Type indicator | Description
CONSTRAINT_CATALOG | DBTYPE_WSTR | Catalog name. NULL if the provider does not support catalogs.
CONSTRAINT_SCHEMA | DBTYPE_WSTR | Unqualified schema name. NULL if the provider does not support schemas.
CONSTRAINT_NAME | DBTYPE_WSTR | Constraint name.
UNIQUE_CONSTRAINT_ CATALOG | DBTYPE_WSTR | Catalog name in which the unique or primary key constraint is defined. NULL if the provider does not support catalogs.
UNIQUE_CONSTRAINT_ SCHEMA | DBTYPE_WSTR | Unqualified schema name in which the unique or primary key constraint is defined. NULL if the provider does not support schemas.
UNIQUE_CONSTRAINT_ NAME | DBTYPE_WSTR | Unique or primary key constraint name.
MATCH_OPTION | DBTYPE_WSTR | "NONE"—No <match type> was specified. "PARTIAL"—A <match type> of PARTIAL was specified. "FULL"—A <match type> of FULL was specified.
UPDATE_RULE | DBTYPE_WSTR | If an <update rule> was specified then the UPDATE_RULE value is one of the following: "CASCADE"—A <referential action> of CASCADE was specified. "SET NULL"—A <referential action> of SET NULL was specified. "SET DEFAULT"—A <referential action> of SET DEFAULT was specified. "NO ACTION"—A <referential action> of NO ACTION was specified.
DELETE_RULE | DBTYPE_WSTR | If a <delete rule> was specified, then the DELETE_RULE value is one of the following: "CASCADE"—A <referential action> of CASCADE was specified. "SET NULL"—A <referential action> of SET NULL was specified. "SET DEFAULT"—A <referential action> of SET DEFAULT was specified. "NO ACTION"—A <referential action> of NO ACTION was specified.
DESCRIPTION | DBTYPE_WSTR | Human-readable description of the constraint.

Default Sort Order: CONSTRAINT_CATALOG, CONSTRAINT_SCHEMA, CONSTRAINT_NAME, UNIQUE_CONSTRAINT_CATALOG, UNIQUE_CONSTRAINT_SCHEMA, UNIQUE_CONSTRAINT_NAME


PRIMARY_KEYS Rowset

The PRIMARY_KEYS rowset identifies the primary key columns defined in the catalog by a given user. This schema rowset is built upon an SQL92 schema view as a convenience to the non-SQL programmer, and, if supported, must be synchronized with the related SQL92 view (CONSTRAINT_COLUMN_USAGE).

The PRIMARY_KEYS rowset contains the following columns.

Column name | Type indicator | Description
PK_NAME | DB_WSTR | Primary key name. NULL if the provider does not support primary key constraints. This column is not returned by 1.x providers.
TABLE_CATALOG | DBTYPE_WSTR | Catalog name in which the table is defined. NULL if the provider does not support catalogs.
TABLE_SCHEMA | DBTYPE_WSTR | Unqualified schema name in which the table is defined. NULL if the provider does not support schemas.
TABLE_NAME | DBTYPE_WSTR | Table name.
COLUMN_NAME | DBTYPE_WSTR | Primary key column name. This column, together with the COLUMN_GUID and COLUMN_PROPID columns, forms the column ID. One or more of these columns will be NULL depending on which elements of the DBID structure the provider uses.
COLUMN_GUID | DBTYPE_GUID | Primary key column GUID.
COLUMN_PROPID | DBTYPE_UI4 | Primary key column property ID.
ORDINAL | DBTYPE_UI4 | The order of the column names (and GUIDs and property IDs) in the key.

Default Sort Order: TABLE_CATALOG, TABLE_SCHEMA, TABLE_NAME


FOREIGN_KEYS Rowset

The FOREIGN_KEYS rowset identifies the foreign key columns defined in the catalog by a given user. This schema rowset is built upon several SQL92 schema views as a convenience to the non-SQL programmer, and, if supported, this must be synchronized with the related SQL92 views (REFERENTIAL_CONSTRAINTS and CONSTRAINT_COLUMN_USAGE).

The FOREIGN_KEYS rowset contains the following columns

Column name | Type indicator | Description
PK_NAME | DBTYPE_WSTR | Primary key name. NULL if the provider does not support named primary key constraints. This column is not returned by 1.x providers.
PK_TABLE_CATALOG | DBTYPE_WSTR | Catalog name in which the primary key table is defined. NULL if the provider does not support catalogs.
PK_TABLE_SCHEMA | DBTYPE_WSTR | Unqualified schema name in which the primary key table is defined. NULL if the provider does not support schemas.
PK_TABLE_NAME | DBTYPE_WSTR | Primary key table name.
PK_COLUMN_NAME | DBTYPE_WSTR | Primary key column name. This column, together with the PK_COLUMN_GUID and PK_COLUMN_PROPID columns, forms the column ID. One or more of these columns will be NULL depending on which elements of the DBID structure the provider uses.
PK_COLUMN_GUID | DBTYPE_GUID | Primary key column GUID.
PK_COLUMN_PROPID | DBTYPE_UI4 | Primary key column property ID.
FK_NAME | DBTYPE_WSTR | Foreign key name. NULL if the provider does not support named foreign key constraints. This column is not returned by 1.x providers.
FK_TABLE_CATALOG | DBTYPE_WSTR | Catalog name in which the foreign key table is defined. NULL if the provider does not support catalogs.
FK_TABLE_SCHEMA | DBTYPE_WSTR | Unqualified schema name in which the foreign key table is defined. NULL if the provider does not support schemas.
FK_TABLE_NAME | DBTYPE_WSTR | Foreign key table name.
FK_COLUMN_NAME | DBTYPE_WSTR | Foreign key column name. This column, together with the FK_COLUMN_GUID and FK_COLUMN_PROPID columns, forms the column ID. One or more of these columns will be NULL depending on which elements of the DBID structure the provider uses.
FK_COLUMN_GUID | DBTYPE_GUID | Foreign key column GUID.
FK_COLUMN_PROPID | DBTYPE_UI4 | Foreign key column property ID.
ORDINAL | DBTYPE_UI4 | The order of the column names (and GUIDs and property IDs) in the key. For example, a table might contain several foreign key references to another table. The ordinal starts over for each reference; for example, two references to a three-column key would return 1, 2, 3, 1, 2, 3.
UPDATE_RULE | DBTYPE_WSTR | If an <update rule> was specified, then the UPDATE_RULE value is one of the following: "CASCADE"—A <referential action> of CASCADE was specified. "SET NULL"—A <referential action> of SET NULL was specified. "SET DEFAULT"—A <referential action> of SET DEFAULT was specified. "NO ACTION"—A <referential action> of NO ACTION was specified. Providers should return NULL only if they cannot determine the UPDATE_RULE. In most cases, this implies a default of NO ACTION.
DEFERRABILITY | DBTYPE_12 | Deferrability of the foreign key. Value is one of the following: DBPROPVAL_DF_INITIALLY_DEFERRED DBPROPVAL_DF_INITIALLY_IMMEDIATE DBPROPVAL_DF_NOT_DEFERRABLE This column is not returned by 1.x providers.
DELETE_RULE | DBTYPE_WSTR | If a <delete rule> was specified then the DELETE_RULE value is one of the following: "CASCADE"—A <referential action> of CASCADE was specified. "SET NULL"—A <referential action> of SET NULL was specified. "SET DEFAULT"—A <referential action> of SET DEFAULT was specified. "NO ACTION"—A <referential action> of NO ACTION was specified. Providers should return NULL only if they cannot determine the DELETE_RULE. In most cases, this implies a default of NO ACTION.

Default Sort Order: FK_TABLE_CATALOG, FK_TABLE_SCHEMA, FK_TABLE_NAME


'RowsetViewer' consumer

"Rowset viewer" - powerful OLE DB consumer, available from MS OLE DB SDK or from MS Data Access SDK. It can be used to work with data using OLE DB interface, for example, add and delete rows, change data, and so on. It also gives useful examples of the consumer's source code.

You can prepare RowsetViewer.exe file using nmake utility or from the Visual Studio environment (example includes rowsetviewer.mak file and VC++ 5 version rowsetviewer.dsp file).

To begin working with MySQL database
- Set "Provider" field of the dialog to "MySqlProv".
- Type server name and database name to "DataSource" field of FullConnect dialog
"MySqlProv Enumerator" to select available MySQL data base
- or set "Prompt" field to any value but DBPROMPT_NOPROMPT provider to ask you about data source to connect.
- Press OK.

To open a rowset, type
- table name to TableID field
- or owner name, then ".", then table name to TableID field
- or catalog name, then ".", then owner name, ".", and table name to TableID field
- or name of a named index to IndexID field
- or owner name, then ".", then name of a named index to IndexID field
- or catalog name, then ".", then owner name, ".", and name of a named index to IndexID field
- or name of a named index (with/out catalog and owner) to IndexID field and name of appropriate table (with/out catalog and owner) to TableID field
- or symbol "#" and index number to IndexID field and name of a table (with/out catalog and owner) to TableID field
- or words "Primary key" to IndexID field and name of a table (with/out catalog and owner) to TableID field

In your own applications, you may set DBID::eKind to DBKIND_NAME or DBKIND_PROPID to fill uName.pwszName or uName.ulPropId. You may use uName.ulPropId field to pass number of index, which does not have a name, to provider.
First index of a table has #0.

© 2000 SWsoft


Visual Samples for OLE DB Provider

Visual samples

We created some new visual samples how to use our OLE DB Provider within such applications as MS Office, Internet Explorer and Explorer.

All of these samples use ADO and RDS over OLE DB. Languages of samples are VBA, Java Script and Visual C++.

These samples are preliminary ones. We do not guarantee that they do not contain bugs.You may use them as a prototype for your own applications.

We will improve these samples in new releases.

List of samples

  • Excel sample demonstrates how to use provider and ADO within MS Office documents.
    You may connect to a MySQL server, open and change a table, open a query, disconnect from server.
    We recommend to change "AdoTable.xls" substring of AdoConnect.xls to "path\AdoTable.xls" in VBA editor.
    Try to type command text under table names. Try to type new value to Excel grid to change a records of a table.

  • HTML sample demonstrates local usage of RDS, which calls ADO and provider's functions.
    We recommend to wait several seconds after you press "Run!" button before pressing "Results" button
    Try to navigate through a query-based rowset with buttons. Try to click a row to change current record

© 2000 SWsoft


Sample Databases

MyOLEDB package includes scripts and a tool to reproduce a sample database. You will find them at Program Files\MyOLEDB\db directory.

Files Sample.sql and Sample2.sql contain scripts to recreate and fill tables Sample and Sample2.
Executable Db_Crt.exe allows to run these statements. You have to run the EXE file, set up necessary MySQL connection settings (server localhost and database test are default ones), then the program notifies you about start and completion of execution of the statement list. You have to run MySQL server prior to running the tool.
Files Form1.frm, Project1.vbp and Project1.vbw contain sources of Db_Crt tool.

If you want to change scripts, which the tool executes, you have to change tool's sources and recompile it in VB 6.

© 2000 SWsoft


Examples overview

Simple Consumer Test Suit is a small set of examples illustrating typical usage of MyOLEDB Provider: reading, appending, deleting, and so on. Examples from this Test Suit are based on Microsoft's Sample Client, available from MS OLE DB SDK or from MS Data Access SDK, and hence are keeping Microsoft's copyright information. All examples are console applications, all of them use a log file to output retrieved information.

In order to build examples from a Test Suit, you should tune up your system dependent information in the file testconf.h and then build an example from the Visual Studio environment, or you may use nmake utility. Examples from the Test Suit were not tested with non-Microsoft compilers.

It is recommended to change DEF_MYSQL_DIR difinition in "testconf.h" to set full (not relative) path to your MySQL database.
Or you could set DEF_MYSQL_DIR identifier value to a valid MyOLEDB data source name

© 2000 SWsoft


'Append' example

The "Append" example is a simple consumer application intended to illustrate how the MyOLEDB Provider could be used to add rows to a MySQL table. AppendData reads the first row from the table and then inserts this row into the same MySQL table 5 times. The main purpose of this test is to illustrate the IRowsetChange::InsertRow function.

By default this example uses "Sample2" table from the "DB\615" database included in OLE DB provider package.

To launch this test you should :

  1. Open the testconf.h file, using any appropriate editor.
  2. Change the DEF_MYSQL_DIR identifier value to reflect a valid MyOLEDB data source name
  3. Change the DEF_MYSQL_FILE identifier value to reflect the name of the table you are going to work with.
  4. Change the DEF_LOG_FILE_FULL_NAME identifier value to reflect the actual name of your log file.
  5. Prepare the sampclnt.exe file using a nmake utility or from the Visual Studio environment (example includes sampclnt.mak file and VC++ 5 version sampclnt.dsp file).

© 2000 SWsoft


'Delete' example

The "Delete" example: a simple consumer application intended to illustrate how the MyOLEDB Provider could be used to delete rows from the MySQL table. the "Delete" example deletes just first 5 rows from the MySQL table. The main purpose of this test is to illustrate the IRowsetChange::DeleteRows function.

By default this example uses "Sample2" table from the "DB\615" database included in OLE DB provider package

To launch this test you should :

  1. Open the testconf.h file using any appropriate editor.
  2. Change the DEF_MYSQL_DIR identifier value to reflect a valid MyOLEDB data source name
  3. Change the DEF_MYSQL_FILE identifier value to reflect the name of the table you are going to work with. (for example, this example uses a "Sample2" table from the "DB\615" database included in OLE DB provider package.)
  4. Change the DEF_LOG_FILE_FULL_NAME identifier value to reflect the actuall name of your log file.
  5. Prepare your sampclnt.exe file using a nmake utility or from the Visual Studio environment (example includes sampclnt.mak file and vc5 version sampclnt.dsp file).

© 2000 SWsoft


'Find' example

The "Find" example is a simple consumer application intended to illustrate how the MyOLEDB Provider could be used to retrieve data from a MySQL table. The main purpose of this example is to illustrate how to use the IRowsetFind::FindNextRow functions. This example implements the following sequence of actions:
1. Creates the accessor to bind column #0 (bookmark) in the rowset.
2. Uses the GetNextRows and GetData functions to get the value of a bookmark for the row #7.
3. Creates the accessor to bind column #1 in the rowset.
4. Then it calls GetNextRows (following by GetData) in order to fetch a value for column #1 from the row #7.
5. Calls FindNextRow. This function begins at the specified bookmark (from the steps 1,2) and find the next row matching the specified value (from the steps 3,4) using given criteria (DBCOMPAREOPS_EQ). Then FindNextRow fetch NUMROWS_CHUNK rows from this point.

The retrieved information is also stored in the log file.

By default this example uses "Sample2" table from the "DB\615" database included in OLE DB provider package

To launch this test you should :

  1. Open the testconf.h file using any appropriate editor.
  2. Change the DEF_MYSQL_DIR identifier value to reflect a valid MyOLEDB data source name
  3. Change the DEF_MYSQL_FILE identifier value to reflect the name of the table you are going to work with. (for example, this example uses a "Sample2" table from the "DB\615" database included in OLE DB provider package.)
  4. Change the DEF_LOG_FILE_FULL_NAME identifier value to reflect the actuall name of your log file.
  5. Prepare a sampclnt.exe file using a nmake utility or from the Visual Studio environment (this example includes sampclnt.mak file and VC++ 5 version sampclnt.dsp file)

© 2000 SWsoft


'Command.001' example

The "Command.001" example is a simple consumer application intended to illustrate how commands could be used in the MyOLEDB Provider to manipulate database structure and inserting data to a MySQL table with SQL statements. Example creates new table on MySQL database, adds a row there and then drops the table. The retrieved information is also stored in the log file. The main purpose of this example is to illustrate the usage of the ICommandText::SetCommandText and ICommand::Execute functions with CREATE TABLE, INSERT and DROP TABLE statements. By default this example creates table "Extra7" with 2 columns: a with integer values and b with string values.

To launch this test you should :

  1. Open the testconf.h file using any appropriate editor.
  2. Change the DEF_MYSQL_DIR identifier value to reflect a valid MyOLEDB data source name
  3. Change the DEF_LOG_FILE_FULL_NAME identifier value to reflect the actuall name of your log file.
  4. Open the sampcInt.h file using any appropriate editor and find Queries section.
  5. Change table name in TEST_TABLE and LTEST_TABLE definitions if necessary.
  6. Change query definitions CREATE_TABLE_QUERY, INSERT_ROW_QUERY or DROP_TABLE_QUERY if you want. (It is usually unnecessary.)
  7. Prepare the sampclnt.exe file using a nmake utility or from the Visual Studio environment (example includes VC++ 6 version sampclnt.dsp file).

© 2000 SWsoft


'Command.002' example

The "Command.002" example is a simple consumer application intended to illustrate how commands could be used in the MyOLEDB Provider to read data from MySQL tables via commands. Example creates rowset based on MySQL table, on which some conditions are applied, and retrieves sequentially rows from it. The retrieved information is also stored in the log file. The main purpose of this example is to illustrate the usage of the ICommand::SetCommandText and ICommand::Execute functions with SELECT ... FROM ...WHERE statement. By default this example uses "Sample2" table from the "DB\615" database included in OLE DB provider package.

To launch this test you should :

  1. Open the testconf.h file using any appropriate editor.
  2. Change the DEF_MYSQL_DIR identifier value to reflect a valid MyOLEDB data source name
  3. Change the DEF_LOG_FILE_FULL_NAME identifier value to reflect the actuall name of your log file.
  4. Open the sampcInt.h file using any appropriate editor and find Queries section.
  5. Change the SELECT_QUERY definition to reflect the name of the table and rowset conditions you are going to work with. (For instance, this example use "Sample2" table from the "DB\615" database and condition "ID BETWEEN 220000000 AND 300000000")
  6. Prepare the sampclnt.exe file using a nmake utility or from the Visual Studio environment (example includes VC++ 6 version sampclnt.dsp file).

© 2000 SWsoft


'Locate.001' example

The "Locate001" example is a simple consumer application intended to illustrate how the MyOLEDB Provider could be used to retrieve data from a MySQL table. The main purpose of this example is to illustrate how to use the IRowsetLocate::GetRowsAt functions.
IRowsetLocate::GetRowsAt determines a starting position for the fetch as the bookmark, plus the offset (10 rows in this example), then retrieves backwards with the NUMROWS_CHUNK rows. In this example we get bookmark for row #15. The retrieved information is also stored in the log file.

By default this example uses "Sample" table from the "DB\615" database included in OLE DB provider package

To launch this test you should :

  1. Open the testconf.h file using any appropriate editor.
  2. Change the DEF_MYSQL_DIR identifier value to reflect a valid MyOLEDB data source name
  3. Change the DEF_MYSQL_FILE_MORE identifier value to reflect the name of the table you are going to work with. (for example, this example uses a "Sample" table from the "DB\615" database included in OLE DB provider package.)
  4. Change the DEF_LOG_FILE_FULL_NAME identifier value to reflect the actuall name of your log file.
  5. Prepare the sampclnt.exe file using a nmake utility or from the Visual Studio environment (an example includes sampclnt.mak file and VC++ 5 version sampclnt.dsp file).

© 2000 SWsoft


'Locate.002' example

The "Locate002" example is a simple consumer application intended to illustrate how MyOLEDB Provider could be used to retrieve data from MySQL table. This example reads and retrieves 10 rows in the rowset according with their bookmarks. The retrieved information is also stored in the log file. The main purpose of this test is to illustrate the IRowsetLocate::GetRowsByBookmark functions.

By default this example uses "Sample" table from the "DB\615" database included in OLE DB provider package

To launch this test you should :

  1. Open the testconf.h file using any appropriate editor.
  2. Change the DEF_MYSQL_DIR identifier value to reflect a valid MyOLEDB data source name
  3. Change the DEF_MYSQL_FILE_MORE identifier value to reflect the name of the table you are going to work with. (This example uses a "Sample" table from the "DB\615" database included in OLE DB provider package)
  4. Change the DEF_LOG_FILE_FULL_NAME identifier value to reflect the actual name of your log file.
  5. Prepare the sampclnt.exe file using a nmake utility or from the Visual Studio environment (example includes sampclnt.mak file and VC++ 5 version sampclnt.dsp file).

© 2000 SWsoft


'Read.001' example

The "Read.001" example is a simple consumer application intended to illustrate how the MyOLEDB Provider could be used to read data from the MySQL table. It simply retrieves sequentially rows from the MySQL table. The retrieved information is also stored in the log file. The main purpose of this example is to illustrate the usage of the IRowset::GetNextRows, IRowset::GetData and IRowset::ReleaseRows functions. By default this example uses "Sample2" table from the "DB\615" database included in OLE DB provider package.

To launch this test you should :

  1. Open the testconf.h file using any appropriate editor.
  2. Change the DEF_MYSQL_DIR identifier value to reflect a valid MyOLEDB data source name
  3. Change the DEF_MYSQL_FILE identifier value to reflect the name of the table you are going to work with. (for example, this example uses a "Sample2" table from the "DB\615" database included in OLE DB provider package.)
  4. Change the DEF_LOG_FILE_FULL_NAME identifier value to reflect the actuall name of your log file.
  5. Prepare the sampclnt.exe file using a nmake utility or from the Visual Studio environment (example includes sampclnt.mak file and VC++ 5 version sampclnt.dsp file)

© 2000 SWsoft


'Read.002' example

The "Read.002" example is a simple consumer application intended to illustrate how the MyOLEDB Provider could be used to read data from a MySQL table. GetNextRows is called 3 times in this example: the first time - it retrieves first 3 rows, second time - it skip 3 rows backwards and then retrieves NUMROWS_CHUNK rows forwards, third time - it retrieves the NUMROWS_CHUNK rows, backwards. Only after performing all that calls application calls ReleaseRows to release row handles. The retrieved information is also stored in the log file. The main purpose of this application is to show how consumer can use the IRowset::GetNextRows, IRowset::GetData and IRowset::ReleaseRows functions and provider's DBPROP_CANHOLDROWS, DBPROP_CANSCROLLBACKWARDS, DBPROP_CANFETCHBACKWARDS rowset behavior. By default this example uses "Sample2" table from the "DB\615" database included in OLE DB provider package.

To launch this test you should :

  1. Open the testconf.h file using any appropriate editor.
  2. Change the DEF_MYSQL_DIR identifier value to reflect a valid MyOLEDB data source name
  3. Change the DEF_MYSQL_FILE identifier value to reflect the name of the table you are going to work with. (for example, this example uses a "Sample2" table from the "DB\615" database included in OLE DB provider package).
  4. Change the DEF_LOG_FILE_FULL_NAME identifier value to reflect the actuall name of your log file.
  5. Prepare the sampclnt.exe file using a nmake utility or from the Visual Studio environment (example includes a sampclnt.mak file and VC++ 5 version sampclnt.dsp file).

© 2000 SWsoft


'Schema' example

The "Schema" example is a simple consumer application intended to illustrate how the MyOLEDB Provider could be used to learn schemas of MySQL database. Provider supports 3 schemas: schema of tables (DBSCHEMA_TABLES), schema of columns (DBSCHEMA_COLUMNS), and schema of supported data types (DBSCHEMA_PROVIDER_TYPES). Such information is stored in MySQL system tables.

Provider prepares and retrieves schema information, row by row. Consumer may use schema rowset as every read-only rowset. The retrieved information is also stored in the log file.

The main purpose of this example is to illustrate the usage of the IDBSchemaRowset::GetRowset, and also IRowset::GetNextRows, IRowset::GetData and IRowset::ReleaseRows functions. You need not use any table in this sample.

To launch this test you should :

  1. Open the testconf.h file using any appropriate editor.
  2. Change the DEF_MYSQL_DIR identifier value to reflect a valid MyOLEDB data source name
  3. Change the DEF_LOG_FILE_FULL_NAME identifier value to reflect the actuall name of your log file.
  4. Build the sampclnt.exe file using a nmake utility or from the Visual Studio environment (example includes VC++ 6 version sampclnt.dsp file).

© 2000 SWsoft


'Scroll' example

The "Scroll" example is a simple consumer application intended to illustrate how the MyOLEDB Provider could be used to retrieve data from a MySQL table. This example calls IRowsetScroll::GetRowsAtRatio function which determines starting position for the fetch using the ulNominator/ulDenominator values and then retrieves rows forward. The retrieved information is also stored in the log file.
The main purpose of this test is to illustrate the IRowsetScroll::GetRowsAtRatio functions.

By default this example uses the "Sample2" table from "DB\615" database included in MyOLEDB Provider package.

To launch this test you should :

  1. Open the testconf.h file using any appropriate editor.
  2. Change the DEF_MYSQL_DIR identifier value to reflect a valid MyOLEDB data source name
  3. Change the DEF_MYSQL_FILE identifier value to reflect the name of the table you are going to work with. (for example, this example uses the "Sample2" table from "DB\615" database included in MyOLEDB Provider package).
  4. Change the DEF_LOG_FILE_FULL_NAME identifier value to reflect the actuall name of your log file.
  5. Prepare the sampclnt.exe file using a nmake utility or from the Visual Studio environment (example includes a sampclnt.mak file and VC++ 5 version sampclnt.dsp file).

© 2000 SWsoft


'Update' example

The "Update" example is a simple consumer application intended to illustrate how the MyOLEDB Provider could be used to update rows in a MySQL table. It reads the first row and then updates rows from 2 to 10 with data from the first row. At the end of this test the first 10 rows in the table will be identical.

The main purpose of this test is to illustrate the IRowsetChange::SetData function

By default this example uses "Sample2" table from the "DB" database icluded in OLE DB provider package. That is, because this example uses very simple updating scheme and will not work with tables having a unique index.

To launch this test you should :

  1. Open the testconf.h file using any appropriate editor.
  2. Change the DEF_MYSQL_DIR identifier value to reflect a valid MyOLEDB data source name
  3. Change the DEF_MYSQL_FILE identifier value to reflect the name of the table you are going to work with.
  4. Change the DEF_LOG_FILE_FULL_NAME identifier value to reflect the actuall name of your log file.
  5. Prepare the sampclnt.exe file using a nmake utility or from the Visual Studio environment (example includes sampclnt.mak file and VC++ 5 version sampclnt.dsp file).

© 2000 SWsoft


Overview of ADO examples

Visual Basic examples illustrate how to use MyOLEDB Provider functionality through ADO from the Visual Basic development environment. They are quite simple and aimed at demonstrating basic operations with data: reading, writhing etc.

All examples where prepared and tested with Microsoft Visual Basic 6.0.

All examples use "Sample2" table of DB\615 sample database as default table.
Please reproduce table's contents if other examples have changed it.

© 2000 SWsoft


'vbAdo' example

"vbAdo" example illustrates how to use ADO over MyOLEDB Provider to read data from the MySQL table
and get information about recordset functionality.
Application reads up to 100 rows from the table.

To play with "vbAdo" example, do the following:

  1. Run "vbAdo" application from Visual Basic IDE or as executable.
  2. Enter correct data source into the "Data Source" textbox.
  3. Read records from "Sample2" table: use "Read" button for it.
  4. Get information about recordset using "Recordset Info" button.
  5. Clean data window using "Clean" button.
  6. Leave application by clicking "Exit" button.

© 2000 SWsoft


'vbAdoBmk' example

"vbAdoBmk" example illustrates how to use ADO over MyOLEDB Provider to read data from the MySQL table and navigate throughout the table using bookmarks.
Please reproduce table's contents if other examples have changed it. It is necessary for steps 10-12.

In order to play with "vbAdoBmk" example and get impression about typical using of bookmarks, do the following:

  1. Run "vbAdoBmk" application.
  2. Enter correct data source into the "Data Source" textbox.
  3. Click "Connect" button with your mouse. (if connection to the datasource was successful, you can see the button "Read" enabled).
  4. Enter special bookmark value of "1" (begin of rowset) to the "Bookmark" textbox.
  5. Enter "10" to the the "Number Of Rows" text box.
  6. Click the "Read" button with your mouse. (give a look to the content of "Last Error Description" and "Status" textboxes - they are empty)
  7. Enter special bookmark value of "2" (end of rowset) to the "Bookmark" textbox.
  8. Enter "10" to the the "Number Of Rows" text box.
  9. Click the "Read" button with your mouse. (give a look to the content of "Last Error Description" and "Status" textboxes - you will see that rowset has the EOF status now)
  10. Enter bookmark value of "30" to the "Bookmark" textbox.
  11. Enter "-10" to the the "Number Of Rows" text box.
  12. Click the "Read" button with your mouse. (give a look to the content of "Last Error Description" and "Status" textboxes - you will see that rowset has no the EOF status now).

You may click "Clean" button in order to "clean" all the previous results or you may click "Exit" button to leave this application.

© 2000 SWsoft


'vbAdoIns' example

"vbAdoIns" example illustrates how to use ADO over MyOLEDB Provider to insert data into the the MySQL table.
Application inserts 1 row to the table.

To play with "vbAdoIns" example, do the following:

  1. Run "vbAdoIns" application from Visual Basic IDE or as executable.
  2. Enter correct data source into the "Data Source" textbox.
  3. Click "Connect" button in order to open ADO connection. (You will see message, that you are about to insert the row).
  4. Click "Start" button to insert the row.
  5. Leave application by clicking "Exit" button.

© 2000 SWsoft


'vbAdoDel' example

"vbAdoDel" example illustrates how to use ADO over MyOLEDB Provider to delete data from the table.
Application deletes first 10 rows from the table.

To play with "vbAdoDel" example, do the following:

  1. Run "vbAdoDel" application from Visual Basic IDE or as executable.
  2. Enter correct data source into the "Data Source" textbox.
  3. Click "Connect" button in order to open ADO connection. (You will see message, that you are about to delete rows).
  4. Click "Start" button to delete first 10 rows from the table.
  5. Leave application by clicking "Exit" button.

© 2000 SWsoft


'vbAdoUpd' example

"vbAdoUpd" example illustrates how to use ADO over MyOLEDB Provider to update data in the the MySQL table.
Application updates first ulMaxNumOfRows rows from the table in the following way:
Field ID increases by 10.
Field LastName transforms to UPPER case.

To play with "vbAdoUpd" example, do the following:

  1. Run "vbAdoUpd" application from Visual Basic IDE or as executable.
  2. Enter correct data source into the "Data Source" textbox.
  3. Click "Connect" button in order to open ADO connection. (You will see message, that you are about to update rows).
  4. Click "Start" button to update first 10 rows from the table.
  5. Leave application by clicking "Exit" button.

© 2000 SWsoft


'vbCInt' example

"vbClnt" shows how you can use Ado data control and Data grid control to work with MyOLEDB Provider. This sample uses "Sample2" as default table.

"vbClnt" demonstrates usage of ADO Connector object with adCmdTable parameter

To play with "vbClnt" example, do the following:

  1. Run "vbClnt" application from Visual Basic IDE or as executable.
  2. Enter correct data source into the "Data Source" textbox.
  3. Enter the table name into the "Table" textbox if necessary.
  4. Click "Connect" to make ADO connection. Please wait while records load (approx. 0.5-5 sec., depending on number of records)
  5. Leave application by clicking "Exit" button.
© 2000 SWsoft


'vbCInt' example

"vbQuery" shows how you can use Ado data control and Data grid control to work with MyOLEDB Provider

"vbQuery" demonstrates usage of ADO Connector object with adCmdText parameter.

To play with "vbQuery" example, do the following:

  1. Run "vbQuery" application from Visual Basic IDE or as executable.
  2. Add the Colibri data source name to the "Connection String". (You may launch "Choose Location" dialog using button with "..." caption. You may type nothing to select database on call)
  3. Enter a SELECT query to the "Query" textbox.
  4. Click "Connect" to make ADO connection. Please wait while records load (approx. 0.5-5 sec., depending on number of records)
  5. Leave application by clicking "Exit" button.

© 2000 SWsoft


MySQL syntax reference

MySQL Language Reference v3.23.11

Contents:

Literals

Literals

User variables

Column types

Functions

CREATE DATABASE

DROP DATABASE

CREATE TABLE

ALTER TABLE

OPTIMIZE TABLE

DROP TABLE

DELETE

SELECT

JOIN

INSERT

REPLACE

LOAD DATA

UPDATE

USE

FLUSH

KILL

SHOW

EXPLAIN

DESCRIBE

LOCK / UNLOCK TABLES

SET

GRANT and REVOKE

CREATE INDEX

Comments

CREATE / DROP FUNCTION

Reserved words


MySQL v.3.23.11 language reference

1 Literals: how to write strings and numbers

1.1 Strings

1.2 Numbers

1.3 Hexadecimal values

1.4 NULL values

1.5 Database, table, index, column and alias names

1.5.1 Case sensitivity in names

1 Literals: how to write strings and numbers

1.1 Strings

A string is a sequence of characters, surrounded by either single quote (`'') or double quote (`"') characters (the later only if you don't run in ANSI mode). Examples:

'a string'
"another string"

Within a string, certain sequences have special meaning. Each of these sequences begins with a backslash (`\'), known as the escape character. MySQL recognizes the following escape sequences:

\0
An ASCII 0 (NUL) character.
\n
A newline character.
\t
A tab character.
\r
A carriage return character.
\b
A backspace character.
\'
A single quote (`'') character.
\"
A double quote (`"') character.
\\
A backslash (`\') character.
\%
A `%' character. This is used to search for literal instances of `%' in contexts where `%' would otherwise be interpreted as a wildcard character.
\_
A `_' character. This is used to search for literal instances of `_' in contexts where `_' would otherwise be interpreted as a wildcard character.

Note that if you use `\%' or `\%_' in some string contexts, these will return the strings `\%' and `\_' and not `%' and `_'.

There are several ways to include quotes within a string:

  • A `'' inside a string quoted with `'' may be written as `'''.
  • A `"' inside a string quoted with `"' may be written as `""'.
  • You can precede the quote character with an escape character (`\').
  • A `'' inside a string quoted with `"' needs no special treatment and need not be doubled or escaped. In the same way, `"' inside a string quoted with `'' needs no special treatment.

The SELECT statements shown below demonstrate how quoting and escaping work:

> SELECT 'hello', '"hello"', '""hello""', 'hel''lo', '\'hello';
+-------+---------+-----------+--------+--------+
| hello | "hello" | ""hello"" | hel'lo | 'hello |
+-------+---------+-----------+--------+--------+

> SELECT "hello", "'hello'", "''hello''", "hel""lo", "\"hello";
+-------+---------+-----------+--------+--------+
| hello | 'hello' | ''hello'' | hel"lo | "hello |
+-------+---------+-----------+--------+--------+

> SELECT "This\nIs\nFour\nlines";
+--------------------+
| This
Is
Four
lines |
+--------------------+

If you want to insert binary data into a BLOB column, the following characters must be represented by escape sequences:

NUL
ASCII 0. You should represent this by `\0' (a backslash and an ASCII `0' character).
\
ASCII 92, backslash. Represent this by `\\'.
'
ASCII 39, single quote. Represent this by `\''.
"
ASCII 34, double quote. Represent this by `\"'.

You should use an escape function on any string that might contain any of the special characters listed above!

1.2 Numbers

Integers are represented as a sequence of digits. Floats use `.' as a decimal separator. Either type of number may be preceded by `-' to indicate a negative value.

Examples of valid integers:

1221
0
-32

Examples of valid floating-point numbers:

294.42
-32032.6809e+10
148.00

An integer may be used in a floating-point context; it is interpreted as the equivalent floating-point number.

1.3 Hexadecimal values

MySQL supports hexadecimal values. In number context these acts like an integer (64 bit precision). In string context these acts like a binary string where each pair of hex digits is converted to a character.

> SELECT 0xa+0
       -> 10
> select 0x5061756c;
       -> Paul

Hexadecimal strings is often used by ODBC to give values for BLOB columns.

1.4 NULL values

The NULL value means ``no data'' and is different from values such as 0 for numeric types or the empty string for string types.

NULL may be represented by \N when using the text file import or export formats (LOAD DATA INFILE, SELECT ... INTO OUTFILE). See section 16 LOAD DATA INFILE syntax.

1.5 Database, table, index, column and alias names

Database, table, index, column and alias names all follow the same rules in MySQL:

Note that the rules changed starting with MySQL 3.23.6 when we introduced quoting of identifiers (database, table and column names) with ` (" will also work to quote identifiers if you run in ANSI mode).

Identifier | max length | Allowed characters
Database | 64 | Any character that is allowed in a directory name execpt /.
Table | 64 | Any character that is allowed in file name, except / or .
Column | 64 | All characters
Alias | 255 | All characters

Note that in addition to the above, you can't have ASCII(0) or ASCII(255) in an identifier.

Note that if the identifer is a restricted word or contains special character you must always quote it with ` when you use it:

SELECT * from `select` where `select`.id > 100;

In previous versions of MySQL, the name rules are as follows:

  • A name may consist of alphanumeric characters from the current character set and also `_' and `$'. The default character set is ISO-8859-1 Latin1; this may be changed by recompiling MySQL.
  • A name may start with any character that is legal in a name. In particular, a name may start with a number (this differs from many other database systems!). However, a name cannot consist only of numbers.
  • You cannot use the `.' character in names because it is used to extend the format by which you can refer to columns (see immediately below).

It is recommended that you do not use names like 1e, because an expression like 1e+1 is ambiguous. It may be interpreted as the expression 1e + 1 or as the number 1e+1.

In MySQL you can refer to a column using any of the following forms:

Column reference | Meaning
col_name | Column col_name from whichever table used in the query contains a column of that name
tbl_name.col_name | Column col_name from table tbl_name of the current database
db_name.tbl_name.col_name | Column col_name from table tbl_name of the database db_name. This form is available in MySQL 3.22 or later.
`column_name` | A column that is a keyword or contains special characters.

You need not specify a tbl_name or db_name.tbl_name prefix for a column reference in a statement unless the reference would be ambiguous. For example, suppose tables t1 and t2 each contain a column c, and you retrieve c in a SELECT statement that uses both t1 and t2. In this case, c is ambiguous because it is not unique among the tables used in the statement, so you must indicate which table you mean by writing t1.c or t2.c. Similarly, if you are retrieving from a table t in database db1 and from a table t in database db2, you must refer to columns in those tables as db1.t.col_name and db2.t.col_name.

The syntax .tbl_name means the table tbl_name in the current database. This syntax is accepted for ODBC compatibility, because some ODBC programs prefix table names with a `.' character.

1.5.1 Case sensitivity in names

In MySQL, databases and tables correspond to directories and files within those directories. Consequently, the case sensitivity of the underlying operating system determines the case sensitivity of database and table names. This means database and table names are case sensitive in Unix and case insensitive in Win32.

Note: Although database and table names are case insensitive for Win32, you should not refer to a given database or table using different cases within the same query. The following query would not work because it refers to a table both as my_table and as MY_TABLE:

> SELECT * FROM my_table WHERE MY_TABLE.col=1;

Column names are case insensitive in all cases.

Aliases on tables are case sensitive. The following query would not work because it refers to the alias both as a and as A:

> SELECT col_name FROM tbl_name AS a
           WHERE a.col_name = 1 OR A.col_name = 2;

Aliases on columns are case insensitive.

© 1997-2000 TCX DataKonsult AB, 2000 SWsoft


MySQL v.3.23.11 language reference

2 User variables

MySQL supports thread specific variables with the @variablename syntax. A variable name may consist of alphanumeric characters from the current character set and also `_', `$', and `.' . The default character set is ISO-8859-1 Latin1; this may be changed by recompiling MySQL.

Variables don't have to be initialized. They contain NULL by default and can store an integer, real or string value. All variables for a thread are automatically freed when the thread exits.

You can set a variable with the SET syntax:

SET @variable= { integer expression | real expression | string expression }
[,@variable= ...].

You can also set a variable in an expression with the @variable:=expr< /CODE > syntax:</P>select@t1:=(@t2:=1)+@t3:=4,@t1,@t2,@t3;
+----------------------+------+------+------+
| @t1:=(@t2:=1)+@t3:=4 | @t1  | @t2  | @t3  |
+----------------------+------+------+------+
|                    5 |    5 |    1 |    4 |
+----------------------+------+------+------+

(We had to use the := syntax here as = was reserved
for comparisons.)

User variables may be used where expressions are allowed. Note that this does
not currently include use in contexts where a number is explicitly required,
such as in the LIMIT clause of a SELECT statement, or
the IGNORE number LINES clause of a LOAD DATA statement.

© 1997-2000 TCX DataKonsult AB, 2000 SWsoft


MySQL v.3.23.11 language reference

3 Column types

3.1 Column type storage requirements

3.2 Numeric types

3.3 Date and time types

3.4 String types

3.5 Numeric types

3.6 Date and time types

3.6.1 Y2K issues and date types
3.6.2 The DATETIME, DATE and TIMESTAMP types
3.6.3 The TIME type
3.6.4 The YEAR type

3.7 String types

3.1 The CHAR and VARCHAR types
3.2 The BLOB and TEXT types
3.3 The ENUM type
3.4 The SET type

3.8 Choosing the right type for a column

3.9 Column indexes

3.10 Multiple-column indexes

3.11 Using column types from other database engines

3 Column types

MySQL supports a number of column types, which may be grouped into three categories: numeric types, date and time types, and string (character) types. This section first gives an overview of the types available and summarizes the storage requirements for each column type, then provides a more detailed description of the properties of the types in each category. The overview is intentionally brief. The more detailed descriptions should be consulted for additional information about particular column types, such as the allowable formats in which you can specify values.

The column types supported by MySQL are listed below. The following code letters are used in the descriptions:

M
Indicates the maximum display size. The maximum legal display size is 255.
D
Applies to floating-point types and indicates the number of digits following the decimal point. The maximum possible value is 30, but should be no greater than M-2.

Square brackets (`[' and `]') indicate parts of type specifiers that are optional.

Note that if you specify ZEROFILL for a column, MySQL will automatically add the UNSIGNED attribute to the column.

TINYINT[(M)] [UNSIGNED] [ZEROFILL]
A very small integer. The signed range is -128 to 127. The unsigned range is 0 to 255.
SMALLINT[(M)] [UNSIGNED] [ZEROFILL]
A small integer. The signed range is -32768 to 32767. The unsigned range is 0 to 65535.
MEDIUMINT[(M)] [UNSIGNED] [ZEROFILL]
A medium-size integer. The signed range is -8388608 to 8388607. The unsigned range is 0 to 16777215.
INT[(M)] [UNSIGNED] [ZEROFILL]
A normal-size integer. The signed range is -2147483648 to 2147483647. The unsigned range is 0 to 4294967295.
INTEGER[(M)] [UNSIGNED] [ZEROFILL]
This is a synonym for INT.
BIGINT[(M)] [UNSIGNED] [ZEROFILL]
A large integer. The signed range is -9223372036854775808 to 9223372036854775807. The unsigned range is 0 to 18446744073709551615. Note that all arithmetic is done using signed BIGINT or DOUBLE values, so you shouldn't use unsigned big integers larger than 9223372036854775807 (63 bits) except with bit functions! Note that -, + and * will use BIGINT arithmetic when both arguments are INTEGER values! This means that if you multiply two big integers (or results from functions that return integers) you may get unexpected results if the result is larger than 9223372036854775807. A floating-point number. Cannot be unsigned. precision can be <=24 for a single precision floating point number and between 25 and 53 for a double precision floating point number. these types are like the FLOAT and DOUBLE types described immediately below. FLOAT(X) have the same ranges as the corresponding FLOAT and DOUBLE types, but the display size and number of decimals is undefined. In MySQL 3.23, this is a true floating point value. In earlier MySQL versions, FLOAT(precision) always has 2 decimals. This syntax is provided for ODBC compatibility.
FLOAT[(M,D)] [ZEROFILL]
A small (single-precision) floating-point number. Cannot be unsigned. Allowable values are -3.402823466E+38 to -1.175494351E-38, 0 and 1.175494351E-38 to 3.402823466E+38. The M is the display width and D is the number of decimals. FLOAT without an argument or with an argument of <= 24 stands for a single-precision floating point number.
DOUBLE[(M,D)] [ZEROFILL]
A normal-size (double-precision) floating-point number. Cannot be unsigned. Allowable values are -1.7976931348623157E+308 to -2.2250738585072014E-308, 0 and 2.2250738585072014E-308 to 1.7976931348623157E+308. The M is the display width and D is the number of decimals. DOUBLE without an argument or FLOAT(X) where 25 <= X <= 53 stands for a double-precision floating point number.
DOUBLE PRECISION[(M,D)] [ZEROFILL]
REAL[(M,D)] [ZEROFILL]
These are synonyms for DOUBLE.
DECIMAL[(M[,D])] [ZEROFILL]
An unpacked floating-point number. Cannot be unsigned. Behaves like a CHAR column: ``unpacked'' means the number is stored as a string, using one character for each digit of the value. The decimal point, and, for negative numbers, the `-' sign is not counted in M. If D is 0, values will have no decimal point or fractional part. The maximum range of DECIMAL values is the same as for DOUBLE, but the actual range for a given DECIMAL column may be constrained by the choice of M and D. If D is left out it's set to 0. If M is left out it's set to 10. Note that in MySQL 3.22 the M argument includes the sign and the decimal point.
NUMERIC(M,D) [ZEROFILL]
This is a synonym for DECIMAL.
DATE
A date. The supported range is '1000-01-01' to '9999-12-31'. MySQL displays DATE values in 'YYYY-MM-DD' format, but allows you to assign values to DATE columns using either strings or numbers.
DATETIME
A date and time combination. The supported range is '1000-01-01 00:00:00' to '9999-12-31 23:59:59'. MySQL displays DATETIME values in 'YYYY-MM-DD HH:MM:SS' format, but allows you to assign values to DATETIME columns using either strings or numbers.
TIMESTAMP[(M)]
A timestamp. The range is '1970-01-01 00:00:00' to sometime in the year 2037. MySQL displays TIMESTAMP values in YYYYMMDDHHMMSS, YYMMDDHHMMSS, YYYYMMDD or YYMMDD format, depending on whether M is 14 (or missing), 12, 8 or 6, but allows you to assign values to TIMESTAMP columns using either strings or numbers. A TIMESTAMP column is useful for recording the date and time of an INSERT or UPDATE operation because it is automatically set to the date and time of the most recent operation if you don't give it a value yourself. You can also set it to the current date and time by assigning it a NULL value. See section 3.6 Date and time types.
TIME
A time. The range is '-838:59:59' to '838:59:59'. MySQL displays TIME values in 'HH:MM:SS' format, but allows you to assign values to TIME columns using either strings or numbers.
YEAR[(2|4)]
A year in 2- or 4- digit formats (default is 4-digit). The allowable values are 1901 to 2155, and 0000 in the 4 year format and 1970-2069 if you use the 2 digit format (70-69). MySQL displays YEAR values in YYYY format, but allows you to assign values to YEAR columns using either strings or numbers. (The YEAR type is new in MySQL 3.22.)
CHAR(M) [BINARY]
A fixed-length string that is always right-padded with spaces to the specified length when stored. The range of M is 1 to 255 characters. Trailing spaces are removed when the value is retrieved. CHAR values are sorted and compared in case-insensitive fashion according to the default character set unless the BINARY keyword is given. NATIONAL CHAR (short form NCHAR) is the ANSI SQL way to define that a CHAR column should use the default CHARACTER set. This is default in MySQL. CHAR is a shorthand for CHARACTER. MySQL allows you to create a column of type CHAR(0). This is mainly useful when you have to be compliant with some old applications that depend on that a column exists but never actually uses the value. This is also quite nice when you need a column that only can take 2 values: A CHAR(0), that is not defined as NOT NULL, will only occupy one bit and can only take 2 values: NULL or "".
[NATIONAL] VARCHAR(M) [BINARY]
A variable-length string. Note: Trailing spaces are removed when the value is stored (this differs from the ANSI SQL specification). The range of M is 1 to 255 characters. VARCHAR values are sorted and compared in case-insensitive fashion unless the BINARY keyword is given. See section 1 Silent column specification changes. VARCHAR is a shorthand for CHARACTER VARYING.
TINYBLOB
TINYTEXT
A BLOB or TEXT column with a maximum length of 255 (2^8 - 1) characters. See section 1 Silent column specification changes.
BLOB
TEXT
A BLOB or TEXT column with a maximum length of 65535 (2^16 - 1) characters. See section 1 Silent column specification changes.
MEDIUMBLOB
MEDIUMTEXT
A BLOB or TEXT column with a maximum length of 16777215 (2^24 - 1) characters. See section 1 Silent column specification changes.
LONGBLOB
LONGTEXT
A BLOB or TEXT column with a maximum length of 4294967295 (2^32 - 1) characters. See section 1 Silent column specification changes.
ENUM('value1','value2',...)
An enumeration. A string object that can have only one value, chosen from the list of values 'value1', 'value2', ..., or NULL. An ENUM can have a maximum of 65535 distinct values.
SET('value1','value2',...)
A set. A string object that can have zero or more values, each of which must be chosen from the list of values 'value1', 'value2', ... A SET can have a maximum of 64 members.

3.1 Column type storage requirements

The storage requirements for each of the column types supported by MySQL are listed below by category.

3.2 Numeric types

Column type | Storage required
TINYINT | 1 byte
SMALLINT | 2 bytes
MEDIUMINT | 3 bytes
INT | 4 bytes
INTEGER | 4 bytes
BIGINT | 8 bytes
FLOAT(X) | 4 if X <= 24 or 8 if 25 <= X <= 53
FLOAT | 4 bytes
DOUBLE | 8 bytes
DOUBLE PRECISION | 8 bytes
REAL | 8 bytes
DECIMAL(M,D) | M bytes (D+2, if M < D)
NUMERIC(M,D) | M bytes (D+2, if M < D)

3.3 Date and time types

Column type | Storage required
DATE | 3 bytes
DATETIME | 8 bytes
TIMESTAMP | 4 bytes
TIME | 3 bytes
YEAR | 1 byte

3.4 String types

Column type | Storage required
CHAR(M) | M bytes, 1 <= M <= 255
VARCHAR(M) | L+1 bytes, where L <= M and 1 <= M <= 255
TINYBLOB, TINYTEXT | L+1 bytes, where L < 2^8
BLOB, TEXT | L+2 bytes, where L < 2^16
MEDIUMBLOB, MEDIUMTEXT | L+3 bytes, where L < 2^24
LONGBLOB, LONGTEXT | L+4 bytes, where L < 2^32
ENUM('value1','value2',...) | 1 or 2 bytes, depending on the number of enumeration values (65535 values maximum)
SET('value1','value2',...) | 1, 2, 3, 4 or 8 bytes, depending on the number of set members (64 members maximum)

VARCHAR and the BLOB and TEXT types are variable-length types, for which the storage requirements depend on the actual length of column values (represented by L in the preceding table), rather than on the type's maximum possible size. For example, a VARCHAR(10) column can hold a string with a maximum length of 10 characters. The actual storage required is the length of the string (L), plus 1 byte to record the length of the string. For the string 'abcd', L is 4 and the storage requirement is 5 bytes.

The BLOB and TEXT types require 1, 2, 3 or 4 bytes to record the length of the column value, depending on the maximum possible length of the type.

If a table includes any variable-length column types, the record format will also be variable-length. Note that when a table is created, MySQL may under certain conditions change a column from a variable-length type to a fixed-length type, or vice-versa. See section 1 Silent column specification changes.

The size of an ENUM object is determined by the number of different enumeration values. 1 byte is used for enumerations with up to 255 possible values. 2 bytes are used for enumerations with up to 65535 values.

The size of a SET object is determined by the number of different set members. If the set size is N, the object occupies (N+7)/8 bytes, rounded up to 1, 2, 3, 4 or 8 bytes. A SET can have a maximum of 64 members.

3.5 Numeric types

MySQL supports all of the ANSI/ISO SQL92 numeric types. These types include the exact numeric data types (NUMERIC, DECIMAL, INTEGER, and SMALLINT), as well as the approximate numeric data types (FLOAT, REAL, and DOUBLE PRECISION). The keyword INT is a synonym for INTEGER, and the keyword DEC is a synonym for DECIMAL.

The NUMERIC and DECIMAL types are implemented as the same type by MySQL, as permitted by the SQL92 standard. They are used for values for which it is important to preserve exact precision, for example with monetary data. When declaring a column of one of these types the precision and scale can be (and usually is) specified; for example:

    salary DECIMAL(9,2)

In this example, 9 (precision) represents the number of significant decimal digits which will be stored for values, and 2 (scale) represents the number of digits which will be stored following the decimal point. In this case, therefore, the range of values which can be stored in the salary column is from -9999999.99 to 9999999.99. In ANSI/ISO SQL92, the syntax DECIMAL(p) is equivalent to DECIMAL(p,0). Similarly, the syntax DECIMAL is equivalent to DECIMAL(p,0), where the implementation is allowed to decide the value of p. MySQL does not currently support either of these variant forms of the DECIMAL/NUMERIC data types. This is not generally a serious problem, as the principal benefits of these types derive from the ability to control both precision and scale explicitly.

DECIMAL and NUMERIC values are stored as strings, rather than as binary floating point numbers, in order to preserve the decimal precision of those values. One character is used for each digit of the value, the decimal point (if scale > 0) and the `-' sign (for negative numbers). If scale is 0, DECIMAL and NUMERIC values contain no decimal point or fractional part.

The maximum range of DECIMAL and NUMERIC values is the same as for DOUBLE, but the actual range for a given DECIMAL or NUMERIC column can be constrained by the precision or scale for a given column. When such a column is assigned a value with more digits following the decimal point than are allowed by the specified scale, the value is rounded to that scale. When a DECIMAL or NUMERIC column is assigned a value whose magnitude exceeds the range implied by the specified (or defaulted) precision and scale, MySQL stores the value representing the corresponding end point of that range.

As an extension to the ANSI/ISO SQL92 standard, MySQL also supports the integral types TINYINT, MEDIUMINT, and BIGINT as listed in the tables above. Another extension is supported by MySQL for optionally specifying the display width of an integral value in parentheses following the base keyword for the type (for example, INT(4)). This optional width specification is used to left-pad the display of values whose width is less than the width specified for the column, but does not constrain the range of values which can be stored in the column, nor the number of digits which will be displayed for values whose width exceeds that specified for the column. When used in conjunction with the optional extension attribute ZEROFILL the default padding of spaces is replaced with zeroes. For example, for a column declared as INT(5) ZEROFILL, a value of 4 is retrieved as 00004. Note that if you store larger values than the display width in an integral column, you may experience problems when MySQL generates temporary tables for some complicated joins as in these case MySQL trust that the data did fit into the original column width.

All integral types can have an optional (non-standard) attribute UNSIGNED. Unsigned values can be used when you want to allow only positive numbers in a column and you need a little bigger numeric range for the column.

The FLOAT type is used to represent approximate numeric data types. The ANSI/ISO SQL92 standard allows an optional specification of the precision (but not the range of the exponent) in bits following the keyword FLOAT in parentheses. The MySQL implementation also supports this optional precision specification. When the keyword FLOAT is used for a column type without a precision specification, MySQL uses four bytes to store the values. A variant syntax is also supported, with two numbers given in parentheses following the FLOAT keyword. With this option, the first number continues to represent the storage requirements for the value in bytes, and the second number specifies the number of digits to be stored and displayed following the decimal point (as with DECIMAL and NUMERIC). When MySQL is asked to store a number for such a column with more decimal digits following the decimal point than specified for the column, the value is rounded to eliminate the extra digits when the value is stored.

The REAL and DOUBLE PRECISION types do not accept precision specifications. As an extension to the ANSI/ISO SQL92 standard, MySQL recognizes DOUBLE as a synonym for the DOUBLE PRECISION type. In contrast with the standard's requirement that the precision for REAL be smaller than that used for DOUBLE PRECISION, MySQL implements both as 8-byte double-precision floating point values (when running in not "Ansi mode"). For maximum portability, code requiring storage of approximate numeric data values should use FLOAT or DOUBLE PRECISION with no specification of precision or number of decimal points.

When asked to store a value in a numeric column that is outside the column type's allowable range, MySQL clips the value to the appropriate endpoint of the range and stores the resulting value instead.

For example, the range of an INT column is -2147483648 to 2147483647. If you try to insert -9999999999 into an INT column, the value is clipped to the lower endpoint of the range, and -2147483648 is stored instead. Similarly, if you try to insert 9999999999, 2147483647 is stored instead.

If the INT column is UNSIGNED, the size of the column's range is the same but its endpoints shift up to 0 and 4294967295. If you try to store -9999999999 and 9999999999, the values stored in the column become 0 and 4294967296.

Conversions that occur due to clipping are reported as ``warnings'' for ALTER TABLE, LOAD DATA INFILE, UPDATE and multi-row INSERT statements.

3.6 Date and time types

The date and time types are DATETIME, DATE, TIMESTAMP, TIME and YEAR. Each of these has a range of legal values, as well as a ``zero'' value that is used when you specify a really illegal value. Note that MySQL allows you to store certain 'not strictly' legal date values, for example 1999-11-31. The reason for this is that we think it's the responsibility of the application to handle date checking, not the SQL servers. To make the date checking 'fast', MySQL only checks that the month is in the range of 0-12 and the day is in the range of 0-31. The above ranges are defined this way because MySQL allows you to store, in a DATE or DATETIME column, dates where the day or month-day are zero. This is extremely useful for applications that need to store a birth-date for which you don't know the exact date. In this case you simply store the date like 1999-00-00 or 1999-01-00. (You can of course not expect to get a correct value from functions like DATE_SUB() or DATE_ADD for dates like these).

Here are some general considerations to keep in mind when working with date and time types:

  • MySQL retrieves values for a given date or time type in a standard format, but it attempts to interpret a variety of formats for values that you supply (e.g., when you specify a value to be assigned to or compared to a date or time type). Nevertheless, only the formats described in the following sections are supported. It is expected that you will supply legal values, and unpredictable results may occur if you use values in other formats.
  • Although MySQL tries to interpret values in several formats, it always expects the year part of date values to be leftmost. Dates must be given in year-month-day order (e.g., '98-09-04'), rather than in the month-day-year or day-month-year orders commonly used elsewhere (e.g., '09-04-98', '04-09-98').
  • MySQL automatically converts a date or time type value to a number if the value is used in a numeric context, and vice versa.
  • When MySQL encounters a value for a date or time type that is out of range or otherwise illegal for the type (see start of this section), it converts the value to the ``zero'' value for that type. (The exception is that out-of-range TIME values are clipped to the appropriate endpoint of the TIME range.) The table below shows the format of the ``zero'' value for each type:
    Column type | ``Zero'' value
    DATETIME | '0000-00-00 00:00:00'
    DATE | '0000-00-00'
    TIMESTAMP | 00000000000000 (length depends on display size)
    TIME | '00:00:00'
    YEAR | 0000
  • The ``zero'' values are special, but you can store or refer to them explicitly using the values shown in the table. You can also do this using the values '0' or 0, which are easier to write.
  • ``Zero'' date or time values used through MyODBC are converted automatically to NULL in MyODBC 2.50.12 and above, because ODBC can't handle such values.

3.6.1 Y2K issues and date types

MySQL itself is Y2K-safe, but input values presented to MySQL may not be. Any input containing 2-digit year values is ambiguous, since the century is unknown. Such values must be interpreted into 4-digit form since MySQL stores years internally using four digits.

For DATETIME, DATE, TIMESTAMP and YEAR types, MySQL interprets dates with ambiguous year values using the following rules:

  • Year values in the range 00-69 are converted to 2000-2069.
  • Year values in the range 70-99 are converted to 1970-1999.

Remember that these rules provide only reasonable guesses as to what your data mean. If the heuristics used by MySQL don't produce the correct values, you should provide unambiguous input containing 4-digit year values.

ORDER BY will sort 2 digit YEAR/DATE/DATETIME types properly.

Note also that some functions like MIN() and MAX() will convert a TIMESTAMP/DATE to a number. This means that a timestamp with a 2 digit year will not work properly with these functions. The fix in this case is to convert the TIMESTAMP/DATE to 4 digit year format or use something like MIN(DATE_ADD(timestamp,INTERVAL 0 DAYS)).

3.6.2 The DATETIME, DATE and TIMESTAMP types

The DATETIME, DATE and TIMESTAMP types are related. This section describes their characteristics, how they are similar and how they differ.

The DATETIME type is used when you need values that contain both date and time information. MySQL retrieves and displays DATETIME values in 'YYYY-MM-DD HH:MM:SS' format. The supported range is '1000-01-01 00:00:00' to '9999-12-31 23:59:59'. (``Supported'' means that although earlier values might work, there is no guarantee that they will.)

The DATE type is used when you need only a date value, without a time part. MySQL retrieves and displays DATE values in 'YYYY-MM-DD' format. The supported range is '1000-01-01' to '9999-12-31'.

The TIMESTAMP column type provides a type that you can use to automatically mark INSERT or UPDATE operations with the current date and time. If you have multiple TIMESTAMP columns, only the first one is updated automatically.

Automatic updating of the first TIMESTAMP column occurs under any of the following conditions:

  • The column is not specified explicitly in an INSERT or LOAD DATA INFILE statement.
  • The column is not specified explicitly in an UPDATE statement and some other column changes value. (Note that an UPDATE that sets a column to the value it already has will not cause the TIMESTAMP column to be updated, because if you set a column to its current value, MySQL ignores the update for efficiency.)
  • You explicitly set the TIMESTAMP column to NULL.

TIMESTAMP columns other than the first may also be set to the current date and time. Just set the column to NULL, or to NOW().

You can set any TIMESTAMP column to a value different than the current date and time by setting it explicitly to the desired value. This is true even for the first TIMESTAMP column. You can use this property if, for example, you want a TIMESTAMP to be set to the current date and time when you create a row, but not to be changed whenever the row is updated later:

  • Let MySQL set the column when the row is created. This will initialize it to the current date and time.
  • When you perform subsequent updates to other columns in the row, set the TIMESTAMP column explicitly to its current value.

On the other hand, you may find it just as easy to use a DATETIME column that you initialize to NOW() when the row is created and leave alone for subsequent updates.

TIMESTAMP values may range from the beginning of 1970 to sometime in the year 2037, with a resolution of one second. Values are displayed as numbers.

The format in which MySQL retrieves and displays TIMESTAMP values depends on the display size, as illustrated by the table below. The `full' TIMESTAMP format is 14 digits, but TIMESTAMP columns may be created with shorter display sizes:

Column type | Display format
TIMESTAMP(14) | YYYYMMDDHHMMSS
TIMESTAMP(12) | YYMMDDHHMMSS
TIMESTAMP(10) | YYMMDDHHMM
TIMESTAMP(8) | YYYYMMDD
TIMESTAMP(6) | YYMMDD
TIMESTAMP(4) | YYMM
TIMESTAMP(2) | YY

All TIMESTAMP columns have the same storage size, regardless of display size. The most common display sizes are 6, 8, 12, and 14. You can specify an arbitrary display size at table creation time, but values of 0 or greater than 14 are coerced to 14. Odd-valued sizes in the range from 1 to 13 are coerced to the next higher even number.

You can specify DATETIME, DATE and TIMESTAMP values using any of a common set of formats:

  • As a string in either 'YYYY-MM-DD HH:MM:SS' or 'YY-MM-DD HH:MM:SS' format. A ``relaxed'' syntax is allowed-any punctuation character may be used as the delimiter between date parts or time parts. For example, '98-12-31 11:30:45', '98.12.31 11+30+45', '98/12/31 11*30*45' and '98@12@31 11^30^45' are equivalent.
  • As a string in either 'YYYY-MM-DD' or 'YY-MM-DD' format. A ``relaxed'' syntax is allowed here, too. For example, '98-12-31', '98.12.31', '98/12/31' and '98@12@31' are equivalent.
  • As a string with no delimiters in either 'YYYYMMDDHHMMSS' or 'YYMMDDHHMMSS' format, provided that the string makes sense as a date. For example, '19970523091528' and '970523091528' are interpreted as '1997-05-23 09:15:28', but '971122459015' is illegal (it has a nonsensical minute part) and becomes '0000-00-00 00:00:00'.
  • As a string with no delimiters in either 'YYYYMMDD' or 'YYMMDD' format, provided that the string makes sense as a date. For example, '19970523' and '970523' are interpreted as '1997-05-23', but '971332' is illegal (it has nonsensical month and day parts) and becomes '0000-00-00'.
  • As a number in either YYYYMMDDHHMMSS or YYMMDDHHMMSS format, provided that the number makes sense as a date. For example, 19830905132800 and 830905132800 are interpreted as '1983-09-05 13:28:00'.
  • As a number in either YYYYMMDD or YYMMDD format, provided that the number makes sense as a date. For example, 19830905 and 830905 are interpreted as '1983-09-05'.
  • As the result of a function that returns a value that is acceptable in a DATETIME, DATE or TIMESTAMP context, such as NOW() or CURRENT_DATE.

Illegal DATETIME, DATE or TIMESTAMP values are converted to the ``zero'' value of the appropriate type ('0000-00-00 00:00:00', '0000-00-00' or 00000000000000).

For values specified as strings that include date part delimiters, it is not necessary to specify two digits for month or day values that are less than 10. '1979-6-9' is the same as '1979-06-09'. Similarly, for values specified as strings that include time part delimiters, it is not necessary to specify two digits for hour, month or second values that are less than 10. '1979-10-30 1:2:3' is the same as '1979-10-30 01:02:03'.

Values specified as numbers should be 6, 8, 12 or 14 digits long. If the number is 8 or 14 digits long, it is assumed to be in YYYYMMDD or YYYYMMDDHHMMSS format and that the year is given by the first 4 digits. If the number is 6 or 12 digits long, it is assumed to be in YYMMDD or YYMMDDHHMMSS format and that the year is given by the first 2 digits. Numbers that are not one of these lengths are interpreted as though padded with leading zeros to the closest length.

Values specified as non-delimited strings are interpreted using their length as given. If the string is 8 or 14 characters long, the year is assumed to be given by the first 4 characters. Otherwise the year is assumed to be given by the first 2 characters. The string is interpreted from left to right to find year, month, day, hour, minute and second values, for as many parts as are present in the string. This means you should not use strings that have fewer than 6 characters. For example, if you specify '9903', thinking that will represent March, 1999, you will find that MySQL inserts a ``zero'' date into your table. This is because the year and month values are 99 and 03, but the day part is missing (zero), so the value is not a legal date.

TIMESTAMP columns store legal values using the full precision with which the value was specified, regardless of the display size. This has several implications:

  • Always specify year, month, and day, even if your column types are TIMESTAMP(4) or TIMESTAMP(2). Otherwise, the value will not be a legal date and 0 will be stored.
  • If you use ALTER TABLE to widen a narrow TIMESTAMP column, information will be displayed that previously was ``hidden''.
  • Similarly, narrowing a TIMESTAMP column does not cause information to be lost, except in the sense that less information is shown when the values are displayed.
  • Although TIMESTAMP values are stored to full precision, the only function that operates directly on the underlying stored value is UNIX_TIMESTAMP(). Other functions operate on the formatted retrieved value. This means you cannot use functions such as HOUR() or SECOND() unless the relevant part of the TIMESTAMP value is included in the formatted value. For example, the HH part of a TIMESTAMP column is not displayed unless the display size is at least 10, so trying to use HOUR() on shorter TIMESTAMP values produces a meaningless result.

You can to some extent assign values of one date type to an object of a different date type. However, there may be some alteration of the value or loss of information:

  • If you assign a DATE value to a DATETIME or TIMESTAMP object, the time part of the resulting value is set to '00:00:00', because the DATE value contains no time information.
  • If you assign a DATETIME or TIMESTAMP value to a DATE object, the time part of the resulting value is deleted, because the DATE type stores no time information.
  • Remember that although DATETIME, DATE and TIMESTAMP values all can be specified using the same set of formats, the types do not all have the same range of values. For example, TIMESTAMP values cannot be earlier than 1970 or later than 2037. This means that a date such as '1968-01-01', while legal as a DATETIME or DATE value, is not a valid TIMESTAMP value and will be converted to 0 if assigned to such an object.

Be aware of certain pitfalls when specifying date values:

  • The relaxed format allowed for values specified as strings can be deceiving. For example, a value such as '10:11:12' might look like a time value because of the `:' delimiter, but if used in a date context will be interpreted as the year '2010-11-12'. The value '10:45:15' will be converted to '0000-00-00' because '45' is not a legal month.
  • Year values specified as two digits are ambiguous, since the century is unknown. MySQL interprets 2-digit year values using the following rules:
    • Year values in the range 00-69 are converted to 2000-2069.
    • Year values in the range 70-99 are converted to 1970-1999.

3.6.3 The TIME type

MySQL retrieves and displays TIME values in 'HH:MM:SS' format (or 'HHH:MM:SS' format for large hours values). TIME values may range from '-838:59:59' to '838:59:59'. The reason the hours part may be so large is that the TIME type may be used not only to represent a time of day (which must be less than 24 hours), but also elapsed time or a time interval between two events (which may be much greater than 24 hours, or even negative).

You can specify TIME values in a variety of formats:

  • As a string in 'HH:MM:SS' format. A ``relaxed'' syntax is allowed--any punctuation character may be used as the delimiter between time parts. For example, '10:11:12' and '10.11.12' are equivalent.
  • As a string with no delimiters in 'HHMMSS' format, provided that it makes sense as a time. For example, '101112' is understood as '10:11:12', but '109712' is illegal (it has a nonsensical minute part) and becomes '00:00:00'.
  • As a number in HHMMSS format, provided that it makes sense as a time. For example, 101112 is understood as '10:11:12'.
  • As the result of a function that returns a value that is acceptable in a TIME context, such as CURRENT_TIME.

For TIME values specified as strings that include a time part delimiter, it is not necessary to specify two digits for hours, minutes or seconds values that are less than 10. '8:3:2' is the same as '08:03:02'.

Be careful about assigning ``short'' TIME values to a TIME column. MySQL interprets values using the assumption that the rightmost digits represent seconds. (MySQL interprets TIME values as elapsed time, rather than as time of day.) For example, you might think of '11:12', '1112' and 1112 as meaning '11:12:00' (12 minutes after 11 o'clock), but MySQL interprets them as '00:11:12' (11 minutes, 12 seconds). Similarly, '12' and 12 are interpreted as '00:00:12'.

Values that lie outside the TIME range but are otherwise legal are clipped to the appropriate endpoint of the range. For example, '-850:00:00' and '850:00:00' are converted to '-838:59:59' and '838:59:59'.

Illegal TIME values are converted to '00:00:00'. Note that since '00:00:00' is itself a legal TIME value, there is no way to tell, from a value of '00:00:00' stored in a table, whether the original value was specified as '00:00:00' or whether it was illegal.

3.6.4 The YEAR type

The YEAR type is a 1-byte type used for representing years.

MySQL retrieves and displays YEAR values in YYYY format. The range is 1901 to 2155.

You can specify YEAR values in a variety of formats:

  • As a four-digit string in the range '1901' to '2155'.
  • As a four-digit number in the range 1901 to 2155.
  • As a two-digit string in the range '00' to '99'. Values in the ranges '00' to '69' and '70' to '99' are converted to YEAR values in the ranges 2000 to 2069 and 1970 to 1999.
  • As a two-digit number in the range 1 to 99. Values in the ranges 1 to 69 and 70 to 99 are converted to YEAR values in the ranges 2001 to 2069 and 1970 to 1999. Note that the range for two-digit numbers is slightly different than the range for two-digit strings, since you cannot specify zero directly as a number and have it be interpreted as 2000. You must specify it as a string '0' or '00' or it will be interpreted as 0000.
  • As the result of a function that returns a value that is acceptable in a YEAR context, such as NOW().

Illegal YEAR values are converted to 0000.

3.7 String types

The string types are CHAR, VARCHAR, BLOB, TEXT, ENUM and SET.

3.1 The CHAR and VARCHAR types

The CHAR and VARCHAR types are similar, but differ in the way they are stored and retrieved.

The length of a CHAR column is fixed to the length that you declare when you create the table. The length can be any value between 1 and 255. (As of MySQL 3.23, the length of CHAR may be 0 to 255.) When CHAR values are stored, they are right-padded with spaces to the specified length. When CHAR values are retrieved, trailing spaces are removed.

Values in VARCHAR columns are variable-length strings. You can declare a VARCHAR column to be any length between 1 and 255, just as for CHAR columns. However, in contrast to CHAR, VARCHAR values are stored using only as many characters as are needed, plus one byte to record the length. Values are not padded; instead, trailing spaces are removed when values are stored. (This space removal differs from the ANSI SQL specification.)

If you assign a value to a CHAR or VARCHAR column that exceeds the column's maximum length, the value is truncated to fit.

The table below illustrates the differences between the two types of columns by showing the result of storing various string values into CHAR(4) and VARCHAR(4) columns:

Value | CHAR(4) | Storage required | VARCHAR(4) | Storage required
'' | ' ' | 4 bytes | '' | 1 byte
'ab' | 'ab ' | 4 bytes | 'ab' | 3 bytes
'abcd' | 'abcd' | 4 bytes | 'abcd' | 5 bytes
'abcdefgh' | 'abcd' | 4 bytes | 'abcd' | 5 bytes

The values retrieved from the CHAR(4) and VARCHAR(4) columns will be the same in each case, because trailing spaces are removed from CHAR columns upon retrieval.

Values in CHAR and VARCHAR columns are sorted and compared in case-insensitive fashion, unless the BINARY attribute was specified when the table was created. The BINARY attribute means that column values are sorted and compared in case-sensitive fashion according to the ASCII order of the machine where the MySQL server is running.

The BINARY attribute is ``sticky''. This means that if a column marked BINARY is used in an expression, the whole expression is compared as a BINARY value.

MySQL may silently change the type of a CHAR or VARCHAR column at table creation time. See section 1 Silent column specification changes.

3.2 The BLOB and TEXT types

A BLOB is a binary large object that can hold a variable amount of data. The four BLOB types TINYBLOB, BLOB, MEDIUMBLOB and LONGBLOB differ only in the maximum length of the values they can hold. See section 3.1 Column type storage requirements.

The four TEXT types TINYTEXT, TEXT, MEDIUMTEXT and LONGTEXT correspond to the four BLOB types and have the same maximum lengths and storage requirements. The only difference between BLOB and TEXT types is that sorting and comparison is performed in case-sensitive fashion for BLOB values and case-insensitive fashion for TEXT values. In other words, a TEXT is a case-insensitive BLOB.

If you assign a value to a BLOB or TEXT column that exceeds the column type's maximum length, the value is truncated to fit.

In most respects, you can regard a TEXT column as a VARCHAR column that can be as big as you like. Similarly, you can regard a BLOB column as a VARCHAR BINARY column. The differences are:

  • You can have indexes on BLOB and TEXT columns with MySQL versions 3.23.2 and newer. Older versions of MySQL did not support this.
  • There is no trailing-space removal for BLOB and TEXT columns when values are stored, as there is for VARCHAR columns.
  • BLOB and TEXT columns cannot have DEFAULT values.

MyODBC defines BLOB values as LONGVARBINARY and TEXT values as LONGVARCHAR.

Because BLOB and TEXT values may be extremely long, you may run up against some constraints when using them:

  • If you want to use GROUP BY or ORDER BY on a BLOB or TEXT column, you must convert the column value into a fixed-length object. The standard way to do this is with the SUBSTRING function. For example:
    > select comment from tbl_name,substring(comment,20) as substr
     ORDER BY substr;
    If you don't do this, only the first max_sort_length bytes of the column are used when sorting. The default value of max_sort_length is 1024; this value can be changed using the -O option when starting the mysqld server. You can group on an expression involving BLOB or TEXT values by specifying the column position or by using an alias:
    > select id,substring(blob_col,1,100) from tbl_name
           GROUP BY 2;
> select id,substring(blob_col,1,100) as b from tbl_name
           GROUP BY b;
  • The maximum size of a BLOB or TEXT object is determined by its type, but the largest value you can actually transmit between the client and server is determined by the amount of available memory and the size of the communications buffers. You can change the message buffer size, but you must do so on both the server and client ends.

Note that each BLOB or TEXT value is represented internally by a separately-allocated object. This is in contrast to all other column types, for which storage is allocated once per column when the table is opened.

3.3 The ENUM type

An ENUM is a string object whose value normally is chosen from a list of allowed values that are enumerated explicitly in the column specification at table creation time.

The value may also be the empty string ("") or NULL under certain circumstances:

  • If you insert an invalid value into an ENUM (that is, a string not present in the list of allowed values), the empty string is inserted instead as a special error value.
  • If an ENUM is declared NULL, NULL is also a legal value for the column, and the default value is NULL. If an ENUM is declared NOT NULL, the default value is the first element of the list of allowed values.

Each enumeration value has an index:

  • Values from the list of allowable elements in the column specification are numbered beginning with 1.
  • The index value of the empty string error value is 0. This means that you can use the following SELECT statement to find rows into which invalid ENUM values were assigned:
    > SELECT * FROM tbl_name WHERE enum_col=0;
  • The index of the NULL value is NULL.

For example, a column specified as ENUM("one", "two", "three") can have any of the values shown below. The index of each value is also shown:

Value | Index
NULL | NULL
"" | 0
"one" | 1
"two" | 2
"three" | 3

An enumeration can have a maximum of 65535 elements.

Lettercase is irrelevant when you assign values to an ENUM column. However, values retrieved from the column later have lettercase matching the values that were used to specify the allowable values at table creation time.

If you retrieve an ENUM in a numeric context, the column value's index is returned. If you store a number into an ENUM, the number is treated as an index, and the the value stored is the enumeration member with that index.

ENUM values are sorted according to the order in which the enumeration members were listed in the column specification. (In other words, ENUM values are sorted according to their index numbers.) For example, "a" sorts before "b" for ENUM("a", "b"), but "b" sorts before "a" for ENUM("b", "a"). The empty string sorts before non-empty strings, and NULL values sort before all other enumeration values.

If you want to get all possible values for an ENUM column, you should use: SHOW COLUMNS FROM table_name LIKE enum_column_name and parse the ENUM definition in the second column.

3.4 The SET type

A SET is a string object that can have zero or more values, each of which must be chosen from a list of allowed values specified when the table is created. SET column values that consist of multiple set members are specified with members separated by commas (`,'). A consequence of this is that SET member values cannot themselves contain commas.

For example, a column specified as SET("one", "two") NOT NULL can have any of these values:

""
"one"
"two"
"one,two"

A SET can have a maximum of 64 different members.

MySQL stores SET values numerically, with the low-order bit of the stored value corresponding to the first set member. If you retrieve a SET value in a numeric context, the value retrieved has bits set corresponding to the set members that make up the column value. If a number is stored into a SET column, the bits that are set in the binary representation of the number determine the set members in the column value. Suppose a column is specified as SET("a","b","c","d"). Then the members have the following bit values:

SET member | Decimal value | Binary value
a | 1 | 0001
b | 2 | 0010
c | 4 | 0100
d | 8 | 1000

If you assign a value of 9 to this column, that is 1001 in binary, so the first and fourth SET value members "a" and "d" are selected and the resulting value is "a,d".

For a value containing more than one SET element, it does not matter what order the elements are listed in when you insert the value. It also doesn't not matter how many times a given element is listed in the value. When the value is retrieved later, each element in the value will appear once, with elements listed according to the order in which they were specified at table creation time. For example, if a column is specified as SET("a","b","c","d"), then "a,d", "d,a" and "d,a,a,d,d" will all appear as "a,d" when retrieved.

SET values are sorted numerically. NULL values sort before non-NULL SET values.

Normally, you perform a SELECT on a SET column using the LIKE operator or the FIND_IN_SET() function:

> SELECT * FROM tbl_name WHERE set_col LIKE '%value%';
> SELECT * FROM tbl_name WHERE FIND_IN_SET('value',set_col)>0;

But the following will also work:

> SELECT * FROM tbl_name WHERE set_col = 'val1,val2';
> SELECT * FROM tbl_name WHERE set_col & 1;

The first of these statements looks for an exact match. The second looks for values containing the first set member.

If you want to get all possible values for an SET column, you should use: SHOW COLUMNS FROM table_name LIKE set_column_name and parse the SET definition in the second column.

3.8 Choosing the right type for a column

For the most efficient use of storage, try to use the most precise type in all cases. For example, if an integer column will be used for values in the range between 1 and 99999, MEDIUMINT UNSIGNED is the best type.

Accurate representation of monetary values is a common problem. In MySQL, you should use the DECIMAL type. This is stored as a string, so no loss of accuracy should occur. If accuracy is not too important, the DOUBLE type may also be good enough.

For high precision, you can always convert to a fixed-point type stored in a BIGINT. This allows you to do all calculations with integers and convert results back to floating-point values only when necessary.

3.9 Column indexes

All MySQL column types can be indexed. Use of indexes on the relevant columns is the best way to improve the performance of SELECT operations.

A table may have up to 16 indexes. The maximum index length is 256 bytes, although this may be changed when compiling MySQL.

For CHAR and VARCHAR columns, you can index a prefix of a column. This is much faster and requires less disk space than indexing the whole column. The syntax to use in the CREATE TABLE statement to index a column prefix looks like this:

KEY index_name (col_name(length))

The example below creates an index for the first 10 characters of the name column:

> CREATE TABLE test (
           name CHAR(200) NOT NULL,
           KEY index_name (name(10)));

For BLOB and TEXT columns, you must index a prefix of the column, you cannot index the entire thing.

3.10 Multiple-column indexes

MySQL can create indexes on multiple columns. An index may consist of up to 15 columns. (On CHAR and VARCHAR columns you can also use a prefix of the column as a part of an index).

A multiple-column index can be considered a sorted array containing values that are created by concatenating the values of the indexed columns.

MySQL uses multiple-column indexes in such a way that queries are fast when you specify a known quantity for the first column of the index in a WHERE clause, even if you don't specify values for the other columns.

Suppose a table is created using the following specification:

> CREATE TABLE test (
           id INT NOT NULL,
           last_name CHAR(30) NOT NULL,
           first_name CHAR(30) NOT NULL,
           PRIMARY KEY (id),
           INDEX name (last_name,first_name));

Then the index name is an index over last_name and first_name. The index will be used for queries that specify values in a known range for last_name, or for both last_name and first_name. Therefore, the name index will be used in the following queries:

> SELECT * FROM test WHERE last_name="Widenius";

> SELECT * FROM test WHERE last_name="Widenius"
                          AND first_name="Michael";

> SELECT * FROM test WHERE last_name="Widenius"
                          AND (first_name="Michael" OR first_name="Monty");

> SELECT * FROM test WHERE last_name="Widenius"
                          AND first_name >="M" AND first_name < "N";

However, the name index will NOT be used in the following queries:

> SELECT * FROM test WHERE first_name="Michael";

> SELECT * FROM test WHERE last_name="Widenius"
                          OR first_name="Michael";

3.11 Using column types from other database engines

To make it easier to use code written for SQL implementations from other vendors, MySQL maps column types as shown in the table below. These mappings make it easier to move table definitions from other database engines to MySQL:

Other vendor type | MySQL type
BINARY(NUM) | CHAR(NUM) BINARY
CHAR VARYING(NUM) | VARCHAR(NUM)
FLOAT4 | FLOAT
FLOAT8 | DOUBLE
INT1 | TINYINT
INT2 | SMALLINT
INT3 | MEDIUMINT
INT4 | INT
INT8 | BIGINT
LONG VARBINARY | MEDIUMBLOB
LONG VARCHAR | MEDIUMTEXT
MIDDLEINT | MEDIUMINT
VARBINARY(NUM) | VARCHAR(NUM) BINARY

Column type mapping occurs at table creation time. If you create a table with types used by other vendors and then issue a DESCRIBE tbl_name statement, MySQL reports the table structure using the equivalent MySQL types.

© 1997-2000 TCX DataKonsult AB, 2000 SWsoft


MySQL v.3.23.11 language reference

4 Functions for use in SELECT and WHERE clauses

4.1 Grouping functions

4.2 Normal arithmetic operations

4.3 Bit functions

4.4 Logical operations

4.5 Comparison operators

4.6 String comparison functions

4.7 Cast operators

4.8 Control flow functions

4.9 Mathematical functions

4.10 String functions

4.11 Date and time functions

4.12 Miscellaneous functions

4.13 Functions for use with GROUP BY clauses

4 Functions for use in SELECT and WHERE clauses

A select_expression or where_definition in a SQL statement can consist of any expression using the functions described below.

An expression that contains NULL always produces a NULL value unless otherwise indicated in the documentation for the operators and functions involved in the expression.

Note: There must be no whitespace between a function name and the parenthesis following it. This helps the MySQL parser distinguish between function calls and references to tables or columns that happen to have the same name as a function. Spaces around arguments are permitted, though.

For the sake of brevity, examples display the output from the mysql program in abbreviated form. So this:

> select MOD(29,9);
1 rows in set (0.00 sec)

+-----------+
| mod(29,9) |
+-----------+
|         2 |
+-----------+

Is displayed like this:

> select MOD(29,9);
        -> 2

4.1 Grouping functions

( ... )
Parentheses. Use these to force the order of evaluation in an expression.
> select 1+2*3;
        -> 7
> select (1+2)*3;
        -> 9

4.2 Normal arithmetic operations

The usual arithmetic operators are available. Note that in the case of -, + and *, the result is calculated with BIGINT (64-bit) precision if both arguments are integers!

+
Addition
> select 3+5;
        -> 8
-
Subtraction
> select 3-5;
        -> -2
*
Multiplication
> select 3*5;
        -> 15
> select 18014398509481984*18014398509481984.0;
        -> 324518553658426726783156020576256.0
> select 18014398509481984*18014398509481984;
        -> 0
The result of the last expression is incorrect because the result of the integer multiplication exceeds the 64-bit range of BIGINT calculations.
/
Division
> select 3/5;
        -> 0.60
Division by zero produces a NULL result:
> select 102/(1-1);
        -> NULL
A division will be calculated with BIGINT arithmetic only if performed in a context where its result is converted to an integer!

4.3 Bit functions

MySQL uses BIGINT (64-bit) arithmetic for bit operations, so these operators have a maximum range of 64 bits.

|
Bitwise OR
> select 29 | 15;
        -> 31
&
Bitwise AND
> select 29 & 15;
        -> 13
<<
Shifts a longlong (BIGINT) number to the left.
> select 1 << 2
        -> 4
>>
Shifts a longlong (BIGINT) number to the right.
> select 4 >> 2
        -> 1
~
Invert all bits.
> select 5 & ~1
        -> 4
BIT_COUNT(N)
Returns the number of bits that are set in the argument N.
> select BIT_COUNT(29);
        -> 4

4.4 Logical operations

All logical functions return 1 (TRUE) or 0 (FALSE).

NOT
!
Logical NOT. Returns 1 if the argument is 0, otherwise returns 0. Exception: NOT NULL returns NULL.
> select NOT 1;
        -> 0
> select NOT NULL;
        -> NULL
> select ! (1+1);
        -> 0
> select ! 1+1;
        -> 1
The last example returns 1 because the expression evaluates the same way as (!1)+1.
OR
||
Logical OR. Returns 1 if either argument is not 0 and not NULL.
> select 1 || 0;
        -> 1
> select 0 || 0;
        -> 0
> select 1 || NULL;
        -> 1
AND
&&
Logical AND. Returns 0 if either argument is 0 or NULL, otherwise returns 1.
> select 1 && NULL;
        -> 0
> select 1 && 0;
        -> 0

4.5 Comparison operators

Comparison operations result in a value of 1 (TRUE), 0 (FALSE) or NULL. These functions work for both numbers and strings. Strings are automatically converted to numbers and numbers to strings as needed (as in Perl).

MySQL performs comparisons using the following rules:

  • If one or both arguments are NULL, the result of the comparison is NULL, except for the <=> operator.
  • If both arguments in a comparison operation are strings, they are compared as strings.
  • If both arguments are integers, they are compared as integers.
  • Hexadecimal values are treated as binary strings if not compared to a number.
  • If one of the arguments is a TIMESTAMP or DATETIME column and the other argument is a constant, the constant is converted to a timestamp before the comparison is performed. This is done to be more ODBC-friendly.
  • In all other cases, the arguments are compared as floating-point (real) numbers.

By default, string comparisons are done in case-independent fashion using the current character set (ISO-8859-1 Latin1 by default, which also works excellently for English).

The examples below illustrate conversion of strings to numbers for comparison operations:

> SELECT 1 > '6x';
         -> 0
> SELECT 7 > '6x';
         -> 1
> SELECT 0 > 'x6';
         -> 0
> SELECT 0 = 'x6';
         -> 1
=
Equal
> select 1 = 0;
        -> 0
> select '0' = 0;
        -> 1
> select '0.0' = 0;
        -> 1
> select '0.01' = 0;
        -> 0
> select '.01' = 0.01;
        -> 1
<>
!=
Not equal
> select '.01' <> '0.01';
        -> 1
> select .01 <> '0.01';
        -> 0
> select 'zapp' <> 'zappp';
        -> 1
<=
Less than or equal
> select 0.1 <= 2;
        -> 1
<
Less than
> select 2 <= 2;
        -> 1
>=
Greater than or equal
> select 2 >= 2;
        -> 1
>
Greater than
> select 2 > 2;
        -> 0
<=>
Null safe equal
> select 1 <=> 1, NULL <=> NULL, 1 <=> NULL;
        -> 1 1 0
IS NULL
IS NOT NULL
Test whether or not a value is or is not NULL
> select 1 IS NULL, 0 IS NULL, NULL IS NULL:
        -> 0 0 1
> select 1 IS NOT NULL, 0 IS NOT NULL, NULL IS NOT NULL;
        -> 1 1 0
expr BETWEEN min AND max
If expr is greater than or equal to min and expr is less than or equal to max, BETWEEN returns 1, otherwise it returns 0. This is equivalent to the expression (min <= expr AND expr <= max) if all the arguments are of the same type. The first argument (expr) determines how the comparison is performed as follows:
  • If expr is a TIMESTAMP, DATE or DATETIME column, min and max are formated to a the same format if they are constants.
  • If expr is a case-insensitive string expression, a case-insensitive string comparison is done.
  • If expr is a case-sensitive string expression, a case-sensitive string comparison is done.
  • If expr is an integer expression, an integer comparison is done.
  • Otherwise, a floating-point (real) comparison is done.
> select 1 BETWEEN 2 AND 3;
        -> 0
> select 'b' BETWEEN 'a' AND 'c';
        -> 1
> select 2 BETWEEN 2 AND '3';
        -> 1
> select 2 BETWEEN 2 AND 'x-3';
        -> 0
expr IN (value,...)
Returns 1 if expr is any of the values in the IN list, else returns 0. If all values are constants, then all values are evaluated according to the type of expr and sorted. The search for the item is then done using a binary search. This means IN is very quick if the IN value list consists entirely of constants. If expr is a case-sensitive string expression, the string comparison is performed in case-sensitive fashion.
> select 2 IN (0,3,5,'wefwf');
        -> 0
> select 'wefwf' IN (0,3,5,'wefwf');
        -> 1
expr NOT IN (value,...)
Same as NOT (expr IN (value,...)).
ISNULL(expr)
If expr is NULL, ISNULL() returns 1, otherwise it returns 0.
> select ISNULL(1+1);
        -> 0
> select ISNULL(1/0);
        -> 1
Note that a comparison of NULL values using = will always be false!
COALESCE(list)
Returns first non-NULL element in list.
> select COALESCE(NULL,1);
        -> 1
> select COALESCE(NULL,NULL,NULL);
        -> NULL
INTERVAL(N,N1,N2,N3,...)
Returns 0 if N < N1, 1 if N < N2 and so on. All arguments are treated as integers. It is required that N1 < N2 < N3 < ... < Nn for this function to work correctly. This is because a binary search is used (very fast).
> select INTERVAL(23, 1, 15, 17, 30, 44, 200);
        -> 3
> select INTERVAL(10, 1, 10, 100, 1000);
        -> 2
> select INTERVAL(22, 23, 30, 44, 200);
        -> 0

4.6 String comparison functions

Normally, if any expression in a string comparison is case sensitive, the comparison is performed in case-sensitive fashion.

expr LIKE pat [ESCAPE 'escape-char']
Pattern matching using SQL simple regular expression comparison. Returns 1 (TRUE) or 0 (FALSE). With LIKE you can use the following two wildcard characters in the pattern:
% Matches any number of characters, even zero characters
_ Matches exactly one character
> select 'David!' LIKE 'David_';
        -> 1
> select 'David!' LIKE '%D%v%';
        -> 1
To test for literal instances of a wildcard character, precede the character with the escape character. If you don't specify the ESCAPE character, `\' is assumed:
\% Matches one % character
\_ Matches one _ character
> select 'David!' LIKE 'David\_';
        -> 0
> select 'David_' LIKE 'David\_';
        -> 1
To specify a different escape character, use the ESCAPE clause:
> select 'David_' LIKE 'David|_' ESCAPE '|';
        -> 1
LIKE is allowed on numeric expressions! (This is a MySQL extension to the ANSI SQL LIKE.)
> select 10 LIKE '1%';
        -> 1
Note: Because MySQL uses the C escape syntax in strings (e.g., `\n'), you must double any `\' that you use in your LIKE strings. For example, to search for `\n', specify it as `\\n'. To search for `\', specify it as `\\\\' (the backslashes are stripped once by the parser, and another time when the pattern match is done, leaving a single backslash to be matched).
expr NOT LIKE pat [ESCAPE 'escape-char']
Same as NOT (expr LIKE pat [ESCAPE 'escape-char']).
expr REGEXP pat
expr RLIKE pat
Performs a pattern match of a string expression expr against a pattern pat. The pattern can be an extended regular expression. See section H Description of MySQL regular expression syntax. Returns 1 if expr matches pat, otherwise returns 0. RLIKE is a synonym for REGEXP, provided for mSQL compatibility. Note: Because MySQL uses the C escape syntax in strings (e.g., `\n'), you must double any `\' that you use in your REGEXP strings. In MySQL 3.23.4 REGEXP is case insensitive for normal (not binary) strings.
> select 'Monty!' REGEXP 'm%y%%';
        -> 0
> select 'Monty!' REGEXP '.*';
        -> 1
> select 'new*\n*line' REGEXP 'new\\*.\\*line';
        -> 1
> select "a" REGEXP "A", "a" REGEXP BINARY "A";
        -> 1  0
REGEXP and RLIKE use the current character set (ISO-8859-1 Latin1 by default) when deciding the type of a character.
expr NOT REGEXP pat
expr NOT RLIKE pat
Same as NOT (expr REGEXP pat).
STRCMP(expr1,expr2)
STRCMP() returns 0 if the strings are the same, -1 if the first argument is smaller than the second according to the current sort order, and 1 otherwise.
> select STRCMP('text', 'text2');
        -> -1
> select STRCMP('text2', 'text');
        -> 1
> select STRCMP('text', 'text');
        -> 0

4.7 Cast operators

BINARY
The BINARY operator casts the string following it to a binary string. This is an easy way to force a column comparison to be case sensitive even if the column isn't defined as BINARY or BLOB.
> select "a" = "A";
        -> 1
> select BINARY "a" = "A";
        -> 0
BINARY was introduced in MySQL 3.23.0

4.8 Control flow functions

IFNULL(expr1,expr2)
If expr1 is not NULL, IFNULL() returns expr1, else it returns expr2. IFNULL() returns a numeric or string value, depending on the context in which it is used.
> select IFNULL(1,0);
        -> 1
> select IFNULL(0,10);
        -> 0
> select IFNULL(1/0,10);
        -> 10
> select IFNULL(1/0,'yes');
        -> 'yes'
IF(expr1,expr2,expr3)
If expr1 is TRUE (expr1 <> 0 and expr1 <> NULL) then IF() returns expr2, else it returns expr3. IF() returns a numeric or string value, depending on the context in which it is used.
> select IF(1>2,2,3);
        -> 3
> select IF(1<2,'yes','no');
        -> 'yes'
> select IF(strcmp('test','test1'),'yes','no');
        -> 'no'
expr1 is evaluated as an integer value, which means that if you are testing floating-point or string values, you should do so using a comparison operation.
> select IF(0.1,1,0);
        -> 0
> select IF(0.1<>0,1,0);
        -> 1
In the first case above, IF(0.1) returns 0 because 0.1 is converted to an integer value, resulting in a test of IF(0). This may not be what you expect. In the second case, the comparison tests the original floating-point value to see whether it is non-zero. The result of the comparison is used as an integer.
CASE value WHEN [compare-value] THEN result [WHEN [compare-value] THEN result ...] [ELSE result] END
CASE WHEN [condition] THEN result [WHEN [condition] THEN result ...] [ELSE result] END
The first version returns the result where value=compare-value. The second version returns the result for the first condition which is true. If there was no matching result value, then the result after ELSE is returned. If there is no ELSE part then NULL is returned.
> SELECT CASE 1 WHEN 1 THEN "one" WHEN 2 THEN "two" ELSE "more" END;
       -> "one"
> SELECT CASE WHEN 1>0 THEN "true" ELSE "false" END;
       -> "true"
> SELECT CASE BINARY "B" when "a" then 1 when "b" then 2 END;
       -> NULL

4.9 Mathematical functions

All mathematical functions return NULL in case of an error.

-
Unary minus. Changes the sign of the argument.
> select - 2;
        -> -2
Note that if this operator is used with a BIGINT, the return value is a BIGINT! This means that you should avoid using - on integers that may have the value of -2^63!
ABS(X)
Returns the absolute value of X.
> select ABS(2);
        -> 2
> select ABS(-32);
        -> 32
This function is safe to use with BIGINT values.
SIGN(X)
Returns the sign of the argument as -1, 0 or 1, depending on whether X is negative, zero, or positive.
> select SIGN(-32);
        -> -1
> select SIGN(0);
        -> 0
> select SIGN(234);
        -> 1
MOD(N,M)
%
Modulo (like the % operator in C). Returns the remainder of N divided by M.
> select MOD(234, 10);
        -> 4
> select 253 % 7;
        -> 1
> select MOD(29,9);
        -> 2
This function is safe to use with BIGINT values.
FLOOR(X)
Returns the largest integer value not greater than X.
> select FLOOR(1.23);
        -> 1
> select FLOOR(-1.23);
        -> -2
Note that the return value is converted to a BIGINT!
CEILING(X)
Returns the smallest integer value not less than X.
> select CEILING(1.23);
        -> 2
> select CEILING(-1.23);
        -> -1
Note that the return value is converted to a BIGINT!
ROUND(X)
Returns the argument X, rounded to the nearest integer.
> select ROUND(-1.23);
        -> -1
> select ROUND(-1.58);
        -> -2
> select ROUND(1.58);
        -> 2
ROUND(X,D)
Returns the argument X, rounded to a number with D decimals. If D is 0, the result will have no decimal point or fractional part.
> select ROUND(1.298, 1);
        -> 1.3
> select ROUND(1.298, 0);
        -> 1
EXP(X)
Returns the value of e (the base of natural logarithms) raised to the power of X.
> select EXP(2);
        -> 389056
> select EXP(-2);
        -> 0.135335
LOG(X)
Returns the natural logarithm of X.
> select LOG(2);
        -> 0.693147
> select LOG(-2);
        -> NULL
If you want the log of a number X to some arbitary base B, use the formula LOG(X)/LOG(B).
LOG10(X)
Returns the base-10 logarithm of X.
> select LOG10(2);
        -> 0.301030
> select LOG10(100);
        -> 2.000000
> select LOG10(-100);
        -> NULL
POW(X,Y)
POWER(X,Y)
Returns the value of X raised to the power of Y.
> select POW(2,2);
        -> 4.000000
> select POW(2,-2);
        -> 0.250000
SQRT(X)
Returns the non-negative square root of X.
> select SQRT(4);
        -> 2.000000
> select SQRT(20);
        -> 4.472136
PI()
Returns the value of PI.
> select PI();
        -> 3.141593
COS(X)
Returns the cosine of X, where X is given in radians.
> select COS(PI());
        -> -1.000000
SIN(X)
Returns the sine of X, where X is given in radians.
> select SIN(PI());
        -> 0.000000
TAN(X)
Returns the tangent of X, where X is given in radians.
> select TAN(PI()+1);
        -> 1.557408
ACOS(X)
Returns the arc cosine of X, that is, the value whose cosine is X. Returns NULL if X is not in the range -1 to 1.
> select ACOS(1);
        -> 0.000000
> select ACOS(1.0001);
        -> NULL
> select ACOS(0);
        -> 1.570796
ASIN(X)
Returns the arc sine of X, that is, the value whose sine is X. Returns NULL if X is not in the range -1 to 1.
> select ASIN(0.2);
        -> 0.201358
> select ASIN('foo');
        -> 0.000000
ATAN(X)
Returns the arc tangent of X, that is, the value whose tangent is X.
> select ATAN(2);
        -> 1.107149
> select ATAN(-2);
        -> -1.107149
ATAN2(X,Y)
Returns the arc tangent of the two variables X and Y. It is similar to calculating the arc tangent of Y / X, except that the signs of both arguments are used to determine the quadrant of the result.
> select ATAN(-2,2);
        -> -0.785398
> select ATAN(PI(),0);
        -> 1.570796
COT(X)
Returns the cotangent of X.
> select COT(12);
        -> -1.57267341
> select COT(0);
        -> NULL
RAND()
RAND(N)
Returns a random floating-point value in the range 0 to 1.0. If an integer argument N is specified, it is used as the seed value.
> select RAND();
        -> 0.5925
> select RAND(20);
        -> 0.1811
> select RAND(20);
        -> 0.1811
> select RAND();
        -> 0.2079
> select RAND();
        -> 0.7888
You can't use a column with RAND() values in an ORDER BY clause, because ORDER BY would evaluate the column multiple times. In MySQL 3.23, you can however do: SELECT * FROM table_name ORDER BY RAND() This is useful to get a random sample of a set SELECT * FROM table1,table2 WHERE a=b AND c<d ORDER BY RAND() LIMIT 1000. Note that a RAND() in a WHERE clause will be re-evaluated every time the WHERE is executed.
LEAST(X,Y,...)
With two or more arguments, returns the smallest (minimum-valued) argument. The arguments are compared using the following rules:
  • If the return value is used in an INTEGER context, or all arguments are integer-valued, they are compared as integers.
  • If the return value is used in a REAL context, or all arguments are real-valued, they are compared as reals.
  • If any argument is a case-sensitive string, the arguments are compared as case-sensitive strings.
  • In other cases, the arguments are compared as case-insensitive strings.
> select LEAST(2,0);
        -> 0
> select LEAST(34.0,3.0,5.0,760);
        -> 3.0
> select LEAST("B","A","C");
        -> "A"
In MySQL versions prior to 3.22.5, you can use MIN() instead of LEAST.
GREATEST(X,Y,...)
Returns the largest (maximum-valued) argument. The arguments are compared using the same rules as for LEAST.
> select GREATEST(2,0);
        -> 2
> select GREATEST(34.0,3.0,5.0,760);
        -> 760
> select GREATEST("B","A","C");
        -> "C"
In MySQL versions prior to 3.22.5, you can use MAX() instead of GREATEST.
DEGREES(X)
Returns the argument X, converted from radians to degrees.
> select DEGREES(PI());
        -> 180.000000
RADIANS(X)
Returns the argument X, converted from degrees to radians.
> select RADIANS(90);
        -> 1.570796
TRUNCATE(X,D)
Returns the number X, truncated to D decimals. If D is 0, the result will have no decimal point or fractional part.
> select TRUNCATE(1.223,1);
        -> 1.2
> select TRUNCATE(1.999,1);
        -> 1.9
> select TRUNCATE(1.999,0);
        -> 1

4.10 String functions

String-valued functions return NULL if the length of the result would be greater than the max_allowed_packet server parameter.

For functions that operate on string positions, the first position is numbered 1.

ASCII(str)
Returns the ASCII code value of the leftmost character of the string str. Returns 0 if str is the empty string. Returns NULL if str is NULL.
> select ASCII('2');
        -> 50
> select ASCII(2);
        -> 50
> select ASCII('dx');
        -> 100
See also the ORD() function.
ORD(str)
If the leftmost character of the string str is a multi-byte character, returns the code of multi-byte character by returning the ASCII code value of the character in the format of: ((first byte ASCII code)*256+(second byte ASCII code))[*256+third byte ASCII code...]. If the leftmost character is not a multi-byte character, returns the same value as the like ASCII() function does.
> select ORD('2');
        -> 50
CONV(N,from_base,to_base)
Converts numbers between different number bases. Returns a string representation of the number N, converted from base from_base to base to_base. Returns NULL if any argument is NULL. The argument N is interpreted as an integer, but may be specified as an integer or a string. The minimum base is 2 and the maximum base is 36. If to_base is a negative number, N is regarded as a signed number. Otherwise, N is treated as unsigned. CONV works with 64-bit precision.
> select CONV("a",16,2);
        -> '1010'
> select CONV("6E",18,8);
        -> '172'
> select CONV(-17,10,-18);
        -> '-H'
> select CONV(10+"10"+'10'+0xa,10,10);
        -> '40'
BIN(N)
Returns a string representation of the binary value of N, where N is a longlong (BIGINT) number. This is equivalent to CONV(N,10,2). Returns NULL if N is NULL.
> select BIN(12);
        -> '1100'
OCT(N)
Returns a string representation of the octal value of N, where N is a longlong number. This is equivalent to CONV(N,10,8). Returns NULL if N is NULL.
> select OCT(12);
        -> '14'
HEX(N)
Returns a string representation of the hexadecimal value of N, where N is a longlong (BIGINT) number. This is equivalent to CONV(N,10,16). Returns NULL if N is NULL.
> select HEX(255);
        -> 'FF'
CHAR(N,...)
CHAR() interprets the arguments as integers and returns a string consisting of the characters given by the ASCII code values of those integers. NULL values are skipped.
> select CHAR(77,121,83,81,'76');
        -> 'MySQL'
> select CHAR(77,73,'73');
        -> 'MMM'
CONCAT(str1,str2,...)
Returns the string that results from concatenating the arguments. Returns NULL if any argument is NULL. May have more than 2 arguments. A numeric argument is converted to the equivalent string form.
> select CONCAT('My', 'S', 'QL');
        -> 'MySQL'
> select CONCAT('My', NULL, 'QL');
        -> NULL
> select CONCAT(14.3);
        -> '14.3'
LENGTH(str)
OCTET_LENGTH(str)
CHAR_LENGTH(str)
CHARACTER_LENGTH(str)
Returns the length of the string str.
> select LENGTH('text');
        -> 4
> select OCTET_LENGTH('text');
        -> 4
Note that for CHAR_LENGTH(), multi-byte characters are only counted once.
LOCATE(substr,str)
POSITION(substr IN str)
Returns the position of the first occurrence of substring substr in string str. Returns 0 if substr is not in str.
> select LOCATE('bar', 'foobarbar');
        -> 4
> select LOCATE('xbar', 'foobar');
        -> 0
This function is multi-byte safe.
LOCATE(substr,str,pos)
Returns the position of the first occurrence of substring substr in string str, starting at position pos. Returns 0 if substr is not in str.
> select LOCATE('bar', 'foobarbar',5);
        -> 7
This function is multi-byte safe.
INSTR(str,substr)
Returns the position of the first occurrence of substring substr in string str. This is the same as the two-argument form of LOCATE(), except that the arguments are swapped.
> select INSTR('foobarbar', 'bar');
        -> 4
> select INSTR('xbar', 'foobar');
        -> 0
This function is multi-byte safe.
LPAD(str,len,padstr)
Returns the string str, left-padded with the string padstr until str is len characters long.
> select LPAD('hi',4,'??');
        -> '??hi'
RPAD(str,len,padstr)
Returns the string str, right-padded with the string padstr until str is len characters long.
> select RPAD('hi',5,'?');
        -> 'hi???'
LEFT(str,len)
Returns the leftmost len characters from the string str.
> select LEFT('foobarbar', 5);
        -> 'fooba'
This function is multi-byte safe.
RIGHT(str,len)
Returns the rightmost len characters from the string str.
> select RIGHT('foobarbar', 4);
        -> 'rbar'
This function is multi-byte safe.
SUBSTRING(str,pos,len)
SUBSTRING(str FROM pos FOR len)
MID(str,pos,len)
Returns a substring len characters long from string str, starting at position pos. The variant form that uses FROM is ANSI SQL92 syntax.
> select SUBSTRING('Quadratically',5,6);
        -> 'ratica'
This function is multi-byte safe.
SUBSTRING(str,pos)
SUBSTRING(str FROM pos)
Returns a substring from string str starting at position pos.
> select SUBSTRING('Quadratically',5);
        -> 'ratically'
> select SUBSTRING('foobarbar' FROM 4);
        -> 'barbar'
This function is multi-byte safe.
SUBSTRING_INDEX(str,delim,count)
Returns the substring from string str after count occurrences of the delimiter delim. If count is positive, everything to the left of the final delimiter (counting from the left) is returned. If count is negative, everything to the right of the final delimiter (counting from the right) is returned.
> select SUBSTRING_INDEX('www.mysql.com', '.', 2);
        -> 'www.mysql'
> select SUBSTRING_INDEX('www.mysql.com', '.', -2);
        -> 'mysql.com'
This function is multi-byte safe.
LTRIM(str)
Returns the string str with leading space characters removed.
> select LTRIM('  barbar');
        -> 'barbar'
RTRIM(str)
Returns the string str with trailing space characters removed.
> select RTRIM('barbar   ');
        -> 'barbar'
This function is multi-byte safe.
TRIM([[BOTH | LEADING | TRAILING] [remstr] FROM] str)
Returns the string str with all remstr prefixes and/or suffixes removed. If none of the specifiers BOTH, LEADING or TRAILING are given, BOTH is assumed. If remstr is not specified, spaces are removed.
> select TRIM('  bar   ');
        -> 'bar'
> select TRIM(LEADING 'x' FROM 'xxxbarxxx');
        -> 'barxxx'
> select TRIM(BOTH 'x' FROM 'xxxbarxxx');
        -> 'bar'
> select TRIM(TRAILING 'xyz' FROM 'barxxyz');
        -> 'barx'
This function is multi-byte safe.
SOUNDEX(str)
Returns a soundex string from str. Two strings that sound ``about the same'' should have identical soundex strings. A ``standard'' soundex string is 4 characters long, but the SOUNDEX() function returns an arbitrarily long string. You can use SUBSTRING() on the result to get a ``standard'' soundex string. All non-alphanumeric characters are ignored in the given string. All international alpha characters outside the A-Z range are treated as vowels.
> select SOUNDEX('Hello');
        -> 'H400'
> select SOUNDEX('Quadratically');
        -> 'Q36324'
SPACE(N)
Returns a string consisting of N space characters.
> select SPACE(6);
        -> '      '
REPLACE(str,from_str,to_str)
Returns the string str with all all occurrences of the string from_str replaced by the string to_str.
> select REPLACE('www.mysql.com', 'w', 'Ww');
        -> 'WwWwWw.mysql.com'
This function is multi-byte safe.
REPEAT(str,count)
Returns a string consisting of the string str repeated count times. If count <= 0, returns an empty string. Returns NULL if str or count are NULL.
> select REPEAT('MySQL', 3);
        -> 'MySQLMySQLMySQL'
REVERSE(str)
Returns the string str with the order of the characters reversed.
> select REVERSE('abc');
        -> 'cba'
This function is multi-byte safe.
INSERT(str,pos,len,newstr)
Returns the string str, with the substring beginning at position pos and len characters long replaced by the string newstr.
> select INSERT('Quadratic', 3, 4, 'What');
        -> 'QuWhattic'
This function is multi-byte safe.
ELT(N,str1,str2,str3,...)
Returns str1 if N = 1, str2 if N = 2, and so on. Returns NULL if N is less than 1 or greater than the number of arguments. ELT() is the complement of FIELD().
> select ELT(1, 'ej', 'Heja', 'hej', 'foo');
        -> 'ej'
> select ELT(4, 'ej', 'Heja', 'hej', 'foo');
        -> 'foo'
FIELD(str,str1,str2,str3,...)
Returns the index of str in the str1, str2, str3, ... list. Returns 0 if str is not found. FIELD() is the complement of ELT().
> select FIELD('ej', 'Hej', 'ej', 'Heja', 'hej', 'foo');
        -> 2
> select FIELD('fo', 'Hej', 'ej', 'Heja', 'hej', 'foo');
        -> 0
FIND_IN_SET(str,strlist)
Returns a value 1 to N if the string str is in the list strlist consisting of N substrings. A string list is a string composed of substrings separated by `,' characters. If the first argument is a constant string and the second is a column of type SET, the FIND_IN_SET() function is optimized to use bit arithmetic! Returns 0 if str is not in strlist or if strlist is the empty string. Returns NULL if either argument is NULL. This function will not work properly if the first argument contains a `,'.
> SELECT FIND_IN_SET('b','a,b,c,d');
        -> 2
MAKE_SET(bits,str1,str2,...)
Returns a set (a string containing substrings separated by `,' characters) consisting of the strings that have the corresponding bit in bits set. str1 corresponds to bit 0, str2 to bit 1, etc. NULL strings in str1, str2, ... are not appended to the result.
> SELECT MAKE_SET(1,'a','b','c');
        -> 'a'
> SELECT MAKE_SET(1 | 4,'hello','nice','world');
        -> 'hello,world'
> SELECT MAKE_SET(0,'a','b','c');
        -> ''
EXPORT_SET(bits,on,off,[separator,[number_of_bits]])
Returns a string where for every bit set in 'bit', you get a 'on' string and for every reset bit you get an 'off' string. Each string is separated with 'separator' (default ',') and only 'number_of_bits' (default 64) of 'bits' is used.
> select EXPORT_SET(5,'Y','N',',',4)
        -> Y,N,Y,N
LCASE(str)
LOWER(str)
Returns the string str with all characters changed to lowercase according to the current character set mapping (the default is ISO-8859-1 Latin1). This function is multi-byte safe.
> select LCASE('QUADRATICALLY');
        -> 'quadratically'
UCASE(str)
UPPER(str)
Returns the string str with all characters changed to uppercase according to the current character set mapping (the default is ISO-8859-1 Latin1).
> select UCASE('Hej');
        -> 'HEJ'
This function is multi-byte safe.
LOAD_FILE(file_name)
Reads the file and returns the file contents as a string. The file must be on the server, you must specify the full pathname to the file, and you must have the file privilege. The file must be readable by all and be smaller than max_allowed_packet. If the file doesn't exist or can't be read due to one of the above reasons, the function returns NULL.
> UPDATE table_name
           SET blob_column=LOAD_FILE("/tmp/picture")
           WHERE id=1;

MySQL automatically converts numbers to strings as necessary, and vice versa:

> SELECT 1+"1";
        -> 2
> SELECT CONCAT(2,' test');
        -> '2 test'

If you want to convert a number to a string explicitly, pass it as the argument to CONCAT().

If a string function is given a binary string as an argument, the resulting string is also a binary string. A number converted to a string is treated as a binary string. This only affects comparisons.

4.11 Date and time functions

See section 3.6 Date and time types for a description of the range of values each type has, and the valid formats in which date and time values may be specified.

Here is an example that uses date functions. The query below selects all records with a date_col value from within the last 30 days:

> SELECT something FROM table
           WHERE TO_DAYS(NOW()) - TO_DAYS(date_col) <= 30;
DAYOFWEEK(date)
Returns the weekday index for date (1 = Sunday, 2 = Monday, ... 7 = Saturday). These index values correspond to the ODBC standard.
> select DAYOFWEEK('1998-02-03');
        -> 3
WEEKDAY(date)
Returns the weekday index for date (0 = Monday, 1 = Tuesday, ... 6 = Sunday).
> select WEEKDAY('1997-10-04 22:23:00');
        -> 5
> select WEEKDAY('1997-11-05');
        -> 2
DAYOFMONTH(date)
Returns the day of the month for date, in the range 1 to 31.
> select DAYOFMONTH('1998-02-03');
        -> 3
DAYOFYEAR(date)
Returns the day of the year for date, in the range 1 to 366.
> select DAYOFYEAR('1998-02-03');
        -> 34
MONTH(date)
Returns the month for date, in the range 1 to 12.
> select MONTH('1998-02-03');
        -> 2
DAYNAME(date)
Returns the name of the weekday for date.
> select DAYNAME("1998-02-05");
        -> 'Thursday'
MONTHNAME(date)
Returns the name of the month for date.
> select MONTHNAME("1998-02-05");
        -> 'February'
QUARTER(date)
Returns the quarter of the year for date, in the range 1 to 4.
> select QUARTER('98-04-01');
        -> 2
WEEK(date)
WEEK(date,first)
With a single argument, returns the week for date, in the range 0 to 53 (yes, there may be the beginnings of a 53 week), for locations where Sunday is the first day of the week. The two-argument form of WEEK() allows you to specify whether the week starts on Sunday or Monday. The week starts on Sunday if the second argument is 0, on Monday if the second argument is 1.
> select WEEK('1998-02-20');
        -> 7
> select WEEK('1998-02-20',0);
        -> 7
> select WEEK('1998-02-20',1);
        -> 8
> select WEEK('1998-12-31',1);
        -> 53
YEAR(date)
Returns the year for date, in the range 1000 to 9999.
> select YEAR('98-02-03');
        -> 1998
YEARWEEK(date)
YEARWEEK(date,first)
Returns year and week for a data. The second arguments works exactly like the second argument to WEEK(). Note that the year may be different from the year in the date argument for the first and the last week of the year!
> select YEARWEEK('1987-01-01');
        -> 198653
HOUR(time)
Returns the hour for time, in the range 0 to 23.
> select HOUR('10:05:03');
        -> 10
MINUTE(time)
Returns the minute for time, in the range 0 to 59.
> select MINUTE('98-02-03 10:05:03');
        -> 5
SECOND(time)
Returns the second for time, in the range 0 to 59.
> select SECOND('10:05:03');
        -> 3
PERIOD_ADD(P,N)
Adds N months to period P (in the format YYMM or YYYYMM). Returns a value in the format YYYYMM. Note that the period argument P is not a date value.
> select PERIOD_ADD(9801,2);
        -> 199803
PERIOD_DIFF(P1,P2)
Returns the number of months between periods P1 and P2. P1 and P2 should be in the format YYMM or YYYYMM. Note that the period arguments P1 and P2 are not date values.
> select PERIOD_DIFF(9802,199703);
        -> 11
DATE_ADD(date,INTERVAL expr type)
DATE_SUB(date,INTERVAL expr type)
ADDDATE(date,INTERVAL expr type)
SUBDATE(date,INTERVAL expr type)
These functions perform date arithmetic. They are new for MySQL 3.22. ADDDATE() and SUBDATE() are synonyms for DATE_ADD() and DATE_SUB(). In MySQL 3.23, you can use + and - instead of DATE_ADD() and DATE_SUB(). (See example) date is a DATETIME or DATE value specifying the starting date. expr is an expression specifying the interval value to be added or substracted from the starting date. expr is a string; it may start with a `-' for negative intervals. type is a keyword indicating how the expression should be interpreted. The EXTRACT(type FROM date) function returns the 'type' interval from the date. The following table shows how the type and expr arguments are related:
type value | Meaning | Expected expr format
SECOND | Seconds | SECONDS
MINUTE | Minutes | MINUTES
HOUR | Hours | HOURS
DAY | Days | DAYS
MONTH | Months | MONTHS
YEAR | Years | YEARS
MINUTE_SECOND | Minutes and seconds | "MINUTES:SECONDS"
HOUR_MINUTE | Hours and minutes | "HOURS:MINUTES"
DAY_HOUR | Days and hours | "DAYS HOURS"
YEAR_MONTH | Years and months | "YEARS-MONTHS"
HOUR_SECOND | Hours, minutes, | "HOURS:MINUTES:SECONDS"
DAY_MINUTE | Days, hours, minutes | "DAYS HOURS:MINUTES"
DAY_SECOND | Days, hours, minutes, seconds | "DAYS HOURS:MINUTES:SECONDS"
MySQL allows any punctuation delimiter in the expr format. The ones shown in the table are the suggested delimiters. If the date argument is a DATE value and your calculations involve only YEAR, MONTH and DAY parts (that is, no time parts), the result is a DATE value. Otherwise the result is a DATETIME value.
> SELECT "1997-12-31 23:59:59" + INTERVAL 1 SECOND;
        -> 1998-01-01 00:00:00
> SELECT INTERVAL 1 DAY + "1997-12-31";
        -> 1998-01-01
> SELECT "1998-01-01" - INTERVAL 1 SECOND;
       -> 1997-12-31 23:59:59
> SELECT DATE_ADD("1997-12-31 23:59:59",
                       INTERVAL 1 SECOND);
        -> 1998-01-01 00:00:00
> SELECT DATE_ADD("1997-12-31 23:59:59",
                       INTERVAL 1 DAY);
        -> 1998-01-01 23:59:59
> SELECT DATE_ADD("1997-12-31 23:59:59",
                       INTERVAL "1:1" MINUTE_SECOND);
        -> 1998-01-01 00:01:00
> SELECT DATE_SUB("1998-01-01 00:00:00",
                       INTERVAL "1 1:1:1" DAY_SECOND);
        -> 1997-12-30 22:58:59
> SELECT DATE_ADD("1998-01-01 00:00:00",
                       INTERVAL "-1 10" DAY_HOUR);
        -> 1997-12-30 14:00:00
> SELECT DATE_SUB("1998-01-02", INTERVAL 31 DAY);
        -> 1997-12-02
> SELECT EXTRACT(YEAR FROM "1999-07-02");
       -> 1999
> SELECT EXTRACT(YEAR_MONTH FROM "1999-07-02 01:02:03");
       -> 199907
> SELECT EXTRACT(DAY_MINUTE FROM "1999-07-02 01:02:03");
       -> 20102
If you specify an interval value that is too short (does not include all the interval parts that would be expected from the type keyword), MySQL assumes you have left out the leftmost parts of the interval value. For example, if you specify a type of DAY_SECOND, the value of expr is expected to have days, hours, minutes and seconds parts. If you specify a value like "1:10", MySQL assumes that the days and hours parts are missing and the value represents minutes and seconds. In other words, "1:10" DAY_SECOND is interpreted in such a way that it is equivalent to "1:10" MINUTE_SECOND. This is analogous to the way that MySQL interprets TIME values as representing elapsed time rather than as time of day. If you use really incorrect dates, the result is NULL. If you add MONTH, YEAR_MONTH or YEAR and the resulting date has a day that is larger than the maximum day for the new month, the day is adjusted to the maximum days in the new month.
> select DATE_ADD('1998-01-30', Interval 1 month);
        -> 1998-02-28
Note from the preceding example that the word INTERVAL and the type keyword are not case sensitive.
TO_DAYS(date)
Given a date date, returns a daynumber (the number of days since year 0).
> select TO_DAYS(950501);
        -> 728779
> select TO_DAYS('1997-10-07');
        -> 729669
TO_DAYS() is not intended for use with values that precede the advent of the Gregorian calendar (1582) as it doesn't take in account the days that was lost when the calender was changed.
FROM_DAYS(N)
Given a daynumber N, returns a DATE value.
> select FROM_DAYS(729669);
        -> '1997-10-07'
FROM_DAYS() is not intended for use with values that precede the advent of the Gregorian calendar (1582).
DATE_FORMAT(date,format)
Formats the date value according to the format string. The following specifiers may be used in the format string:
%M | Month name (January..December)
%W | Weekday name (Sunday..Saturday)
%D | Day of the month with english suffix (1st, 2nd, 3rd, etc.)
%Y | Year, numeric, 4 digits
%y | Year, numeric, 2 digits
%X | Year for the week where Sunday is the first day of the week, numeric, 4 digits, used with '%V'
%x | Year for the week, where Monday is the first day of the week, numeric, 4 digits, used with '%v'
%a | Abbreviated weekday name (Sun..Sat)
%d | Day of the month, numeric (00..31)
%e | Day of the month, numeric (0..31)
%m | Month, numeric (01..12)
%c | Month, numeric (1..12)
%b | Abbreviated month name (Jan..Dec)
%j | Day of year (001..366)
%H | Hour (00..23)
%k | Hour (0..23)
%h | Hour (01..12)
%I | Hour (01..12)
%l | Hour (1..12)
%i | Minutes, numeric (00..59)
%r | Time, 12-hour (hh:mm:ss [AP]M)
%T | Time, 24-hour (hh:mm:ss)
%S | Seconds (00..59)
%s | Seconds (00..59)
%p | AM or PM
%w | Day of the week (0=Sunday..6=Saturday)
%U | Week (0..53), where Sunday is the first day of the week
%u | Week (0..53), where Monday is the first day of the week
%V | Week (1..53), where Sunday is the first day of the week. Used with '%X'
%v | Week (1..53), where Monday is the first day of the week. Used with '%x'
%% A literal `%'.
All other characters are just copied to the result without interpretation.
> select DATE_FORMAT('1997-10-04 22:23:00', '%W %M %Y');
        -> 'Saturday October 1997'
> select DATE_FORMAT('1997-10-04 22:23:00', '%H:%i:%s');
        -> '22:23:00'
> select DATE_FORMAT('1997-10-04 22:23:00',
                          '%D %y %a %d %m %b %j');
        -> '4th 97 Sat 04 10 Oct 277'
> select DATE_FORMAT('1997-10-04 22:23:00',
                          '%H %k %I %r %T %S %w');
        -> '22 22 10 10:23:00 PM 22:23:00 00 6'
> select DATE_FORMAT('1999-01-01', '%X %V');
        -> '1998 52'
As of MySQL 3.23, the % character is required before format specifier characters. In earlier versions of MySQL, % was optional.
TIME_FORMAT(time,format)
This is used like the DATE_FORMAT() function above, but the format string may contain only those format specifiers that handle hours, minutes and seconds. Other specifiers produce a NULL value or 0.
CURDATE()
CURRENT_DATE
Returns today's date as a value in 'YYYY-MM-DD' or YYYYMMDD format, depending on whether the function is used in a string or numeric context.
> select CURDATE();
        -> '1997-12-15'
> select CURDATE() + 0;
        -> 19971215
CURTIME()
CURRENT_TIME
Returns the current time as a value in 'HH:MM:SS' or HHMMSS format, depending on whether the function is used in a string or numeric context.
> select CURTIME();
        -> '23:50:26'
> select CURTIME() + 0;
        -> 235026
NOW()
SYSDATE()
CURRENT_TIMESTAMP
Returns the current date and time as a value in 'YYYY-MM-DD HH:MM:SS' or YYYYMMDDHHMMSS format, depending on whether the function is used in a string or numeric context.
> select NOW();
        -> '1997-12-15 23:50:26'
> select NOW() + 0;
        -> 19971215235026
UNIX_TIMESTAMP()
UNIX_TIMESTAMP(date)
If called with no argument, returns a Unix timestamp (seconds since '1970-01-01 00:00:00' GMT). If UNIX_TIMESTAMP() is called with a date argument, it returns the value of the argument as seconds since '1970-01-01 00:00:00' GMT. date may be a DATE string, a DATETIME string, a TIMESTAMP, or a number in the format YYMMDD or YYYYMMDD in local time.
> select UNIX_TIMESTAMP();
        -> 882226357
> select UNIX_TIMESTAMP('1997-10-04 22:23:00');
        -> 875996580
When UNIX_TIMESTAMP is used on a TIMESTAMP column, the function will receive the value directly, with no implicit ``string-to-unix-timestamp'' conversion.
FROM_UNIXTIME(unix_timestamp)
Returns a representation of the unix_timestamp argument as a value in 'YYYY-MM-DD HH:MM:SS' or YYYYMMDDHHMMSS format, depending on whether the function is used in a string or numeric context.
> select FROM_UNIXTIME(875996580);
        -> '1997-10-04 22:23:00'
> select FROM_UNIXTIME(875996580) + 0;
        -> 19971004222300
FROM_UNIXTIME(unix_timestamp,format)
Returns a string representation of the Unix timestamp, formatted according to the format string. format may contain the same specifiers as those listed in the entry for the DATE_FORMAT() function.
> select FROM_UNIXTIME(UNIX_TIMESTAMP(),
                            '%Y %D %M %h:%i:%s %x');
        -> '1997 23rd December 03:43:30 x'
SEC_TO_TIME(seconds)
Returns the seconds argument, converted to hours, minutes and seconds, as a value in 'HH:MM:SS' or HHMMSS format, depending on whether the function is used in a string or numeric context.
> select SEC_TO_TIME(2378);
        -> '00:39:38'
> select SEC_TO_TIME(2378) + 0;
        -> 3938
TIME_TO_SEC(time)
Returns the time argument, converted to seconds.
> select TIME_TO_SEC('22:23:00');
        -> 80580
> select TIME_TO_SEC('00:39:38');
        -> 2378

4.12 Miscellaneous functions

DATABASE()
Returns the current database name.
> select DATABASE();
        -> 'test'
If there is no current database, DATABASE() returns the empty string.
USER()
SYSTEM_USER()
SESSION_USER()
Returns the current MySQL user name.
> select USER();
        -> 'davida@localhost'
In MySQL 3.22.11 or later, this includes the client hostname as well as the username. You can extract just the username part like this (which works whether or not the value includes a hostname part):
> select substring_index(USER(),"@",1);
        -> 'davida'
PASSWORD(str)
Calculates a password string from the plaintext password str. This is the function that is used for encrypting MySQL passwords for storage in the Password column of the user grant table.
> select PASSWORD('badpwd');
        -> '7f84554057dd964b'
PASSWORD() encryption is non-reversible. PASSWORD() does not perform password encryption in the same way that Unix passwords are encrypted. You should not assume that if your Unix password and your MySQL password are the same, PASSWORD() will result in the same encrypted value as is stored in the Unix password file. See ENCRYPT().
ENCRYPT(str[,salt])
Encrypt str using the Unix crypt() system call. The salt argument should be a string with two characters. (As of MySQL 3.22.16, salt may be longer than two characters.)
> select ENCRYPT("hello");
        -> 'VxuFAJXVARROc'
If crypt() is not available on your system, ENCRYPT() always returns NULL. ENCRYPT() ignores all but the first 8 characters of str, at least on some systems. This will be determined by the behavior of the underlying crypt() system call.
ENCODE(str,pass_str)
Encrypt str using pass_str as the password. To decrypt the result, use DECODE(). The results is a binary string. If you want to save it in a column, use a BLOB column type.
DECODE(crypt_str,pass_str)
Descrypts the encrypted string crypt_str using pass_str as the password. crypt_str should be a string returned from ENCODE().
MD5(string)
Calculates a MD5 checksum for the string. Value is returned as a 32 long hex number that may, for example, be used as a hash key.
> select MD5("testing")
        -> 'ae2b1fca515949e5d54fb22b8ed95575'
This is a "RSA Data Security, Inc. MD5 Message-Digest Algorithm".
LAST_INSERT_ID([expr])
Returns the last automatically generated value that was inserted into an AUTO_INCREMENT column.
> select LAST_INSERT_ID();
        -> 195
The last ID that was generated is maintained in the server on a per-connection basis. It will not be changed by another client. It will not even be changed if you update another AUTO_INCREMENT column with a non-magic value (that is, a value that is not NULL and not 0). If expr is given as an argument to LAST_INSERT_ID() in an UPDATE clause, then the value of the argument is returned as a LAST_INSERT_ID() value. This can be used to simulate sequences: First create the table:
> create table sequence (id int not null);
> insert into sequence values (0);
Then the table can be used to generate sequence numbers like this:
> update sequence set id=LAST_INSERT_ID(id+1);
You can generate sequences without calling LAST_INSERT_ID(), but the utility of using the function this way is that the ID value is maintained in the server as the last automatically generated value. You can retrieve the new ID as you would read any normal AUTO_INCREMENT value in MySQL. For example, LAST_INSERT_ID() (without an argument) will return the new ID. The C API function mysql_insert_id() can also be used to get the value.
FORMAT(X,D)
Formats the number X to a format like '#,###,###.##', rounded to D decimals. If D is 0, the result will have no decimal point or fractional part.
> select FORMAT(12332.123456, 4);
        -> '12,332.1235'
> select FORMAT(12332.1,4);
        -> '12,332.1000'
> select FORMAT(12332.2,0);
        -> '12,332'
VERSION()
Returns a string indicating the MySQL server version.
> select VERSION();
        -> '3.22.19b-log'
GET_LOCK(str,timeout)
Tries to obtain a lock with a name given by the string str, with a timeout of timeout seconds. Returns 1 if the lock was obtained successfully, 0 if the attempt timed out, or NULL if an error occurred (such as running out of memory or the thread was killed with mysqladmin kill). A lock is released when you execute RELEASE_LOCK(), execute a new GET_LOCK() or the thread terminates. This function can be used to implement application locks or to simulate record locks. It blocks requests by other clients for locks with the same name; clients that agree on a given lock string name can use the string to perform cooperative advisory locking.
> select GET_LOCK("lock1",10);
        -> 1
> select GET_LOCK("lock2",10);
        -> 1
> select RELEASE_LOCK("lock2");
        -> 1
> select RELEASE_LOCK("lock1");
        -> NULL
Note that the second RELEASE_LOCK() call returns NULL because the lock "lock1" was automatically released by the second GET_LOCK() call.
RELEASE_LOCK(str)
Releases the lock named by the string str that was obtained with GET_LOCK(). Returns 1 if the lock was released, 0 if the lock wasn't locked by this thread (in which case the lock is not released) and NULL if the named lock didn't exist. The lock will not exist if it was never obtained by a call to GET_LOCK() or if it already has been released.
BENCHMARK(count,expr)
The BENCHMARK() function executes the expression expr repeatedly count times. It may be used to time how fast MySQL processes the expression. The result value is always 0. The intended use is in the mysql client, which reports query execution times.
> select BENCHMARK(1000000,encode("hello","goodbye"));
+----------------------------------------------+
| BENCHMARK(1000000,encode("hello","goodbye")) |
+----------------------------------------------+
|                                            0 |
+----------------------------------------------+
1 row in set (4.74 sec)
The time reported is elapsed time on the client end, not CPU time on the server end. It may be advisable to execute BENCHMARK() several times, and interpret the result with regard to how heavily loaded the server machine is.

4.13 Functions for use with GROUP BY clauses

If you use a group function in a statement containing no GROUP BY clause, it is equivalent to grouping on all rows.

COUNT(expr)
Returns a count of the number of non-NULL values in the rows retrieved by a SELECT statement.
> select student.student_name,COUNT(*)
           from student,course
           where student.student_id=course.student_id
           GROUP BY student_name;
COUNT(*) is somewhat different in that it returns a count of the number of rows retrieved, whether or not they contain NULL values. COUNT(*) is optimized to return very quickly if the SELECT retrieves from one table, no other columns are retrieved and there is no WHERE clause. For example:
> select COUNT(*) from student;
COUNT(DISTINCT expr,[expr...])
Returns a count of the number of different values.
> select COUNT(DISTINCT results) from student;
In MySQL you can get the number of distinct expressions combinations by giving a list of expressions. In ANSI SQL you would have to do a concatenation of all expressions inside CODE(DISTINCT ..).
AVG(expr)
Returns the average value of expr.
> select student_name, AVG(test_score)
           from student
           GROUP BY student_name;
MIN(expr)
MAX(expr)
Returns the minimum or maximum value of expr. MIN() and MAX() may take a string argument; in such cases they return the minimum or maximum string value.
> select student_name, MIN(test_score), MAX(test_score)
           from student
           GROUP BY student_name;
SUM(expr)
Returns the sum of expr. Note that if the return set has no rows, it returns NULL!
STD(expr)
STDDEV(expr)
Returns the standard deviation of expr. This is an extension to ANSI SQL. The STDDEV() form of this function is provided for Oracle compatability.
BIT_OR(expr)
Returns the bitwise OR of all bits in expr. The calculation is performed with 64-bit (BIGINT precision.
BIT_AND(expr)
Returns the bitwise AND of all bits in expr. The calculation is performed with 64-bit (BIGINT precision.

MySQL has extended the use of GROUP BY. You can use columns or calculations in the SELECT expressions which don't appear in the GROUP BY part. This stands for any possible value for this group. You can use this to get better performance by avoiding sorting and grouping on unnecessary items. For example, you don't need to group on customer.name in the following query:

> select order.custid,customer.name,max(payments)
       from order,customer
       where order.custid = customer.custid
       GROUP BY order.custid;

In ANSI SQL, you would have to add customer.name to the GROUP BY clause. In MySQL, the name is redundant.

Don't use this feature if the columns you omit from the GROUP BY part aren't unique in the group!

In some cases, you can use MIN() and MAX() to obtain a specific column value even if it isn't unique. The following gives the value of column from the row containing the smallest value in the sort column:

substr(MIN(concat(sort,space(6-length(sort)),column),7,length(column)))

Note that if you are using MySQL 3.22 (or earlier) or if you are trying to follow ANSI SQL, you can't use expressions in GROUP BY or ORDER BY clauses. You can work around this limitation by using an alias for the expression:

> SELECT id,FLOOR(value/100) AS val FROM tbl_name
           GROUP BY id,val ORDER BY val;

In MySQL 3.23 you can do:

> SELECT id,FLOOR(value/100) FROM tbl_name ORDER BY RAND();

© 1997-2000 TCX DataKonsult AB, 2000 SWsoft


MySQL v.3.23.11 language reference

5 CREATE DATABASE syntax

CREATE DATABASE db_name

CREATE DATABASE creates a database with the given name. Rules for allowable database names are given in section 1.5 Database, table, index, column and alias names. An error occurs if the database already exists.

Databases in MySQL are implemented as directories containing files that correspond to tables in the database.

In Colibri, CREATE DATABASE creates file system.tbl in system database directory, which is a parameter of Colibri DSN. The directory should exist.

You can also create databases via ODBC Data Source Administrator utility or MySQL's mysqladmin utility.

© 1997-2000 TCX DataKonsult AB, 2000 SWsoft


MySQL v.3.23.11 language reference

6 DROP DATABASE syntax

DROP DATABASE [IF EXISTS] db_name

DROP DATABASE drops all tables in the database and deletes the database. Be VERY careful with this command!

DROP DATABASE returns the number of files that were removed from the database directory. Normally for Colibri , this is two times the number of tables, since each table corresponds to a `.MKD' file and a `.FRB' file.

In MySQL 3.22 or later, you can use the keywords IF EXISTS to prevent an error from occurring if the database doesn't exist.

You can also drop databases with mysqladmin.

© 1997-2000 TCX DataKonsult AB, 2000 SWsoft


MySQL v.3.23.11 language reference

7 CREATE TABLE syntax

7.1 Silent column specification changes

7 CREATE TABLE syntax

CREATE [TEMPORARY] TABLE [IF NOT EXISTS] tbl_name [(create_definition,...)]
[table_options] [select_statement]

create_definition:
  col_name type [NOT NULL | NULL] [DEFAULT default_value] [AUTO_INCREMENT]
            [PRIMARY KEY] [reference_definition]
  or    PRIMARY KEY (index_col_name,...)
  or    KEY [index_name] (index_col_name,...)
  or    INDEX [index_name] (index_col_name,...)
  or    UNIQUE [INDEX] [index_name] (index_col_name,...)
  or    [CONSTRAINT symbol] FOREIGN KEY index_name (index_col_name,...)
            [reference_definition]
  or    CHECK (expr)

type:
        TINYINT[(length)] [UNSIGNED] [ZEROFILL]
  or    SMALLINT[(length)] [UNSIGNED] [ZEROFILL]
  or    MEDIUMINT[(length)] [UNSIGNED] [ZEROFILL]
  or    INT[(length)] [UNSIGNED] [ZEROFILL]
  or    INTEGER[(length)] [UNSIGNED] [ZEROFILL]
  or    BIGINT[(length)] [UNSIGNED] [ZEROFILL]
  or    REAL[(length,decimals)] [UNSIGNED] [ZEROFILL]
  or    DOUBLE[(length,decimals)] [UNSIGNED] [ZEROFILL]
  or    FLOAT[(length,decimals)] [UNSIGNED] [ZEROFILL]
  or    DECIMAL(length,decimals) [UNSIGNED] [ZEROFILL]
  or    NUMERIC(length,decimals) [UNSIGNED] [ZEROFILL]
  or    CHAR(length) [BINARY]
  or    VARCHAR(length) [BINARY]
  or    DATE
  or    TIME
  or    TIMESTAMP
  or    DATETIME
  or    TINYBLOB
  or    BLOB
  or    MEDIUMBLOB
  or    LONGBLOB
  or    TINYTEXT
  or    TEXT
  or    MEDIUMTEXT
  or    LONGTEXT
  or    ENUM(value1,value2,value3,...)
  or    SET(value1,value2,value3,...)

index_col_name:
        col_name [(length)]

reference_definition:
        REFERENCES tbl_name [(index_col_name,...)]
                   [MATCH FULL | MATCH PARTIAL]
                   [ON DELETE reference_option]
                   [ON UPDATE reference_option]

reference_option:
        RESTRICT | CASCADE | SET NULL | NO ACTION | SET DEFAULT

table_options:
    TYPE = {ISAM | MYISAM | HEAP}
or	AUTO_INCREMENT = #
or	AVG_ROW_LENGTH = #
or	CHECKSUM = {0 | 1}
or	COMMENT = "string"
or	MAX_ROWS = #
or	MIN_ROWS = #
or	PACK_KEYS = {0 | 1}
or	PASSWORD = "string"
or	DELAY_KEY_WRITE = {0 | 1}
or      ROW_FORMAT= { default | dynamic | static | compressed }

select_statement:
    [IGNORE | REPLACE] SELECT ...  (Some legal select statement)

CREATE TABLE creates a table with the given name in the current database. Rules for allowable table names are given in section 1.5 Database, table, index, column and alias names. An error occurs if there is no current database or if the table already exists.

In MySQL 3.22 or later, the table name can be specified as db_name.tbl_name. This works whether or not there is a current database.

In MySQL 3.23, you can use the TEMPORARY keyword when you create a table. A temporary table will automatically be deleted if a connection dies and the name is per connection. This means that two different connections can both use the same temporary table name without conflicting with each other or with an existing table of the same name. (The existing table is hidden until the temporary table is deleted).

In MySQL 3.23 or later, you can use the keywords IF NOT EXISTS so that an error does not occur if the table already exists. Note that there is no verification that the table structures are identical.

Each table tbl_name is represented by some files in the database directory. In the case of MyISAM-type tables you will get:

File | Purpose
tbl_name.frm | Table definition (form) file
tbl_name.MYD | Data file
tbl_name.MYI | Index file

For more information on the properties of the various column types, see section 3 Column types.

  • If neither NULL nor NOT NULL is specified, the column is treated as though NULL had been specified.
  • An integer column may have the additional attribute AUTO_INCREMENT. When you insert a value of NULL (recommended) or 0 into an AUTO_INCREMENT column, the column is set to value+1, where value is the largest value for the column currently in the table. AUTO_INCREMENT sequences begin with 1. If you delete the row containing the maximum value for an AUTO_INCREMENT column, the value will be reused with an ISAM table but not with a MyISAM table. If you delete all rows in the table with DELETE FROM TABLE (without a WHERE), the sequence starts over. Note: There can be only one AUTO_INCREMENT column per table, and it must be indexed. To make MySQL compatible with some ODBC applications, you can find the last inserted row with the following query:
    SELECT * FROM tbl_name WHERE auto_col IS NULL
  • NULL values are handled differently for TIMESTAMP columns than for other column types. You cannot store a literal NULL in a TIMESTAMP column; setting the column to NULL sets it to the current date and time. Because TIMESTAMP columns behave this way, the NULL and NOT NULL attributes do not apply in the normal way and are ignored if you specify them. On the other hand, to make it easier for MySQL clients to use TIMESTAMP columns, the server reports that such columns may be assigned NULL values (which is true), even though TIMESTAMP never actually will contain a NULL value. You can see this when you use DESCRIBE tbl_name to get a description of your table. Note that setting a TIMESTAMP column to 0 is not the same as setting it to NULL, because 0 is a valid TIMESTAMP value.
  • If no DEFAULT value is specified for a column, MySQL automatically assigns one. If the column may take NULL as a value, the default value is NULL. If the column is declared as NOT NULL, the default value depends on the column type:
    • For numeric types other than those declared with the AUTO_INCREMENT attribute, the default is 0. For an AUTO_INCREMENT column, the default value is the next value in the sequence.
    • For date and time types other than TIMESTAMP, the default is the appropriate ``zero'' value for the type. For the first TIMESTAMP column in a table, the default value is the current date and time. See section 3.6 Date and time types.
    • For string types other than ENUM, the default is the empty string. For ENUM, the default is the first enumeration value.
  • KEY is a synonym for INDEX.
  • In MySQL, a UNIQUE key can have only distinct values. An error occurs if you try to add a new row with a key that matches an existing row.
  • A PRIMARY KEY is an unique KEY with the extra constraint that all key columns must be defined as NOT NULL. In MySQL the key is named PRIMARY. A table can have only one PRIMARY KEY. If you don't have a PRIMARY KEY and some applications ask for the PRIMARY KEY in your tables, MySQL will return the first UNIQUE key, which doesn't have any NULL columns, as the PRIMARY KEY.
  • A PRIMARY KEY can be a multiple-column index. However, you cannot create a multiple-column index using the PRIMARY KEY key attibute in a column specification. Doing so will mark only that single column as primary. You must use the PRIMARY KEY(index_col_name, ...) syntax.
  • If the PRIMARY/ UNIQUE key consists of only one column and this is of type integer, one can also refer to it as _rowid (new in 3.23.11).
  • If you don't assign a name to an index, the index will be assigned the same name as the first index_col_name, with an optional suffix (_2, _3, ...) to make it unique. You can see index names for a table using SHOW INDEX FROM tbl_name. See section 21 SHOW syntax (Get information about tables, columns,...).
  • Only the MyISAM table type supports indexes on columns that can have NULL values. In other cases you must declare such columns NOT NULL or an error results.
  • With col_name(length) syntax, you can specify an index which uses only a part of a CHAR or VARCHAR column. This can make the index file much smaller. See section 3.9 Column indexes.
  • Only the MyISAM table type supports indexing on BLOB and TEXT columns. When putting an index on a BLOB or TEXT column you MUST always specify the length of the index:
    CREATE TABLE test (blob_col BLOB, index(blob_col(10)));
  • When you use ORDER BY or GROUP BY with a TEXT or BLOB column, only the first max_sort_length bytes are used. See section 3.7.2 The BLOB and TEXT types.
  • The FOREIGN KEY, CHECK and REFERENCES clauses don't actually do anything. The syntax for them is provided only for compatibility, to make it easier to port code from other SQL servers and to run applications that create tables with references.
  • Each NULL column takes one bit extra, rounded up to the nearest byte.
  • The maximum record length in bytes can be calculated as follows:
    row length = 1
             + (sum of column lengths)
             + (number of NULL columns + 7)/8
             + (number of variable-length columns)
  • The table_options and SELECT options is only implemented in MySQL 3.23 and above. The different table types are:
    ISAM | The original table handler. See section 8.2 ISAM tables
    MyISAM | The new binary portable table handler. See section 8.1 MyISAM tables.
    HEAP | The data for this table is only stored in memory. See section 8.3 HEAP tables.
    See section 8 MySQL table types. The other table options are used to optimize the behavior of the table. In most cases, you don't have to specify any of them. The options work for all table types, if not otherwise indicated.
    AUTO_INCREMENT | The next auto_increment value you want to set for your table (MyISAM)
    AVG_ROW_LENGTH | An approximation of the average row length for your table. You only need to set this for tables with variable size records.
    CHECKSUM | Set this to 1 if you want MySQL to maintain a checksum for all rows (makes the table a little slower to update but makes it easier to find corrupted tables) (MyISAM)
    COMMENT | A 60 character comment for your table
    MAX_ROWS | Max number of rows you plan to store in the table
    MIN_ROWS | Minimum number of rows you plan to store in the table
    PACK_KEYS | Set this to 1 if you want to have smaller index. This usually makes updates slower and reads faster (MyISAM, ISAM).
    PASSWORD | Encrypt the .frm file with a password. This option doesn't do anything in the standard MySQL version.
    DELAY_KEY_WRITE | Set this to 1 if want to delay key table updates until the table is closed (MyISAM).
    ROW_FORMAT | Defines how the rows should be stored (for the future).
    When you use a MyISAM table, MySQL uses the product of max_rows * avg_row_length to decide how big the resulting table will be. If you don't specify any of the above options, the maximum size for a table will be 4G (or 2G if your operating systems only supports 2G tables). If you don't use PACK_KEYS, the default is to only pack strings, not numbers. If you use PACK_KEYS=1, numbers will be packed as well. When packing binary number keys, MySQL will use prefix compression. This means that you will only get a big benefit of this if you have many numbers that are the same. Prefix compression means that every key needs one extra byte to indicate how many bytes of the previous key are the same for the next key (note that the pointer to the row is stored in high-byte-first-order directly after the key, to improve compression. This means that if you have many equal keys on two rows in a row, all following 'same' keys will usually only take 2 bytes (including the pointer to the row). Compare this to the ordinary case where the following keys will take 'storage_size_for_key' + pointer_size (usually 4). On the other hand, if all keys are totally different, you will lose 1 byte per key, if the key isn't a key that can have NULL values (In this case the packed key length will be stored in the same byte that is used to mark if a key is NULL).
  • If you specify a SELECT after the CREATE STATEMENT, MySQL will create new fields for all elements in the SELECT. For example:
    > CREATE TABLE test (a int not null auto_increment,
           primary key (a), key(b))
           TYPE=HEAP SELECT b,c from test2;
    This will create a HEAP table with 3 columns. Note that the table will automatically be deleted if any errors occur while copying data into the table.

7.1 Silent column specification changes

In some cases, MySQL silently changes a column specification from that given in a CREATE TABLE statement. (This may also occur with ALTER TABLE.)

  • VARCHAR columns with a length less than four are changed to CHAR.
  • If any column in a table has a variable length, the entire row is variable-length as a result. Therefore, if a table contains any variable-length columns (VARCHAR, TEXT or BLOB), all CHAR columns longer than three characters are changed to VARCHAR columnss. This doesn't affect how you use the columns in any way; in MySQL, VARCHAR is just a different way to store characters. MySQL performs this conversion because it saves space and makes table operations faster. See section 8 MySQL table types
  • TIMESTAMP display sizes must be even and in the range from 2 to 14. If you specify a display size of 0 or greater than 14, the size is coerced to 14. Odd-valued sizes in the range from 1 to 13 are coerced to the next higher even number.
  • You cannot store a literal NULL in a TIMESTAMP column; setting it to NULL sets it to the current date and time. Because TIMESTAMP columns behave this way, the NULL and NOT NULL attributes do not apply in the normal way and are ignored if you specify them. DESCRIBE tbl_name always reports that a TIMESTAMP column may be assigned NULL values.
  • MySQL maps certain column types used by other SQL database vendors to MySQL types. See section 3.11 Using column types from other database engines.

If you want to see whether or not MySQL used a column type other than the one you specified, issue a DESCRIBE tbl_name statement after creating or altering your table.

Certain other column type changes may occur if you compress a table using myisampack. See section 8.1.2.3 Compressed table characteristics.

© 1997-2000 TCX DataKonsult AB, 2000 SWsoft


MySQL v.3.23.11 language reference

8 ALTER TABLE syntax

ALTER [IGNORE] TABLE tbl_name alter_spec [, alter_spec ...]

alter_specification:
        ADD [COLUMN] create_definition [FIRST | AFTER column_name ]
  or    ADD INDEX [index_name] (index_col_name,...)
  or    ADD PRIMARY KEY (index_col_name,...)
  or    ADD UNIQUE [index_name] (index_col_name,...)
  or    ALTER [COLUMN] col_name {SET DEFAULT literal | DROP DEFAULT}
  or    CHANGE [COLUMN] old_col_name create_definition
  or    MODIFY [COLUMN] create_definition
  or    DROP [COLUMN] col_name
  or    DROP PRIMARY KEY
  or    DROP INDEX index_name
  or    RENAME [AS] new_tbl_name
  or    table_options

ALTER TABLE allows you to change the structure of an existing table. For example, you can add or delete columns, create or destroy indexes, change the type of existing columns, or rename columns or the table itself. You can also change the comment for the table and type of the table. See section 7 CREATE TABLE syntax.

If you use ALTER TABLE to change a column specification but DESCRIBE tbl_name indicates that your column was not changed, it is possible that MySQL ignored your modification for one of the reasons described in section 7.1 Silent column specification changes. For example, if you try to change a VARCHAR column to CHAR, MySQL will still use VARCHAR if the table contains other variable-length columns.

ALTER TABLE works by making a temporary copy of the original table. The alteration is performed on the copy, then the original table is deleted and the new one is renamed. This is done in such a way that all updates are automatically redirected to the new table without any failed updates. While ALTER TABLE is executing, the original table is readable by other clients. Updates and writes to the table are stalled until the new table is ready.

  • To use ALTER TABLE, you need select, insert, delete, update, create and drop privileges on the table.
  • IGNORE is a MySQL extension to ANSI SQL92. It controls how ALTER TABLE works if there are duplicates on unique keys in the new table. If IGNORE isn't specified, the copy is aborted and rolled back. If IGNORE is specified, then for rows with duplicates on a unique key, only the first row is used; the others are deleted.
  • You can issue multiple ADD, ALTER, DROP and CHANGE clauses in a single ALTER TABLE statement. This is a MySQL extension to ANSI SQL92, which allows only one of each clause per ALTER TABLE statement.
  • CHANGE col_name, DROP col_name and DROP INDEX are MySQL extensions to ANSI SQL92.
  • MODIFY is an Oracle extension to ALTER TABLE.
  • The optional word COLUMN is a pure noise word and can be omitted.
  • If you use ALTER TABLE tbl_name RENAME AS new_name without any other options, MySQL simply renames the files that correspond to the table tbl_name. There is no need to create the temporary table.
  • create_definition clauses use the same syntax for ADD and CHANGE as for CREATE TABLE. Note that this syntax includes the column name, not just the column type. See section 7 CREATE TABLE syntax.
  • You can rename a column using a CHANGE old_col_name create_definition clause. To do so, specify the old and new column names and the type that the column currently has. For example, to rename an INTEGER column from a to b, you can do this:
    > ALTER TABLE t1 CHANGE a b INTEGER;
    If you want to change a column's type but not the name, CHANGE syntax still requires two column names even if they are the same. For example:
    > ALTER TABLE t1 CHANGE b b BIGINT NOT NULL;
    However, as of MySQL 3.22.16a, you can also use MODIFY to change a column's type without renaming it:
    > ALTER TABLE t1 MODIFY b BIGINT NOT NULL;
  • If you use CHANGE or MODIFY to shorten a column for which an index exists on part of the column (for instance, if you have an index on the first 10 characters of a VARCHAR column), you cannot make the column shorter than the number of characters that are indexed.
  • When you change a column type using CHANGE or MODIFY, MySQL tries to convert data to the new type as well as possible.
  • In MySQL 3.22 or later, you can use FIRST or ADD ... AFTER col_name to add a column at a specific position within a table row. The default is to add the column last.
  • ALTER COLUMN specifies a new default value for a column or removes the old default value. If the old default is removed and the column can be NULL, the new default is NULL. If the column cannot be NULL, MySQL assigns a default value. Default value assignment is described in section 7 CREATE TABLE syntax.
  • DROP INDEX removes an index. This is a MySQL extension to ANSI SQL92.
  • If columns are dropped from a table, the columns are also removed from any index of which they are a part. If all columns that make up an index are dropped, the index is dropped as well.
  • DROP PRIMARY KEY drops the primary index. If no such index exists, it drops the first UNIQUE index in the table. (MySQL marks the first UNIQUE key as the PRIMARY KEY if no PRIMARY KEY was specified explicitly.)
  • With the C API function mysql_info(), you can find out how many records were copied, and (when IGNORE is used) how many records were deleted due to duplication of unique key values.
  • The FOREIGN KEY, CHECK and REFERENCES clauses don't actually do anything. The syntax for them is provided only for compatibility, to make it easier to port code from other SQL servers and to run applications that create tables with references.

Here is an example that shows some of the uses of ALTER TABLE. We begin with a table t1 that is created as shown below:

> CREATE TABLE t1 (a INTEGER,b CHAR(10));

To rename the table from t1 to t2:

> ALTER TABLE t1 RENAME t2;

To change column a from INTEGER to TINYINT NOT NULL (leaving the name the same), and to change column b from CHAR(10) to CHAR(20) as well as renaming it from b to c:

> ALTER TABLE t2 MODIFY a TINYINT NOT NULL, CHANGE b c CHAR(20);

To add a new TIMESTAMP column named d:

> ALTER TABLE t2 ADD d TIMESTAMP;

To add an index on column d, and make column a the primary key:

> ALTER TABLE t2 ADD INDEX (d), ADD PRIMARY KEY (a);

To remove column c:

> ALTER TABLE t2 DROP COLUMN c;

To add a new AUTO_INCREMENT integer column named c:

> ALTER TABLE t2 ADD c INT UNSIGNED NOT NULL AUTO_INCREMENT,
           ADD INDEX (c);

Note that we indexed c, because AUTO_INCREMENT columns must be indexed, and also that we declare c as NOT NULL, because indexed columns cannot be NULL.

When you add an AUTO_INCREMENT column, column values are filled in with sequence numbers for you automatically.

© 1997-2000 TCX DataKonsult AB, 2000 SWsoft


MySQL v.3.23.11 language reference

9 OPTIMIZE TABLE syntax

OPTIMIZE TABLE tbl_name

OPTIMZE TABLE should be used if you have deleted a large part of a table or if you have made many changes to a table with variable-length rows (tables that have VARCHAR, BLOB or TEXT columns). Deleted records are maintained in a linked list and subsequent INSERT operations reuse old record positions. You can use OPTIMIZE TABLE to reclaim the unused space.

OPTIMIZE TABLE works by making a temporary copy of the original table; The old table is copied to the new table (without the unused rows), then the original table is deleted and the new one is renamed. While OPTIMIZE TABLE is executing, the original table is readable by other clients. Updates and writes to the table are stalled until the new table is ready. This is done in such a way that all updates are automatically redirected to the new table without any failed updates.

© 1997-2000 TCX DataKonsult AB, 2000 SWsoft


MySQL v.3.23.11 language reference

10 DROP TABLE syntax

DROP TABLE [IF EXISTS] tbl_name [, tbl_name,...]

DROP TABLE removes one or more tables. All table data and the table definition are removed, so be careful with this command!

In MySQL 3.22 or later, you can use the keywords IF EXISTS to prevent an error from occurring for tables that don't exist.

© 1997-2000 TCX DataKonsult AB, 2000 SWsoft


MySQL v.3.23.11 language reference

11 DELETE syntax

DELETE [LOW_PRIORITY] FROM tbl_name
    [WHERE where_definition] [LIMIT rows]

DELETE deletes rows from tbl_name that satisfy the condition given by where_definition, and returns the number of records deleted.

If you issue a DELETE with no WHERE clause, all rows are deleted. MySQL does this by recreating the table as an empty table, which is much faster than deleting each row. In this case, DELETE returns zero as the number of affected records. (MySQL can't return the number of rows that were actually deleted, since the recreate is done without opening the data files. As long as the table definition file `tbl_name.frm' is valid, the table can be recreated this way, even if the data or index files have become corrupted.).

If you really want to know how many records are deleted when you are deleting all rows, and are willing to suffer a speed penalty, you can use a DELETE statement of this form:

> DELETE FROM tbl_name WHERE 1>0;

Note that this is MUCH slower than DELETE FROM tbl_name with no WHERE clause, because it deletes rows one at a time.

If you specify the keyword LOW_PRIORITY, execution of the DELETE is delayed until no other clients are reading from the table.

Deleted records are maintained in a linked list and subsequent INSERT operations reuse old record positions. To reclaim unused space and reduce file sizes, use the OPTIMIZE TABLE statement or the myisamchk utility to reorganize tables. OPTIMIZE TABLE is easier, but myisamchk is faster. See section 9 OPTIMIZE TABLE syntax.

The MySQL-specific LIMIT rows option to DELETE tells the server the maximum number of rows to be deleted before control is returned to the client. This can be used to ensure that a specific DELETE command doesn't take too much time. You can simply repeat the DELETE command until the number of affected rows is less than the LIMIT value.

© 1997-2000 TCX DataKonsult AB, 2000 SWsoft


MySQL v.3.23.11 language reference

12 SELECT syntax

SELECT [STRAIGHT_JOIN] [SQL_SMALL_RESULT] [SQL_BIG_RESULT] [HIGH_PRIORITY]
       [DISTINCT | DISTINCTROW | ALL]
    select_expression,...
    [INTO {OUTFILE | DUMPFILE} 'file_name' export_options]
    [FROM table_references
        [WHERE where_definition]
        [GROUP BY col_name,...]
        [HAVING where_definition]
        [ORDER BY {unsigned_integer | col_name | formula} [ASC | DESC] ,...]
        [LIMIT [offset,] rows]
        [PROCEDURE procedure_name] ]

SELECT is used to retrieve rows selected from one or more tables. select_expression indicates the columns you want to retrieve. SELECT may also be used to retrieve rows computed without reference to any table. For example:

> SELECT 1 + 1;
         -> 2

All keywords used must be given in exactly the order shown above. For example, a HAVING clause must come after any GROUP BY clause and before any ORDER BY clause.

  • A SELECT expression may be given an alias using AS. The alias is used as the expression's column name and can be used with ORDER BY or HAVING clauses. For example:
    > select concat(last_name,', ',first_name) AS full_name
    from mytable ORDER BY full_name;
  • The FROM table_references clause indicates the tables from which to retrieve rows. If you name more than one table, you are performing a join. For information on join syntax, see section 13 JOIN syntax.
  • You can refer to a column as col_name, tbl_name.col_name or db_name.tbl_name.col_name. You need not specify a tbl_name or db_name.tbl_name prefix for a column reference in a SELECT statement unless the reference would be ambiguous. See section 1.5 Database, table, index, column and alias names, for examples of ambiguity that require the more explicit column reference forms.
  • A table reference may be aliased using tbl_name [AS] alias_name.
    > select t1.name, t2.salary from employee AS t1, info AS t2
           where t1.name = t2.name;
> select t1.name, t2.salary from employee t1, info t2
           where t1.name = t2.name;
  • Columns selected for output may be referred to in ORDER BY and GROUP BY clauses using column names, column aliases or column positions. Column positions begin with 1.
    > select college, region, seed from tournament
           ORDER BY region, seed;
> select college, region AS r, seed AS s from tournament
           ORDER BY r, s;
> select college, region, seed from tournament
           ORDER BY 2, 3;
    To sort in reverse order, add the DESC (descending) keyword to the name of the column in the ORDER BY clause that you are sorting by. The default is ascending order; this may be specified explicitly using the ASC keyword.
  • The HAVING clause can refer to any column or alias named in the select_expression. It is applied last, just before items are sent to the client, with no optimization. Don't use HAVING for items that should be in the WHERE clause. For example, do not write this:
    > select col_name from tbl_name HAVING col_name > 0;
    Write this instead:
    > select col_name from tbl_name WHERE col_name > 0;
    In MySQL 3.22.5 or later, you can also write queries like this:
    > select user,max(salary) from users
           group by user HAVING max(salary)>10;
    In older MySQL versions, you can write this instead:
    > select user,max(salary) AS sum from users
           group by user HAVING sum>10;
  • SQL_SMALL_RESULT, SQL_BIG_RESULT, STRAIGHT_JOIN and HIGH_PRIORITY are MySQL extensions to ANSI SQL92.
  • STRAIGHT_JOIN forces the optimizer to join the tables in the order in which they are listed in the FROM clause. You can use this to speed up a query if the optimizer joins the tables in non-optimal order. See section 22 EXPLAIN syntax (Get information about a SELECT).
  • SQL_SMALL_RESULT can be used with GROUP BY or DISTINCT to tell the optimizer that the result set will be small. In this case, MySQL will use fast temporary tables to store the resulting table instead of using sorting. SQL_SMALL_RESULT is a MySQL
  • SQL_BIG_RESULT can be used with GROUP BY or DISTINCT to tell the optimizer that the result set will have many rows. In this case, MySQL will directly use disk based temporary tables if needed. MySQL in this case will prefer to do a sort instead doing a temporary table with a key on the GROUP BY elements.
  • HIGH_PRIORITY will give the SELECT higher priority than a statement that updates a table. You should only use this for queries that are very fast and must be done at once. A SELECT HIGH_PRIORITY query will run if the table is locked for read even if there is an update statement that is waiting for the table to be free.
  • The LIMIT clause can be used to constrain the number of rows returned by the SELECT statement. LIMIT takes one or two numeric arguments. If two arguments are given, the first specifies the offset of the first row to return, the second specifies the maximum number of rows to return. The offset of the initial row is 0 (not 1).
    > select * from table LIMIT 5,10;  # Retrieve rows 6-15
    If one argument is given, it indicates the maximum number of rows to return.
    > select * from table LIMIT 5;     # Retrieve first 5 rows
    In other words, LIMIT n is equivalent to LIMIT 0,n.
  • The SELECT ... INTO OUTFILE 'file_name' form of SELECT writes the selected rows to a file. The file is created on the server host, and cannot already exist (among other things, this prevents database tables and files such as `/etc/passwd' from being destroyed). You must have the file privilege on the server host to use this form of SELECT. SELECT ... INTO OUTFILE is the complement of LOAD DATA INFILE; the syntax for the export_options part of the statement consists of the same FIELDS and LINES clauses that are used with the LOAD DATA INFILE statement. See section 16 LOAD DATA INFILE syntax. In the resulting text file, only the following characters are escaped by the ESCAPED BY character:
    • The ESCAPED BY character
    • The first character in FIELDS TERMINATED BY
    • The first character in LINES TERMINATED BY
    Additionally, ASCII 0 is converted to ESCAPED BY followed by 0 (ASCII 48). The reason for the above is that you MUST escape any FIELDS TERMINATED BY, ESCAPED BY or LINES TERMINATED BY characters to reliably be able to read the file back. ASCII 0 is escaped to make it easier to view with some pagers. As the resulting file doesn't have to conform to the SQL syntax, nothing else need be escaped.

If you use INTO DUMPFILE instead of INTO OUTFILE MySQL will only write one row into the file, without any column or line terminations and without any escaping. This is useful if you want to store a blob in a file.

© 1997-2000 TCX DataKonsult AB, 2000 SWsoft


MySQL v.3.23.11 language reference

13 JOIN syntax

MySQL supports the following JOIN syntaxes for use in SELECT statements:

table_reference, table_reference
table_reference [CROSS] JOIN table_reference
table_reference INNER JOIN table_reference
table_reference STRAIGHT_JOIN table_reference
table_reference LEFT [OUTER] JOIN table_reference ON conditional_expr
table_reference LEFT [OUTER] JOIN table_reference USING (column_list)
table_reference NATURAL LEFT [OUTER] JOIN table_reference
{ oj table_reference LEFT OUTER JOIN table_reference ON conditional_expr }

The last LEFT OUTER JOIN syntax shown above exists only for compatibility with ODBC.

  • A table reference may be aliased using tbl_name AS alias_name or tbl_name alias_name.
    > select t1.name, t2.salary from employee AS t1, info AS t2
           where t1.name = t2.name;
  • INNER JOIN and , (comma) are semantically equivalent. Both do a full join between the tables used. Normally, you specify how the tables should be linked in the WHERE condition.
  • The ON conditional is any conditional of the form that may be used in a WHERE clause.
  • If there is no matching record for the right table in a LEFT JOIN, a row with all columns set to NULL is used for the right table. You can use this fact to find records in a table that have no counterpart in another table:
    > select table1.* from table1
           LEFT JOIN table2 ON table1.id=table2.id
           where table2.id is NULL;
    This example finds all rows in table1 with an id value that is not present in table2 (i.e., all rows in table1 with no corresponding row in table2). This assumes that table2.id is declared NOT NULL, of course.
  • The USING (column_list) clause names a list of columns that must exist in both tables. A USING clause such as:
    A LEFT JOIN B USING (C1,C2,C3,...)
    is defined to be semantically identical to an ON expression like this:
    A.C1=B.C1 AND A.C2=B.C2 AND A.C3=B.C3,...
  • The NATURAL LEFT JOIN of two tables is defined to be semantically equivalent to a LEFT JOIN with a USING clause that names all columns that exist in both tables.
  • STRAIGHT_JOIN is identical to JOIN, except that the left table is always read before the right table. This can be used for those (few) cases where the join optimizer puts the tables in the wrong order.

Some examples:

> select * from table1,table2 where table1.id=table2.id;
> select * from table1 LEFT JOIN table2 ON table1.id=table2.id;
> select * from table1 LEFT JOIN table2 USING (id);
> select * from table1 LEFT JOIN table2 ON table1.id=table2.id
           LEFT JOIN table3 ON table2.id=table3.id;

© 1997-2000 TCX DataKonsult AB, 2000 SWsoft


MySQL v.3.23.11 language reference

14 INSERT syntax

    INSERT [LOW_PRIORITY | DELAYED] [IGNORE]
        [INTO] tbl_name [(col_name,...)]
        VALUES (expression,...),(...),...
or  INSERT [LOW_PRIORITY | DELAYED] [IGNORE]
        [INTO] tbl_name [(col_name,...)]
        SELECT ...
or  INSERT [LOW_PRIORITY | DELAYED] [IGNORE]
        [INTO] tbl_name
        SET col_name=expression, col_name=expression, ...

INSERT inserts new rows into an existing table. The INSERT ... VALUES form of the statement inserts rows based on explicitly-specified values. The INSERT ... SELECT form inserts rows selected from another table or tables. The INSERT ... VALUES form with multiple value lists is supported in MySQL 3.22.5 or later. The col_name=expression syntax is supported in MySQL 3.22.10 or later.

tbl_name is the table into which rows should be inserted. The column name list or the SET clause indicates which columns the statement specifies values for.

  • If you specify no column list for INSERT ... VALUES or INSERT ... SELECT, values for all columns must be provided in the VALUES() list or by the SELECT. If you don't know the order of the columns in the table, use DESCRIBE tbl_name to find out.
  • Any column not explicitly given a value is set to its default value. For example, if you specify a column list that doesn't name all the columns in the table, unnamed columns are set to their default values. Default value assignment is described in section 7 CREATE TABLE syntax.
  • An expression may refer to any column that was set earlier in a value list. For example, you can say this:
    > INSERT INTO tbl_name (col1,col2) VALUES(15,col1*2);
    But not this:
    > INSERT INTO tbl_name (col1,col2) VALUES(col2*2,15);
  • If you specify the keyword LOW_PRIORITY, execution of the INSERT is delayed until no other clients are reading from the table. In this case the client has to wait until the insert statement is completed, which may take a long time if the table is in heavy use. This is in contrast to INSERT DELAYED which lets the client continue at once.
  • If you specify the keyword IGNORE in an INSERT with many value rows, any rows which duplicate an existing PRIMARY or UNIQUE key in the table are ignored and are not inserted. If you do not specify IGNORE, the insert is aborted if there is any row that duplicates an existing key value. You can check with the C API function mysql_info() how many rows were inserted into the table.
  • If MySQL was configured using the DONT_USE_DEFAULT_FIELDS option, INSERT statements generate an error unless you explicitly specify values for all columns that require a non-NULL value.
  • The following conditions hold for a INSERT INTO ... SELECT statement:
    • The query cannot contain an ORDER BY clause.
    • The target table of the INSERT statement cannot appear in the FROM clause of the SELECT part of the query, because it's forbidden in ANSI SQL to SELECT from the same table into which you are INSERTing. (The problem is that the SELECT possibly would find records that were inserted earlier during the same run. When using sub-select clauses, the situation could easily be very confusing!)
    • AUTO_INCREMENT columns work as usual.

If you use INSERT ... SELECT or a INSERT ... VALUES statement with multiple value lists, you can use the C API function mysql_info() to get information about the query. The format of the information string is shown below:

Records: 100 Duplicates: 0 Warnings: 0

Duplicates indicates the number of rows that couldn't be inserted because they would duplicate some existing unique index value. Warnings indicates the number of attempts to insert column values that were problematic in some way. Warnings can occur under any of the following conditions:

  • Inserting NULL into a column that has been declared NOT NULL. The column is set to its default value.
  • Setting a numeric column to a value that lies outside the column's range. The value is clipped to the appropriate endpoint of the range.
  • Setting a numeric column to a value such as '10.34 a'. The trailing garbage is stripped and the remaining numeric part is inserted. If the value doesn't make sense as a number at all, the column is set to 0.
  • Inserting a string into a CHAR, VARCHAR, TEXT or BLOB column that exceeds the column's maximum length. The value is truncated to the column's maximum length.
  • Inserting a value into a date or time column that is illegal for the column type. The column is set to the appropriate ``zero'' value for the type.

The DELAYED option for the INSERT statement is a MySQL-specific option that is very useful if you have clients that can't wait for the INSERT to complete. This is a common problem when you use MySQL for logging and you also periodically run SELECT statements that take a long time to complete. DELAYED was introduced in MySQL 3.22.15. It is a MySQL extension to ANSI SQL92.

When you use INSERT DELAYED, the client will get an ok at once and the row will be inserted when the table is not in use by any other thread.

Another major benefit of using INSERT DELAYED is that inserts from many clients are bundled together and written in one block. This is much faster than doing many separate inserts.

Note that currently the queued rows are only stored in memory until they are inserted into the table. This means that if you kill mysqld the hard way (kill -9) or if mysqld dies unexpectedly, any queued rows that weren't written to disk are lost!

The following describes in detail what happens when you use the DELAYED option to INSERT or REPLACE. In this description, the ``thread'' is the thread that received an INSERT DELAYED command and ``handler'' is the thread that handles all INSERT DELAYED statements for a particular table.

  • When a thread executes a DELAYED statement for a table, a handler thread is created to process all DELAYED statements for the table, if no such handler already exists.
  • The thread checks whether or not the handler has acquired a DELAYED lock already; if not, it tells the handler thread to do so. The DELAYED lock can be obtained even if other threads have a READ or WRITE lock on the table. However, the handler will wait for all ALTER TABLE locks or FLUSH TABLES to ensure that the table structure is up to date.
  • The thread executes the INSERT statement but instead of writing the row to the table it puts a copy of the final row into a queue that is managed by the handler thread. Any syntax errors are noticed by the thread and reported to the client program.
  • The client can't report the number of duplicates or the AUTO_INCREMENT value for the resulting row; it can't obtain them from the server, because the INSERT returns before the insert operation has been completed. If you use the C API, the mysql_info() function doesn't return anything meaningful, for the same reason.
  • The update log is updated by the handler thread when the row is inserted into the table. In case of multiple-row inserts, the update log is updated when the first row is inserted.
  • After every delayed_insert_limit rows are written, the handler checks whether or not any SELECT statements are still pending. If so, it allows these to execute before continuing.
  • When the handler has no more rows in its queue, the table is unlocked. If no new INSERT DELAYED commands are received within delayed_insert_timeout seconds, the handler terminates.
  • If more than delayed_queue_size rows are pending already in a specific handler queue, the thread waits until there is room in the queue. This is useful to ensure that the mysqld server doesn't use all memory for the delayed memory queue.
  • The handler thread will show up in the MySQL process list with delayed_insert in the Command column. It will be killed if you execute a FLUSH TABLES command or kill it with KILL thread_id. However, it will first store all queued rows into the table before exiting. During this time it will not accept any new INSERT commands from another thread. If you execute an INSERT DELAYED command after this, a new handler thread will be created.
  • Note that the above means that INSERT DELAYED commands have higher priority than normal INSERT commands if there is an INSERT DELAYED handler already running! Other update commands will have to wait until the INSERT DELAY queue is empty, someone kills the handler thread (with KILL thread_id) or someone executes FLUSH TABLES.
  • The following status variables provide information about INSERT DELAYED commands:
    Delayed_insert_threads | Number of handler threads
    Delayed_writes | Number of rows written with INSERT DELAYED
    Not_flushed_delayed_rows | Number of rows waiting to be written
    You can view these variables by issuing a SHOW STATUS statement or by executing a mysqladmin extended-status command.

Note that INSERT DELAYED is slower than a normal INSERT if the table is not in use. There is also the additional overhead for the server to handle a separate thread for each table on which you use INSERT DELAYED. This means that you should only use INSERT DELAYED when you are really sure you need it!

© 1997-2000 TCX DataKonsult AB, 2000 SWsoft


MySQL v.3.23.11 language reference

15 REPLACE syntax

    REPLACE [LOW_PRIORITY | DELAYED]
        [INTO] tbl_name [(col_name,...)]
        VALUES (expression,...)
or  REPLACE [LOW_PRIORITY | DELAYED]
        [INTO] tbl_name [(col_name,...)]
        SELECT ...
or  REPLACE [LOW_PRIORITY | DELAYED]
        [INTO] tbl_name
        SET col_name=expression, col_name=expression,...

REPLACE works exactly like INSERT, except that if an old record in the table has the same value as a new record on a unique index, the old record is deleted before the new record is inserted. See section 14 INSERT syntax.

Colibri does not support this statement

© 1997-2000 TCX DataKonsult AB, 2000 SWsoft


MySQL v.3.23.11 language reference

16 LOAD DATA INFILE syntax

LOAD DATA [LOW_PRIORITY] [LOCAL] INFILE 'file_name.txt' [REPLACE | IGNORE]
    INTO TABLE tbl_name
    [FIELDS
        [TERMINATED BY '\t']
        [OPTIONALLY] ENCLOSED BY '']
        [ESCAPED BY '\\' ]]
    [LINES TERMINATED BY '\n']
    [IGNORE number LINES]
    [(col_name,...)]

The LOAD DATA INFILE statement reads rows from a text file into a table at a very high speed. If the LOCAL keyword is specified, the file is read from the client host. If LOCAL is not specified, the file must be located on the server. (LOCAL is available in MySQL 3.22.6 or later.)

For security reasons, when reading text files located on the server, the files must either reside in the database directory or be readable by all. Also, to use LOAD DATA INFILE on server files, you must have the file privilege on the server host.

If you specify the keyword LOW_PRIORITY, execution of the LOAD DATA statement is delayed until no other clients are reading from the table.

Using LOCAL will be a bit slower than letting the server access the files directly, since the contents of the file must travel from the client host to the server host. On the other hand, you do not need the file privilege to load local files.

You can also load data files by using the mysqlimport utility; it operates by sending a LOAD DATA INFILE command to the server. The --local option causes mysqlimport to read data files from the client host. You can specify the --compress option to get better performance over slow networks if the client and server support the compressed protocol.

When locating files on the server host, the server uses the following rules:

  • If an absolute pathname is given, the server uses the pathname as is.
  • If a relative pathname with one or more leading components is given, the server searches for the file relative to the server's data directory.
  • If a filename with no leading components is given, the server looks for the file in the database directory of the current database.

Note that these rules mean a file given as `./myfile.txt' is read from the server's data directory, whereas a file given as `myfile.txt' is read from the database directory of the current database. For example, the following LOAD DATA statement reads the file `data.txt' from the database directory for db1 because db1 is the current database, even though the statement explicitly loads the file into a table in the db2 database:

> USE db1;
> LOAD DATA INFILE "data.txt" INTO TABLE db2.my_table;

The REPLACE and IGNORE keywords control handling of input records that duplicate existing records on unique key values. If you specify REPLACE, new rows replace existing rows that have the same unique key value. If you specify IGNORE, input rows that duplicate an existing row on a unique key value are skipped. If you don't specify either option, an error occurs when a duplicate key value is found, and the rest of the text file is ignored.

If you load data from a local file using the LOCAL keyword, the server has no way to stop transmission of the file in the middle of the operation, so the default bahavior is the same as if IGNORE is specified.

LOAD DATA INFILE is the complement of SELECT ... INTO OUTFILE. See section 12 SELECT syntax. To write data from a database to a file, use SELECT ... INTO OUTFILE. To read the file back into the database, use LOAD DATA INFILE. The syntax of the FIELDS and LINES clauses is the same for both commands. Both clauses are optional, but FIELDS must precede LINES if both are specified.

If you specify a FIELDS clause, each of its subclauses (TERMINATED BY, [OPTIONALLY] ENCLOSED BY and ESCAPED BY) is also optional, except that you must specify at least one of them.

If you don't specify a FIELDS clause, the defaults are the same as if you had written this:

FIELDS TERMINATED BY '\t' ENCLOSED BY '' ESCAPED BY '\\'

If you don't specify a LINES clause, the default is the same as if you had written this:

LINES TERMINATED BY '\n'

In other words, the defaults cause LOAD DATA INFILE to act as follows when reading input:

  • Look for line boundaries at newlines
  • Break lines into fields at tabs
  • Do not expect fields to be enclosed within any quoting characters
  • Interpret occurrences of tab, newline or `\' preceded by `\' as literal characters that are part of field values

Conversely, the defaults cause SELECT ... INTO OUTFILE to act as follows when writing output:

  • Write tabs between fields
  • Do not enclose fields within any quoting characters
  • Use `\' to escape instances of tab, newline or `\' that occur within field values
  • Write newlines at the ends of lines

Note that to write FIELDS ESCAPED BY '\\', you must specify two backslashes for the value to be read as a single backslash.

The IGNORE number LINES option can be used to ignore a header of column names at the start of the file:

> LOAD DATA INFILE "/tmp/file_name" into table test IGNORE 1 LINES;

When you use SELECT ... INTO OUTFILE in tandem with LOAD DATA INFILE to write data from a database into a file and then read the file back into the database later, the field and line handling options for both commands must match. Otherwise, LOAD DATA INFILE will not interpret the contents of the file properly. Suppose you use SELECT ... INTO OUTFILE to write a file with fields delimited by commas:

> SELECT * FROM table1 INTO OUTFILE 'data.txt'
           FIELDS TERMINATED BY ','
           FROM ...

To read the comma-delimited file back in, the correct statement would be:

> LOAD DATA INFILE 'data.txt' INTO TABLE table2
           FIELDS TERMINATED BY ',';

If instead you tried to read in the file with the statement shown below, it wouldn't work because it instructs LOAD DATA INFILE to look for tabs between fields:

> LOAD DATA INFILE 'data.txt' INTO TABLE table2
           FIELDS TERMINATED BY '\t';

The likely result is that each input line would be interpreted as a single field.

LOAD DATA INFILE can be used to read files obtained from external sources, too. For example, a file in dBASE format will have fields separated by commas and enclosed in double quotes. If lines in the file are terminated by newlines, the command shown below illustrates the field and line handling options you would use to load the file:

> LOAD DATA INFILE 'data.txt' INTO TABLE tbl_name
           FIELDS TERMINATED BY ',' ENCLOSED BY '"'
           LINES TERMINATED BY '\n';

Any of the field or line handling options may specify an empty string (''). If not empty, the FIELDS [OPTIONALLY] ENCLOSED BY and FIELDS ESCAPED BY values must be a single character. The FIELDS TERMINATED BY and LINES TERMINATED BY values may be more than one character. For example, to write lines that are terminated by carriage return-linefeed pairs, or to read a file containing such lines, specify a LINES TERMINATED BY '\r\n' clause.

FIELDS [OPTIONALLY] ENCLOSED BY controls quoting of fields. For output (SELECT ... INTO OUTFILE), if you omit the word OPTIONALLY, all fields are enclosed by the ENCLOSED BY character. An example of such output (using a comma as the field delimiter) is shown below:

"1","a string","100.20"
"2","a string containing a , comma","102.20"
"3","a string containing a \" quote","102.20"
"4","a string containing a \", quote and comma","102.20"

If you specify OPTIONALLY, the ENCLOSED BY character is used only to enclose CHAR and VARCHAR fields:

1,"a string",100.20
2,"a string containing a , comma",102.20
3,"a string containing a \" quote",102.20
4,"a string containing a \", quote and comma",102.20

Note that occurrences of the ENCLOSED BY character within a field value are escaped by prefixing them with the ESCAPED BY character. Also note that if you specify an empty ESCAPED BY value, it is possible to generate output that cannot be read properly by LOAD DATA INFILE. For example, the output just shown above would appear as shown below if the escape character is empty. Observe that the second field in the fourth line contains a comma following the quote, which (erroneously) appears to terminate the field:

1,"a string",100.20
2,"a string containing a , comma",102.20
3,"a string containing a " quote",102.20
4,"a string containing a ", quote and comma",102.20

For input, the ENCLOSED BY character, if present, is stripped from the ends of field values. (This is true whether or not OPTIONALLY is specified; OPTIONALLY has no effect on input interpretation.) Occurrences of the ENCLOSED BY character preceded by the ESCAPED BY character are interpreted as part of the current field value. In addition, duplicated ENCLOSED BY characters occurring within fields are interpreted as single ENCLOSED BY characters if the field itself starts with that character. For example, if ENCLOSED BY '"' is specified, quotes are handled as shown below:

"The ""BIG"" boss"  -> The "BIG" boss
The "BIG" boss      -> The "BIG" boss
The ""BIG"" boss    -> The ""BIG"" boss

FIELDS ESCAPED BY controls how to write or read special characters. If the FIELDS ESCAPED BY character is not empty, it is used to prefix the following characters on output:

  • The FIELDS ESCAPED BY character
  • The FIELDS [OPTIONALLY] ENCLOSED BY character
  • The first character of the FIELDS TERMINATED BY and LINES TERMINATED BY values
  • ASCII 0 (what is actually written following the escape character is ASCII '0', not a zero-valued byte)

If the FIELDS ESCAPED BY character is empty, no characters are escaped. It is probably not a good idea to specify an empty escape character, particularly if field values in your data contain any of the characters in the list just given.

For input, if the FIELDS ESCAPED BY character is not empty, occurrences of that character are stripped and the following character is taken literally as part of a field value. The exceptions are an escaped `0' or `N' (e.g., \0 or \N if the escape character is `\'). These sequences are interpreted as ASCII 0 (a zero-valued byte) and NULL. See below for the rules on NULL handling.

For more information about `\'-escape syntax, see section 1 Literals: how to write strings and numbers.

In certain cases, field and line handling options interact:

  • If LINES TERMINATED BY is an empty string and FIELDS TERMINATED BY is non-empty, lines are also terminated with FIELDS TERMINATED BY.
  • If the FIELDS TERMINATED BY and FIELDS ENCLOSED BY values are both empty (''), a fixed-row (non-delimited) format is used. With fixed-row format, no delimiters are used between fields. Instead, column values are written and read using the ``display'' widths of the columns. For example, if a column is declared as INT(7), values for the column are written using 7-character fields. On input, values for the column are obtained by reading 7 characters. Fixed-row format also affects handling of NULL values; see below. Note that fixed size format will not work if you are using a multi-byte character set.

Handling of NULL values varies, depending on the FIELDS and LINES options you use:

  • For the default FIELDS and LINES values, NULL is written as \N for output and \N is read as NULL for input (assuming the ESCAPED BY character is `\').
  • If FIELDS ENCLOSED BY is not empty, a field containing the literal word NULL as its value is read as a NULL value (this differs from the word NULL enclosed within FIELDS ENCLOSED BY characters, which is read as the string 'NULL').
  • If FIELDS ESCAPED BY is empty, NULL is written as the word NULL.
  • With fixed-row format (which happens when FIELDS TERMINATED BY and FIELDS ENCLOSED BY are both empty), NULL is written as an empty string. Note that this causes both NULL values and empty strings in the table to be indistinguishable when written to the file since they are both written as empty strings. If you need to be able to tell the two apart when reading the file back in, you should not use fixed-row format.

Some cases are not supported by LOAD DATA INFILE:

  • Fixed-size rows (FIELDS TERMINATED BY and FIELDS ENCLOSED BY both empty) and BLOB or TEXT columns.
  • If you specify one separator that is the same as or a prefix of another, LOAD DATA INFILE won't be able to interpret the input properly. For example, the following FIELDS clause would cause problems:
    FIELDS TERMINATED BY '"' ENCLOSED BY '"'
  • If FIELDS ESCAPED BY is empty, a field value that contains an occurrence of FIELDS ENCLOSED BY or LINES TERMINATED BY followed by the FIELDS TERMINATED BY value will cause LOAD DATA INFILE to stop reading a field or line too early. This happens because LOAD DATA INFILE cannot properly determine where the field or line value ends.

The following example loads all columns of the persondata table:

> LOAD DATA INFILE 'persondata.txt' INTO TABLE persondata;

No field list is specified, so LOAD DATA INFILE expects input rows to contain a field for each table column. The default FIELDS and LINES values are used.

If you wish to load only some of a table's columns, specify a field list:

> LOAD DATA INFILE 'persondata.txt'
           INTO TABLE persondata (col1,col2,...);

You must also specify a field list if the order of the fields in the input file differs from the order of the columns in the table. Otherwise, MySQL cannot tell how to match up input fields with table columns.

If a row has too few fields, the columns for which no input field is present are set to default values. Default value assignment is described in section 7 CREATE TABLE syntax.

An empty field value is interpreted differently than if the field value is missing:

  • For string types, the column is set to the empty string.
  • For numeric types, the column is set to 0.
  • For date and time types, the column is set to the appropriate ``zero'' value for the type. See section 3.6 Date and time types.

TIMESTAMP columns are only set to the current date and time if there is a NULL value for the column, or (for the first TIMESTAMP column only) if the TIMESTAMP column is left out from the field list when a field list is specified.

If an input row has too many fields, the extra fields are ignored and the number of warnings is incremented.

LOAD DATA INFILE regards all input as strings, so you can't use numeric values for ENUM or SET columns the way you can with INSERT statements. All ENUM and SET values must be specified as strings!

If you are using the C API, you can get information about the query by calling the API function mysql_info() when the LOAD DATA INFILE query finishes. The format of the information string is shown below:

Records: 1  Deleted: 0  Skipped: 0  Warnings: 0

Warnings occur under the same circumstances as when values are inserted via the INSERT statement (see section 14 INSERT syntax), except that LOAD DATA INFILE also generates warnings when there are too few or too many fields in the input row. The warnings are not stored anywhere; the number of warnings can only be used as an indication if everything went well. If you get warnings and want to know exactly why you got them, one way to do this is to use SELECT ... INTO OUTFILE into another file and compare this to your original input file.

For more information about the efficiency of INSERT versus LOAD DATA INFILE and speeding up LOAD DATA INFILE

© 1997-2000 TCX DataKonsult AB, 2000 SWsoft


MySQL v.3.23.11 language reference

17 UPDATE syntax

   UPDATE [LOW_PRIORITY]tbl_nameSETcol_name1=expr1,col_name2=expr2,...
    [WHERE where_definition] [LIMIT #]

UPDATE updates columns in existing table rows with new values. The SET clause indicates which columns to modify and the values they should be given. The WHERE clause, if given, specifies which rows should be updated. Otherwise all rows are updated.

If you specify the keyword LOW_PRIORITY, execution of the UPDATE is delayed until no other clients are reading from the table.

If you access a column from tbl_name in an expression, UPDATE uses the current value of the column. For example, the following statement sets the age column to one more than its current value:

> UPDATE persondata SET age=age+1;

UPDATE assignments are evaluated from left to right. For example, the following statement doubles the age column, then increments it:

> UPDATE persondata SET age=age*2, age=age+1;

If you set a column to the value it currently has, MySQL notices this and doesn't update it.

UPDATE returns the number of rows that were actually changed. In MySQL 3.22 or later, the C API function mysql_info() returns the number of rows that were matched and updated and the number of warnings that occurred during the UPDATE.

In MySQL 3.23 you can use LIMIT # to ensure that only a given number of rows are changed.

© 1997-2000 TCX DataKonsult AB, 2000 SWsoft


MySQL v.3.23.11 language reference

18 USE syntax

USE "path"

The USE "path" statement tells MySQL to use a Colibri database with this path as the default database for subsequent queries. Always use absolute paths. The database remains current until the end of the session, or until another USE statement is issued:

> USE "c:\abc";
> SELECT count(*) FROM mytable;      # selects from mytable table placed at c:\abc
> USE "d:\def";
> SELECT count(*) FROM mytable;      # selects from mytable table placed at d:\def

It is not recommended to use this statement in Colibri.

© 1997-2000 TCX DataKonsult AB, 2000 SWsoft


MySQL v.3.23.11 language reference

19 FLUSH syntax (clearing caches)

FLUSH flush_option [,flush_option]

You should use the FLUSH command if you want to clear some of the internal caches MySQL uses. To execute FLUSH, you must have the reload privilege.

flush_option can be any of the following:

HOSTS | Empties the host cache tables. You should flush the host tables if some of your hosts change IP number or if you get the error message Host ... is blocked. When more than max_connect_errors errors occur in a row for a given host while connection to the MySQL server, MySQL assumes something is wrong and blocks the host from further connection requests. Flushing the host tables allows the host to attempt to connect again. You can start mysqld with -O max_connection_errors=999999999 to avoid this error message.
LOGS | Closes and reopens the standard and update log files. If you have specified the update log file without an extension, the extension number of the new update log file will be incremented by one relative to the previous file. If you have used an extension in the file name, MySQL will close and reopen the update log file. On Unix you can use this behaviour to your advantage by first moving the file to another name and then issue FLUSH LOGS.
PRIVILEGES | Reloads the privileges from the grant tables in the mysql database.
TABLES | Closes all open tables.
STATUS | Resets most status variables to zero.

You can also access each of the commands shown above with the mysqladmin utility, using the flush-hosts, flush-logs, reload or flush-tables commands.

© 1997-2000 TCX DataKonsult AB, 2000 SWsoft


MySQL v.3.23.11 language reference

20 KILL syntax

KILL thread_id

Each connection to mysqld runs in a separate thread. You can see which threads are running with the SHOW PROCESSLIST command, and kill a thread with the KILL thread_id command.

If you have the process privilege, you can see and kill all threads. Otherwise, you can see and kill only your own threads.

You can also use the mysqladmin processlist and mysqladmin kill commands to examine and kill threads.

It is not recommended to use this command in Colibri.

© 1997-2000 TCX DataKonsult AB, 2000 SWsoft


MySQL v.3.23.11 language reference

21 SHOW syntax (Get information about tables, columns,...)

   SHOW DATABASES [LIKE wild]
or SHOW TABLES [FROM db_name] [LIKE wild]
or SHOW COLUMNS FROM tbl_name [FROM db_name] [LIKE wild]
or SHOW INDEX FROM tbl_name [FROM db_name]
or SHOW STATUS
or SHOW VARIABLES [LIKE wild]
or SHOW [FULL] PROCESSLIST
or SHOW TABLE STATUS [FROM db_name] [LIKE wild]
or SHOW GRANTS FOR user (*)

(*) Colibri ignores MySQL access rights.

SHOW provides information about databases, tables, columns or the server. If the LIKE wild part is used, the wild string can be a string that uses the SQL `%' and `_' wildcard characters.

You can use db_name.tbl_name as an alternative to the tbl_name FROM db_name syntax. These two statements are equivalent:

> SHOW INDEX FROM mytable FROM mydb;
> SHOW INDEX FROM mydb.mytable;

SHOW DATABASES lists the databases on the MySQL server host. You can also get this list using the mysqlshow command.

SHOW TABLES lists the tables in a given database. You can also get this list using the mysqlshow db_name command.

Note: If a user doesn't have any privileges for a table, the table will not show up in the output from SHOW TABLES or mysqlshow db_name.

SHOW COLUMNS lists the columns in a given table. If the column types are different than you expect them to be based on a CREATE TABLE statement, note that MySQL sometimes changes column types. See section 7.1 Silent column specification changes.

The DESCRIBE statement provides information similar to SHOW COLUMNS. See section 23 DESCRIBE syntax (Get information about columns).

SHOW TABLE STATUS (new in version 3.23) works likes SHOW STATUS, but provides a lot of information about each table. You can also get this list using the mysqlshow --status db_name command. The following columns are returned:

Column | Meaning
Name | Name of the table
Type | Type of table (ISAM, MyISAM or HEAP)
Row_format | The row storage format (Fixed, Dynamic, or Compressed)
Rows | Number of rows
Avg_row_length | Average row length
Data_length | Length of the data file
Max_data_length | Max length of the data file
Index_length | Length of the index file
Data_free | Number of allocated but not used bytes
Auto_increment | Next autoincrement value
Create_time | When the table was created
Update_time | When the data file was last updated
Check_time | When one last run a check on the table
Create_options | Extra options used with CREATE TABLE
Comment | The comment used when creating the table (or some information why MySQL couldn't access the table information).

SHOW FIELDS is a synonym for SHOW COLUMNS and SHOW KEYS is a synonym for SHOW INDEX. You can also list a table's columns or indexes with mysqlshow db_name tbl_name or mysqlshow -k db_name tbl_name.

SHOW INDEX returns the index information in a format that closely resembles the SQLStatistics call in ODBC. The following columns are returned:

Column | Meaning
Table | Name of the table
Non_unique | 0 if the index can't contain duplicates.
Key_name | Name of the index
Seq_in_index | Column sequence number in index, starting with 1.
Column_name | Column name.
Collation | How the column is sorted in the index. In MySQL, this can have values A (Ascending) or NULL (Not sorted).
Cardinality | Number of unique values in the index. This is updated by running isamchk -a.
Sub_part | Number of indexed characters if the column is only partly indexed. NULL if the entire key is indexed.

SHOW STATUS provides server status information (like mysqladmin extended-status). The output resembles that shown below, though the format and numbers may differ somewhat:

+--------------------------+--------+
| Variable_name            | Value  |
+--------------------------+--------+
| Aborted_clients          | 0      |
| Aborted_connects         | 0      |
| Connections              | 17     |
| Created_tmp_tables       | 0      |
| Delayed_insert_threads   | 0      |
| Delayed_writes           | 0      |
| Delayed_errors           | 0      |
| Flush_commands           | 2      |
| Handler_delete           | 2      |
| Handler_read_first       | 0      |
| Handler_read_key         | 1      |
| Handler_read_next        | 0      |
| Handler_read_rnd         | 35     |
| Handler_update           | 0      |
| Handler_write            | 2      |
| Key_blocks_used          | 0      |
| Key_read_requests        | 0      |
| Key_reads                | 0      |
| Key_write_requests       | 0      |
| Key_writes               | 0      |
| Max_used_connections     | 1      |
| Not_flushed_key_blocks   | 0      |
| Not_flushed_delayed_rows | 0      |
| Open_tables              | 1      |
| Open_files               | 2      |
| Open_streams             | 0      |
| Opened_tables            | 11     |
| Questions                | 14     |
| Slow_queries             | 0      |
| Threads_connected        | 1      |
| Threads_running          | 1      |
| Uptime                   | 149111 |
+--------------------------+--------+

The status variables listed above have the following meaning:

Aborted_clients | Number of connections that has been aborted because the client has died without closing the connection properly.
Aborted_connects | Number of tries to connect to the MySQL server that has failed.
Connections | Number of connection attempts to the MySQL server.
Created_tmp_tables | Number of implicit temporary tables that has been created while executing statements.
Delayed_insert_threads | Number of delayed insert handler threads in use.
Delayed_writes | Number of rows written with INSERT DELAYED.
Delayed_errors | Number of rows written with INSERT DELAYED for which some error occurred (probably duplicate key).
Flush_commands | Number of executed FLUSH commands.
Handler_delete | Number of requests to delete a row from a table.
Handler_read_first | Number of requests to read the first row in a table.
Handler_read_key | Number of requests to read a row based on a key.
Handler_read_next | Number of requests to read next row in key order.
Handler_read_rnd | Number of requests to read a row based on a fixed position.
Handler_update | Number of requests to update a row in a table.
Handler_write | Number of requests to insert a row in a table.
Key_blocks_used | The number of used blocks in the key cache.
Key_read_requests | The number of requests to read a key block from the cache.
Key_reads | The number of physical reads of a key block from disk.
Key_write_requests | The number of requests to write a key block to the cache.
Key_writes | The number of physical writes of a key block to disk.
Max_used_connections | The maximum number of connections that has been in use simultaneously.
Not_flushed_key_blocks | Keys blocks in the key cache that has changed but hasn't yet been flushed to disk.
Not_flushed_delayed_rows | Number of rows waiting to be written in INSERT DELAY queues.
Open_tables | Number of tables that are open.
Open_files | Number of files that are open.
Open_streams | Number of streams that are open (used mainly for logging)
Opened_tables | Number of tables that has been opened.
Questions | Number of queries sent to the server.
Slow_queries | Number of queries that has taken more than long_query_time
Threads_connected | Number of currently open connections.
Threads_running | Number of threads that are not sleeping.
Uptime | How many seconds the server has been up.

Some comments about the above:

  • If Opened_tables is big, then your table_cache variable is probably too small.
  • If key_reads is big, then your key_cache is probably too small. The cache hit rate can be calculated with key_reads/key_read_requests.
  • If Handler_read_rnd is big, then you have a probably a lot of queries that requires MySQL to scan whole tables or you have joins that doesn't use keys properly.

SHOW VARIABLES shows the values of the some of MySQL system variables. You can also get this information using the mysqladmin variables command. If the default values are unsuitable, you can set most of these variables using command-line options when mysqld starts up. The output resembles that shown below, though the format and numbers may differ somewhat:

+------------------------+--------------------------+
| Variable_name          | Value                    |
+------------------------+--------------------------+
| back_log               | 5                        |
| connect_timeout        | 5                        |
| basedir                | /my/monty/               |
| datadir                | /my/monty/data/          |
| delayed_insert_limit   | 100                      |
| delayed_insert_timeout | 300                      |
| delayed_queue_size     | 1000                     |
| join_buffer_size       | 131072                   |
| flush_time             | 0                        |
| interactive_timeout    | 28800                    |
| key_buffer_size        | 1048540                  |
| language               | /my/monty/share/english/ |
| log                    | OFF                      |
| log_update             | OFF                      |
| long_query_time        | 10                       |
| low_priority_updates   | OFF                      |
| max_allowed_packet     | 1048576                  |
| max_connections        | 100                      |
| max_connect_errors     | 10                       |
| max_delayed_threads    | 20                       |
| max_heap_table_size    | 16777216                 |
| max_join_size          | 4294967295               |
| max_sort_length        | 1024                     |
| max_tmp_tables         | 32                       |
| net_buffer_length      | 16384                    |
| port                   | 3306                     |
| protocol-version       | 10                       |
| record_buffer          | 131072                   |
| skip_locking           | ON                       |
| socket                 | /tmp/mysql.sock          |
| sort_buffer            | 2097116                  |
| table_cache            | 64                       |
| thread_stack           | 131072                   |
| tmp_table_size         | 1048576                  |
| tmpdir                 | /machine/tmp/            |
| version                | 3.23.0-alpha-debug       |
| wait_timeout           | 28800                    |
+------------------------+--------------------------+

SHOW PROCESSLIST shows you which threads are running. You can also get this information using the mysqladmin processlist command. If you have the process privilege, you can see all threads. Otherwise, you can see only your own threads. See section 20 KILL syntax. If you don't use the the FULL option, then only the first 100 characters of each query will be shown.

SHOW GRANTS FOR user lists the grant commands that must be issued to duplicate the grants for a user.

> SHOW GRANTS FOR root@localhost;
+---------------------------------------------------------------------+
| Grants for root@localhost                                           |
+---------------------------------------------------------------------+
| GRANT ALL PRIVILEGES ON *.* TO 'root''localhost' WITH GRANT OPTION |
+---------------------------------------------------------------------+

© 1997-2000 TCX DataKonsult AB, 2000 SWsoft


MySQL v.3.23.11 language reference

22 EXPLAIN syntax (Get information about a SELECT)

    EXPLAIN tbl_name
or  EXPLAIN SELECT select_options

EXPLAIN tbl_name is a synonym for DESCRIBE tbl_name or SHOW COLUMNS FROM tbl_name.

When you precede a SELECT statement with the keyword EXPLAIN, MySQL explains how it would process the SELECT, providing information about how tables are joined and in which order.

With the help of EXPLAIN, you can see when you must add indexes to tables to get a faster SELECT that uses indexes to find the records. You can also see if the optimizer joins the tables in an optimal order. To force the optimizer to use a specific join order for a SELECT statement, add a STRAIGHT_JOIN clause.

For non-simple joins, EXPLAIN returns a row of information for each table used in the SELECT statement. The tables are listed in the order they would be read. MySQL resolves all joins using a single-sweep multi-join method. This means that MySQL reads a row from the first table, then finds a matching row in the second table, then in the third table and so on. When all tables are processed, it outputs the selected columns and backtracks through the table list until a table is found for which there are more matching rows. The next row is read from this table and the process continues with the next table.

Output from EXPLAIN includes the following columns:

table
The table to which the row of output refers.
type
The join type. Information about the various types is given below.
possible_keys
The possible_keys column indicates which indexes MySQL could use to find the rows in this table. Note that this colums is totally indepentent on the order of the tables. That means that some of the keys in possible_keys may not the usable in practice with the generated table order. If this column is empty, there are no relevant indexes. In this case, you may be able to improve the performance of your query by examining the WHERE clause to see if it refers to some column or columns that would be suitable for indexing. If so, create an appropriate index and check the query with EXPLAIN again. See section 8 ALTER TABLE syntax. To see what indexes a table has, use SHOW INDEX FROM tbl_name.
key
The key column indicates the key that MySQL actually decided to use. The key is NULL if no index was chosen.
key_len
The key_len column indicates the length of the key that MySQL decided to use. The length is NULL if the key is NULL. Note that this tell us how many parts of a multi part key MySQL will actually use.
ref
The ref column shows which columns or constants are used with the key to select rows from the table.
rows
The rows column indicates the number of rows MySQL believe it must examine to execute the query.
Extra
If the Extra column includes the text Only index, this means that information is retrieved from the table using only information in the index tree. Normally, this is much faster than scanning the entire table. If the Extra column includes the text where used, it means that a WHERE clause will be used to restrict which rows will be matched against the next table or sent to the client.

The different join types are listed below, ordered from best to worst type:

system
The table has only one row (= system table). This is a special case of the const join type.
const
The table has at most one matching row, which will be read at the start of the query. Since there is only one row, values from the column in this row can be regarded as constants by the rest of the optimizer. const tables are very fast as they are read only once!
eq_ref
One row will be read from this table for each combination of rows from the previous tables. This the best possible join type, other than the const types. It is used when all parts of an index are used by the join and the index is UNIQUE or a PRIMARY KEY.
ref
All rows with matching index values will be read from this table for each combination of rows from the previous tables. ref is used if the join uses only a leftmost prefix of the key, or if the key is not UNIQUE or a PRIMARY KEY (in other words, if the join cannot select a single row based on the key value). If the key that is used matches only a few rows, this join type is good.
range
Only rows that are in a given range will be retrieved, using an index to select the rows. The ref column indicates which index is used.
index
This is the same as ALL, except that only the index tree is scanned. This is usually faster than ALL, as the index file is usually smaller than the data file.
ALL
A full table scan will be done for each combination of rows from the previous tables. This is normally not good if the table is the first table not marked const, and usually very bad in all other cases. You normally can avoid ALL by adding more indexes, so that the row can be retrieved based on constant values or column values from earlier tables.

You can get a good indication of how good a join is by multiplying all values in the rows column of the EXPLAIN output. This should tell you roughly how many rows MySQL must examine to execute the query. This number is also used when you restrict queries with the max_join_size variable.

The following example shows how a JOIN can be optimized progressively using the information provided by EXPLAIN.

Suppose you have the SELECT statement shown below, that you examine using EXPLAIN:

EXPLAIN SELECT tt.TicketNumber, tt.TimeIn,
            tt.ProjectReference, tt.EstimatedShipDate,
            tt.ActualShipDate, tt.ClientID,
            tt.ServiceCodes, tt.RepetitiveID,
            tt.CurrentProcess, tt.CurrentDPPerson,
            tt.RecordVolume, tt.DPPrinted, et.COUNTRY,
            et_1.COUNTRY, do.CUSTNAME
        FROM tt, et, et AS et_1, do
        WHERE tt.SubmitTime IS NULL
            AND tt.ActualPC = et.EMPLOYID
            AND tt.AssignedPC = et_1.EMPLOYID
            AND tt.ClientID = do.CUSTNMBR;

For this example, assume that:

  • The columns being compared have been declared as follows:

    Table | Column | Column type
    tt | ActualPC | CHAR(10)
    tt | AssignedPC | CHAR(10)
    tt | ClientID | CHAR(10)
    et | EMPLOYID | CHAR(15)
    do | CUSTNMBR | CHAR(15)

  • The tables have the indexes shown below:

    Table | Index
    tt | ActualPC
    tt | AssignedPC
    tt | ClientID
    et | EMPLOYID (primary key)
    do | CUSTNMBR (primary key)

  • The tt.ActualPC values aren't evenly distributed.

Initially, before any optimizations have been performed, the EXPLAIN statement produces the following information:

table type possible_keys                key  key_len ref  rows  Extra
et    ALL  PRIMARY                      NULL NULL    NULL 74
do    ALL  PRIMARY                      NULL NULL    NULL 2135
et_1  ALL  PRIMARY                      NULL NULL    NULL 74
tt    ALL  AssignedPC,ClientID,ActualPC NULL NULL    NULL 3872
      range checked for each record (key map: 35)

Since type is ALL for each table, this output indicates that MySQL is doing a full join for all tables! This will take quite a long time, as the product of the number of rows in each table must be examined! For the case at hand, this is 74 * 2135 * 74 * 3872 = 45,268,558,720 rows. If the tables were bigger, you can only imagine how long it would take...

One problem here is that MySQL can't (yet) use indexes on columns efficiently if they are declared differently. In this context, VARCHAR and CHAR are the same unless they are declared as different lengths. Since tt.ActualPC is declared as CHAR(10) and et.EMPLOYID is declared as CHAR(15), there is a length mismatch.

To fix this disparity between column lengths, use ALTER TABLE to lengthen ActualPC from 10 characters to 15 characters:

> ALTER TABLE tt MODIFY ActualPC VARCHAR(15);

Now tt.ActualPC and et.EMPLOYID are both VARCHAR(15). Executing the EXPLAIN statement again produces this result:

table type   possible_keys   key     key_len ref         rows    Extra
tt    ALL    AssignedPC,ClientID,ActualPC NULL NULL NULL 3872    where used
do    ALL    PRIMARY         NULL    NULL    NULL        2135
      range checked for each record (key map: 1)
et_1  ALL    PRIMARY         NULL    NULL    NULL        74
      range checked for each record (key map: 1)
et    eq_ref PRIMARY         PRIMARY 15      tt.ActualPC 1

This is not perfect, but is much better (the product of the rows values is now less by a factor of 74). This version is executed in a couple of seconds.

A second alteration can be made to eliminate the column length mismatches for the tt.AssignedPC = et_1.EMPLOYID and tt.ClientID = do.CUSTNMBR comparisons:

> ALTER TABLE tt MODIFY AssignedPC VARCHAR(15),
                      MODIFY ClientID   VARCHAR(15);

Now EXPLAIN produces the output shown below:

table type   possible_keys   key     key_len ref            rows     Extra
et    ALL    PRIMARY         NULL    NULL    NULL           74
tt    ref    AssignedPC,ClientID,ActualPC ActualPC 15 et.EMPLOYID 52 where used
et_1  eq_ref PRIMARY         PRIMARY 15      tt.AssignedPC  1
do    eq_ref PRIMARY         PRIMARY 15      tt.ClientID    1

This is ``almost'' as good as it can get.

The remaining problem is that, by default, MySQL assumes that values in the tt.ActualPC column are evenly distributed, and that isn't the case for the tt table. Fortunately, it is easy to tell MySQL about this:

shell> myisamchk --analyze PATH_TO_MYSQL_DATABASE/tt
shell> mysqladmin refresh

Now the join is ``perfect'', and EXPLAIN produces this result:

table type   possible_keys   key     key_len ref            rows    Extra
tt    ALL    AssignedPC,ClientID,ActualPC NULL NULL NULL    3872    where used
et    eq_ref PRIMARY         PRIMARY 15      tt.ActualPC    1
et_1  eq_ref PRIMARY         PRIMARY 15      tt.AssignedPC  1
do    eq_ref PRIMARY         PRIMARY 15      tt.ClientID    1

Note that the rows column in the output from EXPLAIN is an ``educated guess'' from the MySQL join optimizer; To optimize a query, you should check if the numbers are even close to the truth. If not, you may get better performance by using STRAIGHT_JOIN in your SELECT statement and trying to list the tables in a different order in the FROM clause.

© 1997-2000 TCX DataKonsult AB, 2000 SWsoft


MySQL v.3.23.11 language reference

23 DESCRIBE syntax (Get information about columns)

{DESCRIBE | DESC} tbl_name {col_name | wild}

DESCRIBE provides information about a table's columns. col_name may be a column name or a string containing the SQL `%' and `_' wildcard characters.

If the column types are different than you expect them to be based on a CREATE TABLE statement, note that MySQL sometimes changes column types. See section 7.1 Silent column specification changes.

This statement is provided for Oracle compatibility.

The SHOW statement provides similar information. See section 21 SHOW syntax (Get information about tables, columns,...).

© 1997-2000 TCX DataKonsult AB, 2000 SWsoft


MySQL v.3.23.11 language reference

24 LOCK TABLES/UNLOCK TABLES syntax

LOCK TABLES tbl_name [AS alias] {READ | [READ LOCAL] | [LOW_PRIORITY] WRITE}
            [, tbl_name {READ | [LOW_PRIORITY] WRITE} ...]
...
UNLOCK TABLES

LOCK TABLES locks tables for the current thread. UNLOCK TABLES releases any locks held by the current thread. All tables that are locked by the current thread are automatically unlocked when the thread issues another LOCK TABLES, or when the connection to the server is closed.

If a thread obtains a READ lock on a table, that thread (and all other threads) can only read from the table. If a thread obtains a WRITE lock on a table, then only the thread holding the lock can READ from or WRITE to the table. Other threads are blocked.

The difference between READ LOCAL and READ is that READ LOCAL allows non conflicting INSERT statements to execute while the lock is hold. This can't however be used if you are going to manipulate the database files outside MySQL while you hold the lock.

Each thread waits (without timing out) until it obtains all the locks it has requested.

WRITE locks normally have higher priority than READ locks, to ensure that updates are processed as soon as possible. This means that if one thread obtains a READ lock and then another thread requests a WRITE lock, subsequent READ lock requests will wait until the WRITE thread has gotten the lock and released it. You can use LOW_PRIORITY WRITE locks to allow other threads to obtain READ locks while the thread is waiting for the WRITE lock. You should only use LOW_PRIORITY WRITE locks if you are sure that there will eventually be a time when no threads will have a READ lock.

When you use LOCK TABLES, you must lock all tables that you are going to use and you must use the same alias as you are going to use in your queries! If you are using a table multiple times in a query (with aliases), you must get a lock for each alias! This policy ensures that table locking is deadlock free.

Note that you should NOT lock any tables that you are using with INSERT DELAYED. This is because that in this case the INSERT is done by a separate thread.

Normally, you don't have to lock tables, as all single UPDATE statements are atomic; no other thread can interfere with any other currently executing SQL statement. There are a few cases when you would like to lock tables anyway:

  • If you are going to run many operations on a bunch of tables, it's much faster to lock the tables you are going to use. The downside is, of course, that no other thread can update a READ-locked table and no other thread can read a WRITE-locked table.
  • MySQL doesn't support a transaction environment, so you must use LOCK TABLES if you want to ensure that no other thread comes between a SELECT and an UPDATE. The example shown below requires LOCK TABLES in order to execute safely:
    > LOCK TABLES trans READ, customer WRITE;
> select sum(value) from trans where customer_id= some_id;
> update customer set total_value=sum_from_previous_statement
           where customer_id=some_id;
> UNLOCK TABLES;
    Without LOCK TABLES, there is a chance that another thread might insert a new row in the trans table between execution of the SELECT and UPDATE statements.

By using incremental updates (UPDATE customer SET value=value+new_value) or the LAST_INSERT_ID() function, you can avoid using LOCK TABLES in many cases.

You can also solve some cases by using the user-level lock functions GET_LOCK() and RELEASE_LOCK(). These locks are saved in a hash table in the server and implemented with pthread_mutex_lock() and pthread_mutex_unlock() for high speed. See section 4.12 Miscellaneous functions.

© 1997-2000 TCX DataKonsult AB, 2000 SWsoft


MySQL v.3.23.11 language reference

25 SET syntax

SET [OPTION] SQL_VALUE_OPTION= value, ...

SET OPTION sets various options that affect the operation of the server or your client. Any option you set remains in effect until the current session ends, or until you set the option to a different value.

CHARACTER SET character_set_name | DEFAULT
This maps all strings from and to the client with the given mapping. Currently the only option for character_set_name is cp1251_koi8, but you can easily add new mappings by editing the `sql/convert.cc' file in the MySQL source distribution. The default mapping can be restored by using a character_set_name value of DEFAULT. Note that the syntax for setting the CHARACTER SET option differs from the syntax for setting the other options.
PASSWORD = PASSWORD('some password')
Set the password for the current user. Any non-anonymous user can change his own password!
PASSWORD FOR user = PASSWORD('some password')
Set the password for a specific user on the current server host. Only a user with access to the mysql database can do this. The user should be given in user@hostname format, where user and hostname are exactly as they are listed in the User and Host columns of the mysql.user table entry. For example, if you had an entry with User and Host fields of 'bob' and '%.loc.gov', you would write:
> SET PASSWORD FOR bob@"%.loc.gov" = PASSWORD("newpass");

or

> UPDATE mysql.user SET password=  PASSWORD("newpass") where user =

    "bob'<  BR> and host="%.loc.gov";
SQL_AUTO_IS_NULL = 0 | 1
If set to 1 (default) then one can find the last inserted row for a table with an auto_increment row with the following construct: WHERE auto_increment_column IS NULL. This is used by some ODBC programs like Access.
SQL_BIG_TABLES = 0 | 1
If set to 1, all temporary tables are stored on disk rather than in memory. This will be a little slower, but you will not get the error The table tbl_name is full for big SELECT operations that require a large temporary table. The default value for a new connection is 0 (i.e., use in-memory temporary tables).
SQL_BIG_SELECTS = 0 | 1
If set to 0, MySQL will abort if a SELECT is attempted that probably will take a very long time. This is useful when an inadvisable WHERE statement has been issued. A big query is defined as a SELECT that probably will have to examine more than max_join_size rows. The default value for a new connection is 1 (which will allow all SELECT statements).
SQL_LOW_PRIORITY_UPDATES = 0 | 1
If set to 1, all INSERT, UPDATE, DELETE and and LOCK TABLE WRITE statements wait until there is no pending SELECT or LOCK TABLE READ on the affected table.
SQL_MAX_JOIN_SIZE = value | DEFAULT
Don't allow SELECT's that will probably need to examine more than value row combinations. By setting this value one can catch SELECT's where keys are not used properly and that would probably take a long time. Setting this to not default will reset the SQL_BIG_SELECTS flag. If one sets the SQL_BIG_SELECTS flag again, the SQL_MAX_JOIN_SIZE variable will be ignored. One can set a default value for this variable by starting mysqld with -O max_join_size=#.
SQL_SAFE_MODE = 0 | 1
If set to 1, MySQL will abort if a UPDATE or DELETE is attempted that doesn't use a key or LIMIT in the WHERE clause. This makes it possible to catch wrong updates when creating SQL commands by hand.
SQL_SELECT_LIMIT = value | DEFAULT
The maximum number of records to return from SELECT statements. If a SELECT has a LIMIT clause, the LIMIT takes precedence over the value of SQL_SELECT_LIMIT. The default value for a new connection is ``unlimited''. If you have changed the limit, the default value can be restored by using a SQL_SELECT_LIMIT value of DEFAULT.
SQL_LOG_OFF = 0 | 1
If set to 1, no logging will be done to the standard log for this client, if the client has the process privilege. This does not affect the update log!
SQL_LOG_UPDATE = 0 | 1
If set to 0, no logging will be done to the update log for the client, if the client has the process privilege. This does not affect the standard log!
TIMESTAMP = timestamp_value | DEFAULT
Set the time for this client. This is used to get the original timestamp if you use the update log to restore rows.
LAST_INSERT_ID = #
Set the value to be returned from LAST_INSERT_ID(). This is stored in the update log when you use LAST_INSERT_ID() in a command that updates a table.
INSERT_ID = #
Set the value to be used by the following INSERT command when inserting an AUTO_INCREMENT value. This is mainly used with the update log.

© 1997-2000 TCX DataKonsult AB, 2000 SWsoft


MySQL v.3.23.11 language reference

26 GRANT and REVOKE syntax

GRANT priv_type [(column_list)] [, priv_type [(column_list)] ...]
    ON {tbl_name | * | *.* | db_name.*}
    TO user_name [IDENTIFIED BY 'password']
        [, user_name [IDENTIFIED BY 'password'] ...]
    [WITH GRANT OPTION]

REVOKE priv_type [(column_list)] [, priv_type [(column_list)] ...]
    ON {tbl_name | * | *.* | db_name.*}
    FROM user_name [, user_name ...]

GRANT is implemented in MySQL 3.22.11 or later. For earlier MySQL versions, the GRANT statement does nothing.

Colibri ignores access rights set by GRANT and REVOKE.

The GRANT and REVOKE commands allow system administrators to grant and revoke rights to MySQL users at four privilege levels:

Global level
Global privileges apply to all databases on a given server. These privileges are stored in the mysql.user table.
Database level
Database privileges apply to all tables in a given database. These privileges are stored in the mysql.db and mysql.host tables.
Table level
Table privileges apply to all columns in a given table. These privileges are stored in the mysql.tables_priv table.
Column level
Column privileges apply to single columns in a given table. These privileges are stored in the mysql.columns_priv table.

For the GRANT and REVOKE statements, priv_type may be specified as any of the following:

ALL PRIVILEGES      FILE                RELOAD
ALTER               INDEX               SELECT
CREATE              INSERT              SHUTDOWN
DELETE              PROCESS             UPDATE
DROP                REFERENCES          USAGE

ALL is a synonym for ALL PRIVILEGES. REFERENCES is not yet implemented. USAGE is currently a synonym for ``no privileges''. It can be used when you want to create a user that has no privileges.

To revoke the grant privilege from a user, use a priv_type value of GRANT OPTION:

REVOKE GRANT OPTION ON ... FROM ...;

The only priv_type values you can specify for a table are SELECT, INSERT, UPDATE, DELETE, CREATE, DROP, GRANT, INDEX and ALTER.

The only priv_type values you can specify for a column (that is, when you use a column_list clause) are SELECT, INSERT and UPDATE.

You can set global privileges by using ON *.* syntax. You can set database privileges by using ON db_name.* syntax. If you specify ON * and you have a current database, you will set the privileges for that database. (Warning: If you specify ON * and you don't have a current database, you will affect the global privileges!)

In order to accommodate granting rights to users from arbitrary hosts, MySQL supports specifying the user_name value in the form user@host. If you want to specify a user string containing special characters (such as `-'), or a host string containing special characters or wildcard characters (such as `%'), you can quote the user or host name (e.g., 'test-user'@'test-hostname').

You can specify wildcards in the hostname. For example, user@"%.loc.gov" applies to user for any host in the loc.gov domain, and user@"144.155.166.%" applies to user for any host in the 144.155.166 class C subnet.

The simple form user is a synonym for user@"%". Note: If you allow anonymous users to connect to the MySQL server (which is the default), you should also add all local users as user@localhost because otherwise the anonymous user entry for the local host in the mysql.user table will be used when the user tries to log into the MySQL server from the local machine! Anonymous users are defined by inserting entries with User='' into the mysql.user table. You can verify if this applies to you by executing this query:

> SELECT Host,User FROM mysql.user WHERE User='';

For the moment, GRANT only supports host, table, database and column names up to 60 characters long. A user name can be up to 16 characters.

The privileges for a table or column are formed from the logical OR of the privileges at each of the four privilege levels. For example, if the mysql.user table specifies that a user has a global select privilege, this can't be denied by an entry at the database, table or column level.

The privileges for a column can be calculated as follows:

global privileges
OR (database privileges AND host privileges)
OR table privileges
OR column privileges

In most cases, you grant rights to a user at only one of the privilege levels, so life isn't normally as complicated as above.

If you grant privileges for a user/hostname combination that does not exist in the mysql.user table, an entry is added and remains there until deleted with a DELETE command. In other words, GRANT may create user table entries, but REVOKE will not remove them; you must do that explicitly using DELETE.

In MySQL 3.22.12 or later, if a new user is created or if you have global grant privileges, the user's password will be set to the password specified by the IDENTIFIED BY clause, if one is given. If the user already had a password, it is replaced by the new one.

Warning: If you create a new user but do not specify an IDENTIFIED BY clause, the user has no password. This is insecure.

Passwords can also be set with the SET PASSWORD command. See section 25 SET syntax.

If you grant privileges for a database, an entry in the mysql.db table is created if needed. When all privileges for the database have been removed with REVOKE, this entry is deleted.

If a user doesn't have any privileges on a table, the table is not displayed when the user requests a list of tables (e.g., with a SHOW TABLES statement).

The WITH GRANT OPTION clause gives the user the ability to give to other users any privileges the user has at the specified privilege level. You should be careful to whom you give the grant privilege, as two users with different privileges may be able to join privileges!

You cannot grant another user a privilege you don't have yourself; the grant privilege allows you to give away only those privileges you possess.

Be aware that when you grant a user the grant privilege at a particular privilege level, any privileges the user already possesses (or is given in the future!) at that level are also grantable by that user. Suppose you grant a user the insert privilege on a database. If you then grant the select privilege on the database and specify WITH GRANT OPTION, the user can give away not only the select privilege, but also insert. If you then grant the update privilege to the user on the database, the user can give away the insert, select and update.

You should not grant alter privileges to a normal user. If you do that, the user can try to subvert the privilege system by renaming tables!

Note that if you are using table or column privileges for even one user, the server examines table and column privileges for all users and this will slow down MySQL a bit.

When mysqld starts, all privileges are read into memory. Database, table and column privileges take effect at once and user-level privileges take effect the next time the user connects. Modifications to the grant tables that you perform using GRANT or REVOKE are noticed by the server immediately. If you modify the grant tables manually (using INSERT, UPDATE, etc.), you should execute a FLUSH PRIVILEGES statement or run mysqladmin flush-privileges to tell the server to reload the grant tables.

The biggest differences between the ANSI SQL and MySQL versions of GRANT are:

  • ANSI SQL doesn't have global or database-level privileges and ANSI SQL doesn't support all privilege types that MySQL supports.
  • When you drop a table in ANSI SQL, all privileges for the table are revoked. If you revoke a privilege in ANSI SQL, all privileges that were granted based on this privilege are also revoked. In MySQL, privileges can be dropped only with explicit REVOKE commands or by manipulating the MySQL grant tables

© 1997-2000 TCX DataKonsult AB, 2000 SWsoft


MySQL v.3.23.11 language reference

27 CREATE INDEX syntax

CREATE [UNIQUE] INDEX index_name ON tbl_name (col_name[(length)],... )

The CREATE INDEX statement doesn't do anything in MySQL prior to version 3.22. In 3.22 or later, CREATE INDEX is mapped to an ALTER TABLE statement to create indexes. See section 8 ALTER TABLE syntax.

Normally, you create all indexes on a table at the time the table itself is created with CREATE TABLE. See section 7 CREATE TABLE syntax. CREATE INDEX allows you to add indexes to existing tables.

A column list of the form (col1,col2,...) creates a multiple-column index. Index values are formed by concatenating the values of the given columns.

For CHAR and VARCHAR columns, indexes can be created that use only part of a column, using col_name(length) syntax. (On BLOB and TEXT columns the length is required). The statement shown below creates an index using the first 10 characters of the name column:

> CREATE INDEX part_of_name ON customer (name(10));

Since most names usually differ in the first 10 characters, this index should not be much slower than an index created from the entire name column. Also, using partial columns for indexes can make the index file much smaller, which could save a lot of disk space and might also speed up INSERT operations!

Note that you can only add a index on a column that can have NULL values or on a BLOB/TEXT column if you are useing MySQL version 3.23.2 or newer and are using the MyISAM table type.

© 1997-2000 TCX DataKonsult AB, 2000 SWsoft


MySQL v.3.23.11 language reference

29 Comment syntax

The MySQL server supports the # to end of line, -- to end of line and /* in-line or multiple-line */ comment styles:

> select 1+1;     # This comment continues to the end of line
> select 1+1;     -- This comment continues to the end of line
> select 1 /* this is an in-line comment */ + 1;
> select 1+
/*
this is a
multiple-line comment
*/
1;

Note that the -- comment style requires you to have at least one space after the --!

Although the server understands the comment syntax just described, there are some limitations on the way that the mysql client parses /* ... */ comments:

  • Single-quote and double-quote characters are taken to indicate the beginning of a quoted string, even within a comment. If the quote is not matched by a second quote within the comment, the parser doesn't realize the comment has ended. If you are running mysql interactively, you can tell that it has gotten confused like this because the prompt changes from > to '> or ">.
  • A semicolon is taken to indicate the end of the current SQL statement and anything following it to indicate the beginning of the next statement.

These limitations apply both when you run mysql interactively and when you put commands in a file and tell mysql to read its input from that file with mysql < some-file.

MySQL doesn't support the `--' ANSI SQL comment style.

© 1997-2000 TCX DataKonsult AB, 2000 SWsoft


MySQL v.3.23.11 language reference

30 CREATE FUNCTION/DROP FUNCTION syntax

CREATE [AGGREGATE] FUNCTION function_name RETURNS {STRING|REAL|INTEGER}
       SONAME shared_library_name

DROP FUNCTION function_name

A user-definable function (UDF) is a way to extend MySQL with a new function that works like native (built in) MySQL functions such as ABS() and CONCAT().

AGGREGATE is a new option for MySQL 3.23. An AGGREGATE function works exactly like a native MySQL GROUP function like SUM or COUNT().

CREATE FUNCTION saves the function's name, type and shared library name in the mysql.func system table. You must have the insert and delete privileges for the mysql database to create and drop functions.

All active functions are reloaded each time the server starts, unless you start mysqld with the --skip-grant-tables option. In this case, UDF initialization is skipped and UDFs are unavailable. (An active function is one that has been loaded with CREATE FUNCTION and not removed with DROP FUNCTION.)

© 1997-2000 TCX DataKonsult AB, 2000 SWsoft


MySQL v.3.23.11 language reference

31 Is MySQL picky about reserved words?

A common problem stems from trying to create a table with column names that use the names of datatypes or functions built into MySQL, such as TIMESTAMP or GROUP. You're allowed to do it (for example, ABS is an allowed column name), but whitespace is not allowed between a function name and the `(' when using functions whose names are also column names.

The following words are explicitly reserved in MySQL. Most of them are forbidden by ANSI SQL92 as column and/or table names (for example, group). A few are reserved because MySQL needs them and is (currently) using a yacc parser:

action | add | aggregate | all
alter | after | and | as
asc | avg | avg_row_length | auto_increment
between | bigint | bit | binary
blob | bool | both | by
cascade | case | char | character
change | check | checksum | column
columns | comment | constraint | create
cross | current_date | current_time | current_timestamp
data | database | databases | date
datetime | day | day_hour | day_minute
day_second | dayofmonth | dayofweek | dayofyear
dec | decimal | default | delayed
delay_key_write | delete | desc | describe
distinct | distinctrow | double | drop
end | else | escape | escaped
enclosed | enum | explain | exists
fields | file | first | float
float4 | float8 | flush | foreign
from | for | full | function
global | grant | grants | group
having | heap | high_priority | hour
hour_minute | hour_second | hosts | identified
ignore | in | index | infile
inner | insert | insert_id | int
integer | interval | int1 | int2
int3 | int4 | int8 | into
if | is | isam | join
key | keys | kill | last_insert_id
leading | left | length | like
lines | limit | load | local
lock | logs | long | longblob
longtext | low_priority | max | max_rows
match | mediumblob | mediumtext | mediumint
middleint | min_rows | minute | minute_second
modify | month | monthname | myisam
natural | numeric | no | not
null | on | optimize | option
optionally | or | order | outer
outfile | pack_keys | partial | password
precision | primary | procedure | process
processlist | privileges | read | real
references | reload | regexp | rename
replace | restrict | returns | revoke
rlike | row | rows | second
select | set | show | shutdown
smallint | soname | sql_big_tables | sql_big_selects
sql_low_priority_updates | sql_log_off | sql_log_update | sql_select_limit
sql_small_result | sql_big_result | sql_warnings | straight_join
starting | status | string | table
tables | temporary | terminated | text
then | time | timestamp | tinyblob
tinytext | tinyint | trailing | to
type | use | using | unique
unlock | unsigned | update | usage
values | varchar | variables | varying
varbinary | with | write | when
where | year | year_month | zerofill

The following symbols (from the table above) are disallowed by ANSI SQL but allowed by MySQL as column/table names. This is because some of these names are very natural names and a lot of people have already used them.

  • ACTION
  • BIT
  • DATE
  • ENUM
  • NO
  • TEXT
  • TIME
  • TIMESTAMP

© 1997-2000 TCX DataKonsult AB, 2000 SWsoft


IRowsetIndex

IRowsetIndex is the primary interface for exposing index functionality in OLE DB.

The methods in IRowsetIndex are used to define a range of index entries to be read, to position at an index entry within the range, to fetch the index entry, and to access the contents of the index entry.

The following table shows how to perform various index operations.

Operation | Comments
Open an index | To get a handle to an IRowsetIndex object, the consumer calls IOpenRowset::OpenRowset, passing it the DBID of the index. The method returns a pointer to an index rowset.
Close an index | An index is closed by releasing all references to the index rowset.
Insert an index entry | New key entries are inserted into an index by using IRowsetChange.
Delete an index entry | Key entries are deleted from an index by using IRowsetChange.
Update an index entry | Key entries are updated in an index by first deleting the old index entry and then inserting a new index entry.
Traverse the index | To traverse an index, a user calls methods on IRowset.

Method | Description
GetIndexInfo | Returns information about the index rowset capabilities.
Seek | Allows direct positioning at a key value within the current range.
SetRange | Restricts the set of row entries visible through calls to IRowset::GetNextRows and IRowsetIndex::Seek.


IRowsetIndex::GetIndexInfo

Returns information about the index rowset capabilities.

HRESULT GetIndexInfo (
   ULONG *                        pcKeyColumns,
   DBINDEXCOLUMNDESC **   prgIndexColumnDesc,
   ULONG *                        pcIndexProperties,
   DBPROPSET **               prgIndexProperties);

Parameters

pcKeyColumns

[out]
A pointer to memory in which to return the number of key columns in the index.

prgIndexColumnDesc

[out]
A pointer to memory in which to return an array of DBINDEXCOLUMNDESC structures in key column order. The size of the array is equal to *pcKeyColumns. If an error occurs, *prgIndexColumnDesc is set to a null pointer.

pcIndexProperties

[out]
A pointer to memory in which to return the number of DBPROPSET structures returned in *prgIndexProperties. *pcIndexProperties is the total number of property sets for which the provider supports at least one property in the Index property group. If an error occurs, *pcIndexProperties is set to zero.

prgIndexProperties

[out]
A pointer to memory in which to return an array of DBPROPSET structures. One structure is returned for each property set that contains at least one property belonging to the Index property group.

The provider allocates memory for the structures and returns the address to this memory; the consumer releases this memory with IMalloc::Free when it no longer needs the structures. Before calling IMalloc::Free for *prgPropertySets, the consumer should call IMalloc::Free for the rgProperties element within each element of *prgPropertySets. If *pcIndexProperties is zero on output, or if an error occurs, the provider does not allocate any memory and ensures that *prgIndexProperties is a null pointer on output.

Return Code

S_OK
The method succeeded.

E_FAIL
A provider-specific error occurred.

E_INVALIDARG
pcKeyColumns, prgIndexColumnDesc, pcIndexProperties, or prgIndexProperties was a null pointer.

E_OUTOFMEMORY
The provider was unable to allocate sufficient memory in which to return the column description structures or properties of the index.

DB_E_NOINDEX
The rowset uses integrated indexes and there is no current index.

See Also

IDBProperties::GetPropertyInfo


IRowsetIndex::Seek

Allows direct positioning at a key value within the current range established by the IRowsetIndex::SetRange method.

HRESULT Seek (
   HACCESSOR   hAccessor,
   ULONG         cKeyValues,
   void *            pData,
   DBSEEK         dwSeekOptions);

Parameters

hAccessor

[in]
The handle of the accessor to use. This accessor must meet the following criteria, which are illustrated with a key that consists of columns A, B, and C, where A is the most significant column and C is the least significant column:

  • For each key column this accessor binds, it must also bind all more significant key columns. For example, the accessor can bind column A, columns A and B, or columns A, B, and C.

  • Key columns must be bound in order from most significant key column to least significant key column. For example, if the accessor binds columns A and B, then the first binding must bind column A and the second binding must bind column B.

  • If the accessor binds any non-key columns, key columns must be bound first. For example, if the accessor binds columns A, B, and the bookmark column, then the first binding must bind column A, the second binding must bind column B, and the third binding must bind the bookmark column.

    If the accessor does not meet these criteria, the method returns DB_E_BADBINDINFO or a status of DBSTATUS_E_BADACCESSOR for the offending column.

    If hAccessor is the handle of a null accessor (cBindings in IAccessor::CreateAccessor was zero), then Seek does not change the next fetch position.

cKeyValues

[in]
The number of bindings in hAccessor for which *pData contains valid data. SetRange retrieves data from the first cKeyValues key columns from *pData. For example, suppose the accessor binds columns A, B, and C of the key in the previous example and cKeyValues is 2. SetRange retrieves data for columns A
and B.

pData

[in]
A pointer to a buffer containing the key values to which to seek, at offsets that correspond to the bindings in the accessor.

dwSeekOptions

[in]
A bitmask describing the options for the Seek method. The values in DBSEEKENUM have the following meanings:

Value | Description
DBSEEK_FIRSTEQ | First key with values equal to the values in *pData.
DBSEEK_LASTEQ | Last key with values equal to the values in *pData.
DBSEEK_GE | First key with values greater than or equal to the values in *pData.
DBSEEK_GT | First key with values greater than the values in *pData.
DBSEEK_LE | First key with values less than or equal to the values in *pData.
DBSEEK_LT | First key with values less than the values in *pData.

Return Code

S_OK
The method succeeded.

E_FAIL
A provider-specific error occurred.

E_INVALIDARG
dwSeekOptions was invalid.

hAccessor was the handle of a null accessor.

cKeyValues was zero.

pData was a null pointer.

DB_E_BADACCESSORHANDLE
hAccessor was invalid.

DB_E_BADACCESSORTYPE
The specified accessor was not a row accessor.

DB_E_ERRORSOCCURRED
An error occurred while transferring data for one or more key columns. To determine the columns for which values were invalid, the consumer checks the status values.

DB_E_NOINDEX
The rowset uses integrated indexes and there is no current index.

DB_E_NOTFOUND
No key value matching the described characteristics could be found within the current range.

DB_E_NOTREENTRANT
The consumer called this method while it was processing a notification, and it is an error to call this method while processing the specified DBREASON value.

If this method performs deferred accessor validation and that validation takes place before any data is transferred, it can also return any of the following return codes for the reasons listed in the corresponding DBBINDSTATUS values in IAccessor::CreateAccessor:

E_NOINTERFACE
DB_E_BADBINDINFO
DB_E_BADORDINAL
DB_E_BADSTORAGEFLAGS
DB_E_UNSUPPORTEDCONVERSION

Comments

The Seek method provides the caller more control over the traversal of an index. Consider a relational query processor component implementing a merge join over inputs R1 and R2. R1, the outer input, is a rowset ordered by the joining column R1.X. R2, the inner input, is an indexed rowset on column R2.X. Suppose that R1.X has values {10, 20, 100, 110} and that R2.X has values {10, 20, ..., 30, ..., 40, ..., 50, ..., 100, ...}, then when searching R2.X, one could seek directly from 20 to 100 knowing the values of the input R1.X. In some cases, this strategy could be cost effective.

See Also

IRowset::GetNextRows, IRowsetIndex::SetRange


IRowsetIndex::SetRange

Restricts the set of row entries visible through calls to IRowset::GetNextRows and IRowsetIndex::Seek.

HRESULT SetRange (
   HACCESSOR   hAccessor,
   ULONG         cStartKeyColumns,
   void *            pStartData,
   ULONG         cEndKeyColumns,
   void *            pEndData,
   DBRANGE      dwRangeOptions);

Parameters

hAccessor

[in]
The handle of the accessor to use for both *pStartData and *pEndData. This accessor must meet the following criteria, which are illustrated with a key that consists of columns A, B, and C, where A is the most significant column and C is the least significant column:

  • For each key column this accessor binds, it must also bind all more significant key columns. For example, the accessor can bind column A, columns A and B, or columns A, B, and C.

  • Key columns must be bound in order from most significant key column to least significant key column. For example, if the accessor binds columns A and B, then the first binding must bind column A and the second binding must bind column B.

  • If the accessor binds any nonkey columns, key columns must be bound first. For example, if the accessor binds columns A, B, and the bookmark column, then the first binding must bind column A, the second binding must bind column B, and the third binding must bind the bookmark column.

    If the accessor does not meet these criteria, the method returns DB_E_BADBINDINFO or a status of DBSTATUS_E_BADACCESSOR for the offending column.

    If hAccessor is the handle of a null accessor (cBindings in IAccessor::CreateAccessor was zero), then SetRange does not set a range.

cStartKeyColumns

[in]
The number of bindings in hAccessor for which *pStartData contains valid data. SetRange retrieves data from the first cStartKeyValues key columns from *pStartData. For example, suppose the accessor binds columns A, B, and C of the key in the previous example and cStartKeyValues is 2. SetRange retrieves data for columns A and B.

pStartData

[in]
A pointer to a buffer containing the starting key values of the range, at offsets that correspond to the bindings in the accessor.

cEndKeyColumns

[in]
The number of bindings in hAccessor for which *pEndData contains valid data. SetRange retrieves data from the first cEndKeyValues key columns from *pEndData. For example, suppose the accessor binds columns A, B, and C of the key in the previous example and cEndKeyValues is 2. SetRange retrieves data for columns A and B.

pEndData

[in]
A pointer to a buffer containing the ending key values of the range, at offsets that correspond to the bindings in the accessor.

dwRangeOptions

[in]
A bitmask describing the options of the range. The values in DBRANGEENUM have the following meanings:

Value | Description
DBRANGE_ INCLUSIVESTART | The start boundary is inclusive (the default).
DBRANGE_ EXCLUSIVESTART | The start boundary is exclusive.
DBRANGE_ INCLUSIVEEND | The end boundary is inclusive (the default).
DBRANGE_ EXCLUSIVEEND | The end boundary is exclusive.
DBRANGE_ EXCLUDENULLS | Exclude NULLs from the range.
DBRANGE_PREFIX | Use *pStartData as a prefix. *pEndData must be a null pointer. Prefix matching can be specified entirely using the inclusive and exclusive flags. However, because prefix matching is an important common case, this flag enables the consumer to specify only the *pStartData values, and enables the provider to interpret this request quickly.
DBRANGE_MATCH | Set the range to all keys that match *pStartData. *pStartData must specify a full key. *pEndData must be a null pointer. Used for fast equality match.
DBRANGE_MATCH_N_MASK | Equal to 0xFF000000.
DBRANGE_MATCH_N_SHIFT | Equal to 24 to indicate the number of bits to shift to get the number N.

Return Code

S_OK
The method succeeded.

E_FAIL
A provider-specific error occurred.

E_INVALIDARG
dwRangeOptions was invalid.

cStartKeyValues was not zero and pStartData was a null pointer.

cEndKeyValues was not zero and pEndData was a null pointer.

hAccessor was the handle of a null accessor.

DB_E_BADACCESSORHANDLE
hAccessor was invalid.

DB_E_BADACCESSORTYPE
The specified accessor was not a row accessor.

DB_E_ERRORSOCCURRED
An error occurred while transferring data for one or more key columns. To determine the columns for which values were invalid, the consumer checks the status values.

DB_E_NOINDEX
The rowset uses integrated indexes and there is no current index.

If this method performs deferred accessor validation and that validation takes place before any data is transferred, it can also return any of the following return codes for the reasons listed in the corresponding DBBINDSTATUS values in IAccessor::CreateAccessor:

E_NOINTERFACE
DB_E_BADBINDINFO
DB_E_BADORDINAL
DB_E_BADSTORAGEFLAGS
DB_E_UNSUPPORTEDCONVERSION

Comments

A range defines a view in the index containing a contiguous set of key values. The *pStartData and *pEndData values always specify the starting and ending positions in the range, respectively. Thus, for an ascending index, *pStartData contains the smaller value and *pEndData contains the larger value; for a descending index, *pStartData contains the larger value and *pEndData contains the smaller value.

A range on the entire index is defined by calling SetRange (hAcc, 0, NULL, 0, NULL, 0). When a range is set, Seek can only position to rows in the current range.

Inclusive and Exclusive Ranges with Ascending Indexes

The DBRANGE_INCLUSIVE* and DBRANGE_EXCLUSIVE* flags apply only to the last value in the *pStartData and *pEndData buffers. The other values are always inclusive.

Examples with full keys

a) open ranges (single column key)

Desired range SetRange call
X > 5
SetRange(hAcc, 1, {5}, 0, NULL,
DBRANGE_EXCLUSIVESTART);
X &ge; 5
SetRange(hAcc, 1, {5}, 0, NULL,
DBRANGE_INCLUSIVESTART);
X < 5
SetRange(hAcc, 0, NULL, 1, {5},
DBRANGE_EXCLUSIVEEND);
X &le; 5
SetRange(hAcc, 0, NULL, 1, {5},
DBRANGE_INCLUSIVEEND);

b) closed ranges (single column key)

Desired range SetRange call
X &ge; 5 and
X &le; 10
SetRange(hAcc, 1, {5}, 1, {10},
DBRANGE_INCLUSIVESTART |
DBRANGE_INCLUSIVEEND);
X &ge; 5 and
X < 10
SetRange(hAcc, 1, {5}, 1, {10},
DBRANGE_INCLUSIVESTART |
DBRANGE_EXCLUSIVEEND);
X > 5 and
X &le; 10
SetRange(hAcc, 1, {5}, 1, {10},
DBRANGE_EXCLUSIVESTART |
DBRANGE_INCLUSIVEEND);
X > 5 and
X < 10
SetRange(hAcc, 1, {5}, 1, {10},
DBRANGE_EXCLUSIVESTART |
DBRANGE_EXCLUSIVEEND);

c) open ranges (multicolumn key [A, B])

The only way to specify open ranges with multicolumn indexes is by using partial keys. See the examples with partial keys below.

Notice that the range A > 5 and B = 1 cannot be specified because it does not correspond to a contiguous range.

d) closed ranges (multicolumn key [A, B])

Desired range SetRange call
A = 1 and
B &ge; 5 and
B &le; 10
SetRange(hAcc, 2, {1, 5}, 2, {1, 10},
DBRANGE_INCLUSIVESTART |
DBRANGE_INCLUSIVEEND);
A = 1 and B > 5
SetRange(hAcc, 2, {1, 5}, 1, {1},
DBRANGE_EXCLUSIVESTART |
DBRANGE_INCLUSIVEEND);
A = 1 and B < 5
SetRange(hAcc, 1, {1}, 2, {1, 5},
DBRANGE_INCLUSIVESTART |
DBRANGE_EXCLUSIVEEND);

Examples with partial keys

e) open ranges (multicolumn key [A, B])

Desired range SetRange call
A > 5
SetRange(hAcc, 1, {5}, 0, NULL,
DBRANGE_EXCLUSIVESTART);
A &ge; 5
SetRange(hAcc, 1, {5}, 0, NULL,
DBRANGE_INCLUSIVESTART);
A = 5
SetRange(hAcc, 1, {5}, 1,{5},
DBRANGE_INCLUSIVESTART |
DBRANGE_INCLUSIVEEND);
A < 5
SetRange(hAcc, 0, NULL, 1, {5},
DBRANGE_EXCLUSIVEEND);
A &le; 5
SetRange(hAcc, 0, NULL, 1, {5},
DBRANGE_INCLUSIVEEND);

f) closed ranges (multicolumn key [A,B])

Desired range SetRange call
A > 5 and A &le; 10
SetRange(hAcc, 1, {5}, 1, {10},
DBRANGE_EXCLUSIVESTART |
DBRANGE_INCLUSIVEEND);

Prefix Matching

SetRange provides the DBRANGE_PREFIX flag to make it easier for a consumer to formulate ranges involving keys whose value represents a prefix. Consider the text command SELECT * FROM T WHERE T.A LIKE "abc*". This range can be formulated using only the inclusive and exclusive flags as follows for an ascending index:

SetRange (hAcc, 1, {"abc"}, 1, {"abd"}, DBRANGE_INCLUSIVESTART | DBRANGE_EXCLUSIVEEND);

This requires the consumer to know the collation order. The DBRANGE_PREFIX flag is provided to make it easier for the consumer to formulate this very common case as follows:

SetRange(hAcc, 1, {"abc"}, 0, NULL, DBRANGE_PREFIX);

Examples

Desired range SetRange call
A = 1 and
B like "abc*"
SetRange(hAcc, 2, {1, "abc"}, 0, NULL,
DBRANGE_PREFIX);

This call is the same regardless of whether DBRANGE_PREFIX is used with an ascending or descending index.

Equality Matching

To facilitate the formulation of ranges involving equality, the SetRange method offers the DBRANGE_MATCH option flag. Consider the example SELECT * FROM T WHERE T.X = 5. The corresponding range can be formulated in terms of the inclusive and exclusive flags as follows:

SetRange(hAcc, 1, {5}, 1, {5}, DBRANGE_INCLUSIVESTART | DBRANGE_INCLUSIVEEND);

The same range can be formulated using the match flags as follows:

SetRange(hAcc, 1, {5}, 0, NULL, DBRANGE_MATCH);

Example

Desired range SetRange call
A = 5 and B= 6
SetRange(hAcc, 2, {5, 6}, 2, {5, 6},
DBRANGE_INCLUSIVESTART |
DBRANGE_INCLUSIVEEND);
A = 5 and B= 6
SetRange(hAcc, 2, {5, 6}, 0, NULL,
DBRANGE_MATCH);

These calls are the same regardless of whether DBRANGE_MATCH is used with an ascending or descending index.

DBRANGE_MATCH_N is an extension of DBRANGE_MATCH, which indicates to the provider that the first N key values should be assumed to define comparison on equality. This is achieved by reserving the 8 high-order bits of dwRangeOptions to encode the value N. The defined values are DBRANGE_MATCH_N_SHIFT and DBRANGE_MATCH_N_MASK.

Example

a = 5, b = 6, c = 7, d = 8, e = 9, f >= 10 and f <= 20 becomes:

   SetRange (hAcc,
      6, {5,6,7,8,9,10},
      6, {5,6,7,8,9,20},
      (5 << DBRANGE_MATCH_N_SHIFT) | DB_RANGE_INCLUSIVESTART | DB_RANGE_INCLUSIVEEND);

Providers will check whether (dwRangeOptions and DBRANGE_MATCH_N_MASK) is non-zero. If so, then the key values will be interpreted by taking the first N keys encoded in the high-order bits as the keys on which to perform an equality match.

Ranges That Include NULLs

To save consumers from having to determine whether NULL values sort at the start or the end of an index, DBRANGE_EXCLUDENULLS excludes NULL values from the final column specified in *pStartData or *pEndData. This value of dwRangeOptions can only be used with partial keys. It is equivalent to one of the following:

  • If NULL values sort at the start of the index, it is equivalent to specifying an additional column in *pStartData, setting the value of the status of that column to DBSTATUS_S_ISNULL, and setting the DBRANGE_EXCLUSIVESTART value in dwRangeOptions. Thus, the range will start after the last NULL value in the column.

  • If NULL values sort at the end of the index, it is equivalent to specifying an additional column in *pEndData, setting the value of the status of that column to DBSTATUS_S_ISNULL, and setting the DBRANGE_EXCLUSIVEEND value in dwRangeOptions. Thus, the range will end before the first NULL value in the column.

Thus, the consumer does not need to know if NULL values sort at the start or end of the index.

The DBRANGE_EXCLUDENULLS flag is defined to allow consumers to easily obtain contiguous key values excluding NULLs at the start or end of the range. For multicolumn indexes (for example, [X, Y]), this means that key values for the prefix of the key must be an equality match. For example, it makes sense to set a range on X = 5 and DBRANGE_EXCLUDENULLS, but not on X BETWEEN 4 AND 6 and DBRANGE_EXCLUDENULLS because the range X BETWEEN 4 AND 6 and Y IS NOT NULL is not contiguous. Therefore, to use DBRANGE_EXCLUDENULLS a consumer must use an equality comparison or MATCH on the prefix of a multicolumn key.

To determine how an index treats NULLs, a consumer checks the information returned by GetIndexInfo method or the INDEXES schema rowset of IDBSchemaRowset.

Examples

Desired range SetRange call
X is NULL
SetRange(hAcc, 1, {NULL}, 1, {NULL},
DBRANGE_INCLUSIVESTART |
DBRANGE_INCLUSIVEEND);
X is not NULL
SetRange(hAcc, 0, NULL, 0, NULL,
DBRANGE_EXCLUDENULLS);
A = 4 and
B is not NULL
SetRange(hAcc, 1,{4}, 1, {4},
DBRANGE_INCLUSIVESTART |
DBRANGE_INCLUSIVEEND |
DBRANGE_EXCLUDENULLS);
A = 4 and
B is not NULL
SetRange(hAcc, 1, {4}, 0, NULL,
DBRANGE_MATCH | DBRANGE_EXCLUDENULLS );

Duplicate Keys

A SetRange request (with the exclusive flag on an ascending index allowing duplicate keys) sets the index position at the first index entry greater than the *pStartData value. If the index is descending, then SetRange sets the position at the first entry less than the *pStartData value.

End of Range

An index is traversed using IRowset::GetNextRows. This method returns DB_S_ENDOFROWSET when it reaches the end of the currently set range, or when it tries to read before the beginning or after the end of the index. This method also returns DB_S_ENDOFROWSET when the rowset is being populated asynchronously and no additional rows are available at this time. To determine whether additional rows may be available, the consumer should call IDBAsynchStatus::GetStatus or listen for the IDBAsynchNotify::OnStop notification.

Inclusive and Exclusive Ranges with Descending Indexes

As mentioned earlier, with descending indexes the user specifies the values that determine the start of the range using *pStartData and the values that determine the end of the range using *pEndData. The following are some examples.

Examples with full keys

a) open ranges (single column key)

Desired range SetRange call
X > 5
SetRange(hAcc, 0, NULL, 1, {5},
DBRANGE_EXCLUSIVEEND);
X &ge; 5
SetRange(hAcc, 0, NULL, 1, {5},
DBRANGE_INCLUSIVEEND);
X < 5
SetRange(hAcc, 1, {5}, 0, NULL,
DBRANGE_EXCLUSIVESTART);
X &le; 5
SetRange(hAcc, 1, {5}, 0, NULL,
DBRANGE_INCLUSIVESTART);

b) closed ranges (single column key)

Desired range SetRange call
X &ge; 5 and
X &le; 10
SetRange(hAcc, 1, {10}, 1, {5},
DBRANGE_INCLUSIVESTART |
DBRANGE_INCLUSIVEEND);
X &ge; 5 and
X < 10
SetRange(hAcc, 1, {10}, 1, {5},
DBRANGE_EXCLUSIVESTART |
DBRANGE_INCLUSIVEEND);
X > 5 and
X &le; 10
SetRange(hAcc, 1, {10}, 1, {5},
DBRANGE_INCLUSIVESTART |
DBRANGE_EXCLUSIVEEND);
X > 5 and
X < 10
SetRange(hAcc, 1, {10}, 1, {5},
DBRANGE_EXCLUSIVESTART |
DBRANGE_EXCLUSIVEEND);

c) open ranges (multicolumn key [A, B])

The only way to specify open ranges with multicolumn indexes is by using partial keys. See examples with partial keys below.

The range A > 5 and B = 1 cannot be specified because it does not correspond to a contiguous range.

d) closed ranges (multicolumn key [A, B])

Desired range SetRange call
A = 1 and
B &ge; 5 and
B &le; 10
SetRange(hAcc, 2, {1, 10}, 2, {1, 5},
DBRANGE_INCLUSIVESTART |
DBRANGE_INCLUSIVEEND);
A = 1 and B > 5
SetRange(hAcc, 1, {1}, 2, {1, 5},
DBRANGE_INCLUSIVESTART |
DBRANGE_EXCLUSIVEEND);
A = 1 and B < 5
SetRange(hAcc, 2, {1, 5}, 1, {1},
DBRANGE_EXCLUSIVESTART |
DBRANGE_INCLUSIVEEND);

Examples with partial keys

e) open ranges (multicolumn key [A, B])

Desired range SetRange call
A > 5
SetRange(hAcc, 0, NULL, 1, {5},
DBRANGE_EXCLUSIVEEND);
A &ge; 5
SetRange(hAcc, 0, NULL, 1, {5},
DBRANGE_INCLUSIVEEND);
A = 5
SetRange(hAcc, 1, {5}, 1, {5},
DBRANGE_INCLUSIVESTART |
DBRANGE_INCLUSIVEEND);
A < 5
SetRange(hAcc, 1, {5}, 0, NULL,
DBRANGE_EXCLUSIVESTART);
A &le; 5
SetRange(hAcc, 1, {5}, 0, NULL,
DBRANGE_INCLUSIVESTART);

f) closed ranges (multicolumn key [A,B])

Desired range SetRange call
A > 5 and
A &le; 10
SetRange(hAcc, 1, {10}, 1, {5},
DBRANGE_INCLUSIVESTART |
DBRANGE_EXCLUSIVEEND);

See Also

IRowset::GetNextRows, IRowsetIndex::Seek