Today's discussion of how to access row set information continues by examining the more advanced aspects of data access and navigation: column types supported, handling these various typ
Trang 1The key feature of this simple application is that it isn't tied to any particular query result You can modify the SQL command
to access a different number of rows or for different tables, and the application will still work!
Today's discussion of how to access row set information continues by examining the more advanced aspects of data access and navigation: column types supported, handling these various types, defining and using cursors, using bookmarks, and making changes to row data.
Navigation
Listing 19.4 shows you how to navigate a row set sequentially, using the GetNextRows method of the IRowset interface.
As you know, a cursor is a type of pointer that points to the current row you are accessing With the GetNextRows method, the cursor starts at the beginning of the row set and moves sequentially through the row set as you call the GetNextRows method.
As demonstrated in the example, you can use the GetNextRows method to move the cursor a number of rows at a time The GetNextRows method functions until the end of the row set; then the RestartPosition method of the IRowset
Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com
Trang 2interface repositions the cursor to the beginning of the row set.
Bookmarks
If a data provider supports nonsequential access, it can access rows based on a key value, called a bookmark in OLE DB
terminology OLE DB supports two types of bookmarks: numeric and key value bookmarks.
Listing 19.5 Using the GETROWSAT Method to Jump to a Particular Record
1: // Lookup CustomerID 3!
2: lLookup = 3;
3:
4: // Obtain Access to the IRowsetLocate Interface
5: pRowset->QueryInterface(IID_IAccessor, (void **) &pRowsetLocate);
6: pRowsetLocate->GetRowsAt(0, // Reserved for Future
17: pRowset->GetData(hRows[0], hAccessor, pBuffer);
Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com
Trang 318: // Print Out The Field Values
19: printf("%ld\t%.40s\n", (ULONG) pBuffer[pBindings[0].obValue],
Column Types
OLE DB supports all the standard Windows data types You can use these types to describe database columns A column's type
is found in the wType field of both of the DBCOLUMNINFO and DBBINDING structures Table 19.2 lists all the column type constants and the associated descriptions that OLE DB supports.
Table 19.2 OLE DB-Supported Data Types for Columns and Parameters
DBTYPE_EMPTY A type was not specified Used when defining variant type fields.
DBTYPE_NULL A NULL value Used when defining variant type fields.
DBTYPE_RESERVED Reserved for future use.
DBTYPE_I1 A single-byte integer, signed.
DBTYPE_UI1 A single-byte integer, unsigned.
DBTYPE_UI2 A 2-byte integer, unsigned.
DBTYPE_UI4 A 4-byte integer, unsigned.
DBTYPE_UI8 An 8-byte integer, unsigned.
DBTYPE_R4 A single-precision floating point.
DBTYPE_R8 A double-precision floating point.
DBTYPE_DECIMAL An exact numeric decimal value, stored in OLE form.
DBTYPE_NUMERIC An exact numeric decimal value, stored in standard form.
DBTYPE_DATE A date stored in OLE form.
DBTYPE_BOOL A Boolean value, stored in OLE form.
DBTYPE_BYTES An array of bytes The length is specified by the cbMaxLen field.
DBTYPE_BSTR A Unicode character string The length of the string is stored in the
first two bytes.
DBTYPE_STR An ANSI NULL -terminated character string.
DBTYPE_WSTR A Unicode NULL -terminated character string.
DBTYPE_VARIANT A variant in OLE form.
DBTYPE_IDISPATCH A pointer to an OLE object.
Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com
Trang 4DBTYPE_IUNKNOWN A pointer to an OLE interface.
DBTYPE_GUID A GUID (Globally Unique Identifier).
DBTYPE_BYREF A pointer to a type Used in combination with the other data types
listed here For example, to specify a pointer to a single-byte signed integer, use DBTYPE_I1 | DBTYPE_BYREF (Note: The | specifies a logical OR operation.)
DBTYPE_ARRAY A pointer to a SAFEARRAY
DBTYPE_VECTOR A DBVECTOR structure used to define an array of another type;
used in conjunction with another type For example, to specify a vector of single-byte signed integers, use DBTYPE_I1 | DBTYPE_VECTOR
DBTYPE_UDT A user-defined data type.
DBTYPE_DBDATE A DBDATE structure.
DBTYPE_DBTIME A DBTIME structure.
DBTYPE_DBTIMESTAMP A DBTIMESTAMP structure.
BLOBs
Binary Large Objects (BLOBs) can hold images, long text fields, or other large binary field types OLE DB supports BLOB fields if your data provider also supports them Consult your data source documentation to determine how to create a BLOB type field BLOB columns can be retrieved as one large chunk and stored in memory, or they can be retrieved one piece at a time When you are accessing a BLOB column or one chunk of data, the process of retrieving the field data is the same as for any other column The only difference is that you need to allocate a large buffer Listing 19.6 demonstrates how to retrieve a 7,500-byte BLOB column from a data source This example assumes that this column will never be bigger than 7,500 bytes Typically, a BLOB field has the type DBTYPE_BYTES , DBTYPE_WSTR , or DBTYPE_STR
Listing 19.6 How to Retrieve a BLOB Column as a Single Memory Object
19: // These Parameters Are for Future Use
Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com
Trang 539: // Obtain Accessor Interface
40: pRowset->QueryInterface(IID_Accessor, (void **) &pAccessor);
52: pRowset->GetNextRows(NULL, 0, 1, &lNumRows, &phRow);
53: pRowset->GetData(phRow[0], hAccessor, pData);
54 // Remember to release pAccessor;
As this example shows, the process of accessing a BLOB column as a single in-memory object isn't very difficult You can also access a BLOB column by using the OLE streaming interfaces Day 20 covers these interfaces in more detail, including how to use them to access BLOB columns.
Unicode String Processing
Unicode strings are used to support international character sets Many strings defined by OLE DB are defined as Unicode character strings Each Unicode character is 16-bits, twice the size of an ANSI character string For the most part,
NULL -terminated Unicode strings can be manipulated like NULL -terminated ANSI strings The following special
considerations apply to Unicode strings:
When using the printf function, use the %S format directive to print Unicode strings.
●
You can use the functions MultiByteToWideChar and WideCharToMultiByte to convert ANSI strings to Unicode strings, and vice versa.
●
Many functions defined for ANSI character strings are also defined for Unicode character strings, for example,
lstrcat and lstrlen
●
Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com
Trang 6To use the generic string functions for Unicode characters in Visual C++, you must use the #define _UNICODE directive and include the <wchar.h> header files.
●
Cursors
The final topic for today is cursors Cursors are used to navigate a row set If you have used Data Access Objects (DAO), Remote Data Objects (RDO), or Open Database Connectivity (ODBC) you are probably already familiar with different types of cursors that facilitate record navigation and locking This discussion concentrates on the various types of cursors, why they are used, and the Rowset object properties that must be set to invoke them Tomorrow's topics (Day 20) include OLE DB object properties and the implementation of cursors in more detail.
Static Cursors
When using a Static cursor, the order of the rows is in the natural data source order, and if the row set is changed in any way while it is opened, those changes aren't reflected Changes are recognized only when the row set is closed and reopened To specify that a row set uses a static type of cursor, the DBPROP_CANSCROLLBACKWARDS property is set to VARIANT_TRUE and the DBPROP_OTHERINSERT and DBPROP_OTHERUPDATEDELETE properties are set to VARIANT_FALSE
cursors, how they affect row set access, and the Rowset properties that must be set to invoke these cursor types The
discussion of OLE DB continues tomorrow with a more detailed look at properties, transactions, and OLE DB streaming mechanisms.
Q&A
This section answers some common questions related to today's topics.
Q Does OLE DB provide any way for me to search for a particular value in a row set?
A OLE DB provides the IRowsetIndex interface, which I didn't discuss in this lesson You can use this interface with an associated data source index to search for specific rows in a row set, based on key values A data provider must support indexing to use this interface.
Q Are queries the only way to create row sets?
Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com
Trang 7A No, row sets can be generated directly from the Session object if a data provider doesn't support the Rowset object Row sets generated in this manner will contain the complete contents of a data provider object in a tabular form (In the case of a database, a data provider object would typically be the contents of a table.) The
IDBSchemaRowset interface can also be used to generate row sets that contain data source schema information.
Q How does OLE DB handle multiuser row set access?
A OLE DB provides a Transaction object for managing record locking and sharing in a multiuser environment Day 20 covers the Transaction object in more detail.
Modify the application in Listing 19.4 to display schema information for the result of the query Include the column
name, type, length, and so on Hint: Look at what's stored in the DBCOLUMNINFO structure and at the
© Copyright, Sams Publishing All rights reserved.
Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com
Trang 8Teach Yourself Database Programming
with Visual C++ 6 in 21 days
Day 20
Properties, Transactions, and Indexes
Properties and Groups
The Index Object
The IRowsetIndex Interface
Trang 9❍
Today's lesson covers three important topics in OLE DB application development: properties, transactions, and the
Index object You have already learned about OLE DB objects and have used their methods, but you haven't yetdiscovered how to change the state of an object Today you will learn how to use properties to control the state of
an object, or in other words, how to set and retrieve property values of OLE DB objects by using special interfaces.The other major topics for today are the Transaction object and the Index object
Today you will
Learn how to use properties and groups to set the state of various OLE DB objects by using the interfacesthey provide
Properties and Groups
Properties specify the attributes of an OLE DB object and can determine how the object behaves Some propertiescan only be read, whereas others can be read and written Properties are identified by globally unique identifier(GUID) constants and grouped according to the object on which they function The following objects have specialproperties: Columns, DataSource, DataSource initialization objects, Index, Rowset, Session, and
Table Today's explanation of properties begins by discussing how to retrieve a property value
Getting Properties
Most OLE DB objects use the GetProperties method to retrieve property values Table 20.1 summarizes themethods used by each OLE DB object to access its properties Because most objects use the GetProperties
method, this section focuses on that mechanism for retrieving property values
Table 20.1 The Methods Used by OLE DB Objects to Retrieve Property Values OLE DB Object Interface Method
IcommandInfoIcommandProperties
GetPropertiesGetPropertiesGetProperties
Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com
Trang 10GetProperties(ULONG lNumPropIDs, DBPROPIDSET rPropIDs[],
ULONG lNumPropSets, DBPROPSET **prPropSets);
The lNumPropIDs parameter specifies the number of elements in the rPropIDs array The rPropIDs arraycontains a collection of DBPROPIDSET structures that specify the collection of properties for which you want tosee values The DBPROPIDSET structure is defined as follows:
typedef struct tagDBPROPIDSET {
DBPROPID *rgPropertyIDs;
ULONG cPropertyIDs;
GUID guidPropertySet;
} DBPROPIDSET;
The rgPropertyIDs field defines an array of Property IDs That is, the DBPROPIDSET holds a collection
of property IDs, and the GetProperties method actually takes a collection of DBPROPIDSET structures,which in themselves contain a collection of property IDs You will typically define a single DBPROPIDSET
structure, which contains a collection of the property IDs you want to retrieve The cPropertyIDs field definesthe number of elements in the rgPropertyIDs array The guidPropertySet field holds a GUID that
defines the property group to which the properties in the rgPropertyIDs array belong Table 20.2 defines thegroup GUID constants and the OLE DB object they define
Table 20.2 The OLE DB Property Groups OLE DB Object Group GUID Constant
typedef struct tagDBPROPSET {
Trang 11The memory used by the prPropSet parameter is allocated by the call to the
deallocate this memory when it is no longer required You can also use the
CoTaskMemFree API call if you don't have a pointer to the IMalloc interface available
It saves several lines of code, and it's functionally equivalent
The rgProperties field defines an array of DBPROP structures The DBPROP structures hold the actual
property values The cProperties field defines the number of elements in the rgProperties array The
guidProperties defines the property group to which the properties in the rgProperties array belong The
DBPROP structure, which holds the actual property values, is defined as follows:
typedef struct tagDBPROP {
field and their meanings The colid field defines the column for which this property is defined The colid is a
DBID type structure, as you might recall from Day 18, "Querying a Data Source." Finally the vValue field
defines the value of the property; it's defined as a standard C++ VARIANT type
Table 20.3 The Property Status Values Status Value Description
state; the operation was performed
Status Value Description
operation was denied because it couldn't be set for all columns
property from being set
Now that you have the background information you need in order to use the GetProperties method, you canconstruct the appropriate structures to retrieve a property's value and interpret the results You need to define one
Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com
Trang 12structure to define the property ID you want to retrieve, and you need to define one structure to return the actualproperty values (A listing and descriptions of OLE DB object property IDs appear later in this lesson.)
In the Day 18 compendium of the SQL command language, I discussed the use of the GetProperties method
of the IDBProperties interface to determine whether the data provider supported the SQL command language.The property ID to check for SQL support is DPROP_SQLSUPPORT This property is represented as a long
integer, which determines the level of SQL support provided by the data provider Listing 20.1 demonstrates how
to retrieve the DBPROP_SQLSUPPORT property of the DataSource object to determine the level of SQL
support provided by the data provider Note that for brevity, the code in Listing 20.1 doesn't check the return valuefrom GetProperties Without testing the HRESULT, you have no way of knowing whether the properties wereactually returned In your production code, you will need to test for the return value
Listing 20.1 Determining the Level of SQL Support Provided by a Data Provider, Using the
8:
9: // Retrieve the Properties
10: pIDBProperties->GetProperties(1, &PropIDSet, &lNumProps,
&pPropSet);
11:
12: // Interpret the property value
13: if(pPropSet->rgProperties->vValue.lVal & DBPROPVAL_SQL_NONE) {14: cout << "SQL Commands are not supported\n";
Trang 1330: cout << "ANSI 92 Entry SQL Commands supported\n";
OLE DB also provides the GetPropertyInfo and GetCreationProperties
methods to retrieve additional information about the properties that each object makes
available
Setting Properties
To establish a connection to the DataSource object by using the OLE DB ODBC provider, you used the
SetProperties method (refer to Day 18) to specify the required ODBC connection parameters The primarymethod that OLE DB objects use to specify property values is the SetProperties method The
SetProperties(ULONG cPropertySets, DBPROPSET rgPropertySets[]);
contains a collection of property values The rgPropertySets parameter is a DBPROPSET type, discussedearlier today To set the value of a property, you need to create the rgPropertySets array and call the
TIP
On return from the SetProperties method, check the status of each property to
determine whether it was set properly
Property status values are listed in Table 20.3 Table 20.4 lists the methods that each OLE DB object uses in order
to specify property values
Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com
Trang 14Table 20.4 The Methods Used by OLE DB Objects to Specify Property Values OLE DB Object Interface Method
Now that you understand the structures involved in specifying a property, you can specify a property value andcheck the status of the property set operation Listing 20.2 demonstrates how to use the
DBPROPSET_DBINIT group and is used to specify the number of seconds to wait while a connection to the datasource is established Note that for brevity, the code in Listing 20.2 doesn't check the return values In your
production code, you will need to test for the return values
Listing 20.2 How to Use the SETPROPERTIES Method to Set the DBPROP_INIT_TIMEOUT Property
1: // Obtain Access To The OLE DB - ODBC Provider
2: CoCreateInstance(CLSID_MSDASQL, NULL, CLSCTX_INPROC_SERVER,
3: IID_IDBInitialize, (void **) &pIDBInitialize); 4:
5: // Initialize the property values
23: // Remember to release pIDBInitialize and pIDBProperties
Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com
Trang 15A Review of OLE DB Object Properties
Table 20.5 lists all the properties that OLE DB objects support This table lists each property ID and its varianttype An asterisk (*) after a property name signifies that it is a read-only property
NOTE
Certain data providers might provide their own set of properties, so check the data provider
documentation for more information For example, the OLE DB ODBC data provider
supports its own set of properties These properties are part of two OLE DB ODBC
provider-specific groups: DBPROPSET_PROVDERDATASOURCEINFO and
DBPROPSET_PROVIDERROWSET
Table 20.5 The Properties Supported by OLE DB Objects
Column Object Properties
will automatically increment
of a column
description
has a fixed length
can contain NULL values
is part of the primary key
must be unique
DataSource Object Properties
source catalog
DataSource Object Properties (Information)
number of sessions; if 0, sessions are unlimited
can be aborted asynchronously
committed asynchronously
DataSource Object Properties (Information)
source can accept parameters passed by reference (aspointers)
Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com
Trang 16DBPROP_CATALOGLOCATION * A VT_I4 type property It returns
beginning or DBPROPVAL_CL_END if it's at the end
a data source uses for a catalog
catalog names are supported
column states
strings are handled when added to other characterstrings
the data source
source is read-only
the data provider
the data provider
model supported by the data provider
BY clause functions
can be performed across providers or catalogs
case of identifiers is significant
size of a key; if 0, there is no limit
DataSource Object Properties (Information)
length of a row; if 0, there is no limit
fields
number of tables that can be used in a SELECT
statement
source supports multiple parameter sets
data source can support multiple resultsets
Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com
Trang 17DBPROP_MULTIPLESTORAGEOBJECTS * A VT_BOOL type parameter If it's true, the data
source can open multiple objects at the same time
source can update row sets that contain multiple tables
values are handled when sorting
and OLE objects can be accessed through streaming orstorage objects
columns specified in an ORDER BY clause must bepart of the SELECT statement
parameters can be accessed
persistent DBID supported by a data source
to a prepared statement when it's aborted in atransaction
DataSource Object Properties (Information)
to a prepared statement when it's committed in atransaction
data source calls a procedure
executable filename of the provider
DB specification version supported by the provider
of the data provider
handled for quoted identifiers
can be made about conversions on the row sets of acommand
used by the data source for a schema
names can be used in commands
SQL supported by the data source
interfaces supported for row sets
Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com
Trang 18DBPROP_SUBQUERIES * A VT_I4 type parameter It specifies whether
subqueries are supported in commands
definition commands are supported in transactions
isolation levels supported by the data source
DataSource Object Properties (Information)
levels supported by transaction isolation
used by the data source for tables
the user attached to the data source
DataSource Object Properties (Initialization)
source can store password and user information in alocal cache
source requires the password to be sent in an encryptedform
the authentication service to be used
password must be masked before it's sent to the datasource
used for authentication (can be masked)
source must save authentication information
source is allowed to persist authentication information
username used to connect to the data source
data source to connect to
used if a prompt window must be displayed whenaccessing the data source
DataSource Object Properties (Initialization)
impersonation level used for remote procedure calls
identifier
Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com
Trang 19DBPROP_INIT_LOCATION A VT_BSTR type parameter It specifies the location
of the data source (that is, the name of the server)
share access level to the data source
prompt should be displayed for user/data sourceinformation if it's required when connecting to a datasource
procedure call connection level used
provider-specific connection parameters
time to wait for a connection to complete
Index Object Properties
is automatically updated whenever a change is made
uses clustering
fill factor for the index
to allocate for the index
values are treated in the sorting order
Index Object Properties
index can use NULL values
is based on the primary key
sorts bookmarks
is temporary
index mechanisms used by the data source
keys must be unique
RowSet Object Properties
set is preserved even after an aborted transaction
Simpo PDF Merge and Split Unregistered Version - http://www.simpopdf.com