Download ADO.DDD

Document related concepts

SQL wikipedia , lookup

Microsoft Access wikipedia , lookup

Oracle Database wikipedia , lookup

Concurrency control wikipedia , lookup

Entity–attribute–value model wikipedia , lookup

Database wikipedia , lookup

Functional Database Model wikipedia , lookup

Microsoft SQL Server wikipedia , lookup

PL/SQL wikipedia , lookup

Extensible Storage Engine wikipedia , lookup

Relational model wikipedia , lookup

Microsoft Jet Database Engine wikipedia , lookup

Clusterpoint wikipedia , lookup

Open Database Connectivity wikipedia , lookup

Database model wikipedia , lookup

Versant Object Database wikipedia , lookup

Transcript
Програмиране с АDO
Общ преглед на ADO обектния модел
книга Programming ADO
•
•
•
•
•
•
•
•
•
•
•
•
•
•
Connection Object
Open and Close methods
ADO has no collection object in its object model containing all of the Connection
objects.
BeginTrans, CommitTrans, and RollbackTrans
OpenSchema method lets you view much of the metadata about your database.
ADO's events on the Connection object will fire to signify the completion of the
asynchronous call.
To determine why your query failed, you can evaluate the Errors collection of the
Connection object.
Execute method to submit queries, including queries that generate Recordsets.
Execute method also allows you to issue an action query to modify data, manipulate
objects, or change database-specific settings on your database.
Command Object
help your work with queries that you'll execute repeatedly or queries that will check
the value of an output or return parameter on a call to a stored procedure.
You can submit the query to your database via the Command object's Execute
method.
you can issue an action query or a query that will return a Recordset.
ActiveCommand property on the Recordset object refers back to the Command
object used to open that Recordset.
Command object's Parameters collection work with parameterized queries and
stored procedures.
The ActiveConnection property on the Command object refers back to the
Connection object.
Recordset Object
* contains the results of your query.
* Each column is stored in a Field object in the Recordset's Fields collection.
* Open method of the Recordset object retrieve the results of a query either through the
Command object or directly through the Connection object.
* You can also generate a Recordset object by calling the Execute method on either the
Connection or Command object.
* The Recordset's ActiveConnection property refers to the Connection object that the
Recordset uses to communicate with the database.
* ActiveCommand property refers to the Command object that generated the Recordset
Dynamic Properties
• ADO's Properties collection contains Property objects that store
information about database system features.
• Different database systems expose different features. For example,
secure Microsoft Access databases require a system database file
(System.mdw). Microsoft SQL Server has options for using standard or
integrated security. ODBC API calls to take advantage of the unique
features of your particular database system. ADO Properties collection is
reserved for provider-specific features.
Obtaining a Recordset Without a Command Object
If you are not going to execute your query more than once, you
probably don't need to use a Command object:
strConn = "Provider=SQLOLEDB;Data Source=MyServer;" & _
"Initial Catalog=Northwind;" & _
"User ID=MyUserID;Password=MyPassword;“
Set cnNorthwind = New ADODB.Connection
cnNorthwind.Open strConn
strSQL = "SELECT * FROM Customers“
Set rsCustomers = New ADODB.Recordset
rsCustomers.Open strSQL, cnNorthwind
Connection Object: To Use or Not to Use
You might find that sometimes the only reason you use your Connection object
is to open Recordset objects.
•
strConn = "Provider=
SQLOLEDB;Data Source=MyServer;" & _
"Initial Catalog=Northwind;" & _
"User ID=MyUserID;Password=MyPassword;“
strSQL = "SELECT * FROM Customers“
Set rsCustomers = New ADODB.Recordset
rsCustomers.Open strSQL, strConn
ActiveConnection parameter
But proceed with caution! do you want the ActiveConnection property on each
of your Recordset objects to refer to the same Connection object?
Set rsCustomers = New ADODB.Recordset
rsCustomers.Open "SELECT * FROM Customers", strConn
Set rsOrders = New ADODB.Recordset
rsOrders.Open "SELECT * FROM Orders", strConn
• each Recordset object was opened using the same
connection string to communicate with the same
database;
• separate Connection object for each Recordset.
• Each Connection objects maintains its own physical
connection to the database.
1. explicitly create a Connection object and use it with both Recordset objects:
Set cnNorthwind = New ADODB.Connection
cnNorthwind.Open strConn
Set rsCustomers = New ADODB.Recordset
rsCustomers.Open "SELECT * FROM Customers", cnNorthwind
Set rsOrders = New ADODB.Recordset
rsOrders.Open "SELECT * FROM Orders", cnNorthwin
2. one Connection object,( without having to explicitly create one) using
ActiveConnection property on the initial Recordset object for both of them:
Set rsCustomers = New ADODB.Recordset
rsCustomers.Open "SELECT * FROM Customers", strConnSet
rsOrders = New ADODB.Recordset
rsOrders.Open "SELECT * FROM Orders", _
rsCustomers.ActiveConnection
•
•
This (p.2) will improve the performance of your queries &
control the number of actual connections you're making to the
database.
Obtaining a Recordset Without a Database
1. Microsoft developed the ODBC cursor library.
2. Microsoft Visual Basic 5 users could retrieve the results of a query into this
library and actually disconnect from the database and later reconnect to their
databases to update.
3. Remote Data Services (RDS), provided early versions of ADO with a cursor
engine. This technology allowed ADO to pass a recordset across process
boundaries.
4. Beginning with ADO 2.0, recordsets can be persisted to a file and reopened
later.
5. You can also create your own recordset by taking a Recordset object
variable and populating the Fields collection yourself.
Disconnecting a Recordset from a Connection
• disconnected recordsets - open a connection to your database,
retrieve data, close the connection, work with the data, and reopen
the connection when you want to communicate with your database
again.Use ActiveConnection property of the Recordset object :
'Open a connection to your database.
Set cnDatabase = New ADODB.Connection
cnDatabase.CursorLocation = adUseClient
cnDatabase.Open strConn, strUserID, strPassword
'Make the query and retrieve the results.
Set rsData = New ADODB.Recordset
rsData.Open strSQL, cnDatabase, adOpenStatic, _
adLockBatchOptimistic, adCmdTextSet
rsData.ActiveConnection = Nothing
'Close your connection.
cnDatabase.Close
'Modify your recordset.
'Reopen your connection.
cnDatabase.Open
'Point your recordset at your connection.
Set rsData.ActiveConnection = cnDatabase
'Submit the changes from the recordset to your database.
rsData.UpdateBatch
ActiveConnection = Nothing  ADO Cursor Engine to dissociate
the Recordset object from the Connection object.
• reconnect to the database  Open method of the Connection
object,
• associate the Recordset with the Connection object,
• submit the changes in the Recordset to the database by calling the
UpdateBatch .
Persistence Can Pay Off
ADO 2.0 introduced functionality that makes it possible to store database information on
the desktop without having a desktop database. ADO Recordset object has a Save
method
'Retrieve the results of your query and save them to a file. The path to the file
' and the filename are stored in the string strPathToOrdersFile.
Set cnDatabase = New ADODB.Connection
Set rsOrders = New ADODB.Recordset
rsOrders.Open strSQL, cnDatabase, adOpenStatic, _
adLockBatchOptimistic, adCmdText
rsOrders.Save strPathToOrdersFile
'Retrieve the contents of the file into a Recordset,
' modify the Recordset accordingly, and then save the changes back to a file.
rsOrders.Open strPathToOrdersFile, , , _
adLockBatchOptimistic, adCmdFile
rsOrders.AddNew
rsOrders.Update
rsOrders.Save strPathToOrdersFile
'Retrieve the contents of the file into a Recordset & submit the changes to your database.
rsOrders.Open strPathToOrdersFile, , , _
adLockBatchOptimistic, adCmdFile
Set rsOrders.ActiveConnection = cnDatabase
rsOrders.UpdateBatch
The ADO Connection Object
•
Prop. or Coll. Name
Attributes
Connection Object Properties and Collections
Data Type
Long
CommandTimeout
Long
ConnectionString
ConnectionTimeout
String
Long
CursorLocation
Long
DefaultDatabase
String
Errors
Collection of Error objects
IsolationLevel
Long
Mode
object
Properties
Long
Provider
State
Version
Collection of Property objects
String
Long
String
Description
Controls the behavior of the Connection object
after CommitTrans or RollbackTrans has been called
Sets the length of time that queries on this
connection can run before timing out
Specifies how to connect to your database
Sets the length of time that ADO will wait before
an attempt to connect to your db times out
Sets the default value for the location of the cursor
for Recordsets opened on this Connection object
When connecting to Microsoft SQL Server and
other database servers that expose multiple
databases, specifies which database to use
Each Error object contains information
about an error that occurred on the Connection object
Controls the level at which transactions for the
database are isolated
Sets the permissions for modification of the Connection
Stores information about provider-specific properties for
the Connection object
OLE DB provider name
Current state (open or closed) of the Connection object
Version of ADO
IsolationLevel Property
You can use the IsolationLevel property to control the isolation level of the
transactions on your Connection object. The property can be set to any one of the
IsolationLevelEnum values listed:
Constant
adXactUnspecified
IsolationLevelEnum Values
Value
Description
-1
Indicates that the provider is using an
isolation level that cannot be determined
adXactBrowse,
adXactReadUncommitted 256
adXactCursorStability,
adXactReadCommitted
4096
adXactRepeatableRead
65536
adXactIsolated,
adXactSerializable
1048576
Allows you to view changes pending in
another transaction Subject to nonrepeatable
reads and phantom rows
Default; ensures that your transaction does
not view any pending updates Subject to
nonrepeatable reads and phantom rows, but
immune to dirty reads
Ensures that your transaction does not view
any pending updates and that rows you read
are not modified by other transactions Subject
to phantom rows
Specifies complete isolation from other
transactions
ADO Connection Object Functions and Methods
Connection Object Functions and Methods Function or Method
Name
Description
BeginTrans
Cancel
Initiates a transaction
Cancels an asynchronous attempt to
connect to your database
Close
Closes the connection to your
database
CommitTrans
Commits the current transaction
Execute
Submits a query to your database
Open
Opens a connection to your database
OpenSchema
Retrieves schema information from your database
RollbackTrans
Rolls back the current transaction
Connection.Execute CommandText, RecordsAffected, Options
cnDatabase.Execute "DELETE FROM MyTable WHERE ID = 7“
By default, the Execute method on the Connection object returns a Recordset
object:
'Create a new Recordset.
Set rsResults = New ADODB.Recordset
'Set the Recordset to use a keyset cursor and optimistic locking.
'These settings make the Recordset updatable
.rsResults.CursorType = adOpenKeyset
rsResults.LockType = adLockOptimistic
'Call Connection.Execute and retrieve a new, nonupdatable Recordset object.
Set rsResults = cnDatabase.Execute(strSQL)
if you want to maintain any control over the Recordset object generated by
your query, use the Open method on the Recordset object rather than the
Execute method of the Connection object.
The best use of the Execute method is for action queries—queries that will not
return a recordset
Open Method
You use the Open method to connect to your database.
Connection.Open ConnectionString, UserID, Password, Options
OpenSchema Method
provide a list of tables and the names of the fields in each table. You might even want to
retrieve foreign key constraints to show relationships within the database. The OpenSchema
method returns a Recordset object to help you retrieve this type of information:
Set Recordset = Connection.OpenSchema QueryType, Criteria, SchemaID
The current documentation for adSchemaColumns lists four available restrictions:
TABLE_CATALOG, TABLE_SCHEMA, TABLE_NAME, and COLUMN_NAME.:
Dim rsSchema As ADODB.Recordset
Dim aRestrictions As Variant
aRestrictions = Array(Empty, Empty, "Customers", Empty)
Set rsSchema = cnDatabase.OpenSchema(adSchemaColumns, aRestrictions)
ADO Connection Object Events
The connection object raises the events listed in the following table.
Connection Object Events
Event Name
BeginTransComplete
CommitTransComplete
ConnectComplete
Disconnect
ExecuteComplete
InfoMessage
RollbackTransComplete
WillConnect
WillExecute
Description
Fires when the BeginTrans method completes
Fires when the CommitTrans method completes
Fires when the attempt to connect completes
Fires when the Close method completes
Fires when the Execute method completes
Returns informational error messages
Fires when the RollbackTrans method completes
Fires when the Open method on the Connection
object is called, prior to the attempt to connect to the
database
Fires prior to submitting a query to the Connection
object with the Execute method or when the Open
method is called on a Recordset associated with the
Connection object
Anatomy of a Connection String
•
The OLE DB Provider For ODBC Drivers
ADO communicates with your database by means of an OLE DB provider. ADO 2.0 and later ship with native
OLE DB providers for Access, SQL Server, and Oracle databases.
•
if you don't have a native OLE DB provider? As long as you have an ODBC driver that supports basic ODBC
functionality, you should still be able to use ADO. The OLE DB Provider For ODBC Drivers makes ODBC API
calls that ask the driver what functionality it supports.
•
The OLE DB Provider for Access Databases
"Provider=Microsoft.Jet.OLEDB.4.0;
Data Source=C:\Path\To\MyDatabase.MDB;“
The OLE DB Provider For SQL Server Databases
"Provider=SQLOLEDB;Data Source=MyServer;
Initial Catalog=MyDatabase;
User ID=MyUID;Password=MyPassword;“
•
The OLE DB Provider For Oracle Databases
communicate with Oracle's client components rather than directly with the Oracle database. In order to use
ADO with Oracle, you have to install the appropriate version of the Oracle client utilities (SQL*Net) and create
a database alias. Once you've done that, you can use a connection string such as this:
"Provider=MSDAORA;Data Source=MyDatabaseAlias;
User ID=MyUID;Password=MyPassword;"
Managing Your Transactions
BeginTrans, CommitTrans, and RollbackTrans Methods
On Error Resume Next
'Start the transaction.
cnDatabase.BeginTrans
strSQL = "UPDATE Savings SET BalDue = BalDue - 50 " & "WHERE AccountNumber = 123456789“
cnDatabase.Execute strSQL
If cnDatabase.Errors.Count > 0 Then
'An error occurred, cancel changes.
cnDatabase.RollbackTrans
Else
strSQL = "UPDATE Checking SET BalDue = BalDue + 50 " & _
“WHERE AccountNumber = 123456789"
cnDatabase.Execute strSQL
If cnDatabase.Errors.Count > 0 Then
'An error occurred, cancel all of the changes.
cnDatabase.RollbackTrans
Else
‘No errors occurred, commit all of the changes.
cnDatabase.CommitTrans
End If
End If
IsolationLevel Property
•
Definitions of Some Transactional Terms
•
dirty read
•
nonrepeatable read
•
phantom row
•
SQL Server supports all four isolation levels ( Read Committed - default). You can
set the ADO Connection object's IsolationLevel property to use any of the four SQL92 isolation levels.
SQL-92 Isolation Levels
Read Uncommitted
Read Committed
Repeatable Read
Serializable
When one transaction reads uncommitted changes
from another transaction.
When data read in transaction A is modified by
transaction B before transaction A completes.
When transaction A examines the results of a query
and then transaction B inserts a row that satisfies the criteria
for transaction A's query before transaction A completes.
This term comes from the fact that in this case, transaction A
could run the same query twice and see a new row appear
mysteriously (like a phantom) in the second set of results.
Dirty Read
Yes
No
No
No
Nonrep Read
Yes
Yes
No
No
Phant. Row
Yes
Yes
Yes
No
The ADO Recordset and Field Objects
ADO Recordset Object Properties and Collections
• Recordset Object Properties and Collections
Property or Coll. Name
ActiveCommand
ActiveConnection
CacheSize
CursorLocation
Data Type
Variant
String or Connection
Long
Long
CursorType
DataSource
CursorTypeEnum
Object
Fields
Collection of Field objects
Filter
LockType
Variant
LockTypeEnum
MaxRecords
PageCount
PageSize
RecordCount
Sort
Status
Long
Long
Long
Long
String
RecordStatusEnum
Description
Pointer to the Command object that created the
Recordset object
Connection object used to retrieve
the results of your query
number of records cached from the server (1)
the location of the cursor (either client-side or
server-side)
the type of cursor
Allows you to bind the Recordset to a data
source
Pointer to the collection of Field objects that
contain the results of your query
Allows you to filter your Recordset
Specifies how the contents of your Recordset
can be locked and updated
the maximum number of records to be returned
Returns the number of pages in your Recordset
number of records per page in your Recordset
Returns the number of records in the Recordset
Allows you to reorder the data in your Recordset
Returns the update status of the current record
Some Details about properties & collections
CursorType Property
CursorTypeEnum Values
Constant
Value
adOpenForwardOnly
0
adOpenStatic
3
adOpenKeyset
1
adOpenDynamic
2
Description
Default for server-side Recordsets; opens a
Recordset that supports scrolling forward only
Default and only possible value for client-side
Recordsets; supports scrolling forward and
backward; changes made by other users are
not visible
Supports scrolling forward and backward;
modifications and deletions by other users are
visible
Supports scrolling forward and backward;
modifications, deletions, and insertions made
by other users are visible
Fields Collection
In the following Visual Basic code, all lines are equivalent to each other,
referring to the Value property for the CustomerID field in the rsCustomers
Recordset object (assuming CustomerID is the first field in the Recordset):
rsCustomers.Fields("CustomerID").Value
rsCustomers.Fields(0).Value
rsCustomers(0).Value
rsCustomers("CustomerID").Value
rsCustomers.Fields("CustomerID")
rsCustomers.Fields(0)
rsCustomers(0)
rsCustomers("CustomerID")
Filter Property – which records in Recordset to view
you can set the property to a string or to a value in FilterGroupEnum
FilterGroupEnum Values
Constant
Value
Description
adFilterNone
0
Default; clears the current filter
adFilterPendingRecords 1
Displays only the records with
pending changes
adFilterAffectedRecords 2
Displays only the records affected
by the last call to Delete, Resync,
UpdateBatch, or CancelBatch
adFilterFetchedRecords 3
Displays only the records currently
stored in the cache
adFilterConflictingRecords 5
Displays only the records that failed
in the last batch update attempt ,
because a modification from another user
rsOrders.Filter = "CustomerID = 'ALFKI'"
strCriteria = "CompanyName = 'Trail''s Head Gourmet'“
rsCustomers.Filter = strCriteria
LockType Property
LockTypeEnum Values
Constant
adLockReadOnly
Value
1
Description
Default; the Recordset is readonly.
adLockPessimistic
2
ADO relies on the OLE DB
provider to ensure that your
update attempt will succeed.
Only 1 user/moment. Locked
for others.
adLockOptimistic
3
The data is not locked until one
call Update.
adLockBatchOptimistic 4
Modifications to your data are
cached until you call UpdateBatch.
Designed for client side Recordsets.
Works with server side, if OLE DB provider supports the functionality
(Access – not, SQL Server – yes)
ADO Recordset Object Methods
AddNew
Cancel
CancelUpdate
Adds a new record to your Recordset
Cancels an asynchronous query
Cancels pending changes on a record currently
being edited
Close
Closes the Recordset object, releasing its contents Delete
Deletes the current record from your Recordset
Find
Searches your Recordset for a records
GetRows
Returns data from your Recordset in a twodimensional Variant array
GetString
Returns data from your Recordset in a string
Move
Moves the position in Recordset
MoveFirst
Moves to the first record in your Recordset
MoveLast
Moves to the last record in your Recordset
MoveNext
Moves to the next record in your Recordset
MovePrevious
Moves to the previous record in your Recordset
NextRecordset
Retrieves results of the next query (RecordSet)in batch query
Open
Opens the Recordset
Requery
Reexecutes the query that generated the Recordset
Save
Writes the contents of the Recordset to a file
Seek
Searches the Recordset for a specified string
Update
Writes pending changes to the Recordset & DB unless you are
using batch update (LockType = adLockBatchOptimistic). In that case –
modifications only cashed
UpdateBatch
from RecordSet to DB
Examples:
rsCustomers.AddNew
rsCustomers.Fields("CustomerID").Value = "NewID“
rsCustomers.Fields("CompanyName") = "New Customer“
rsCustomers.Fields("Address").Value = "23 Highview St.“
rsCustomers.Fields("City") = "Westwood“
rsCustomers.Fields("State") = "MA“
rsCustomers.Fields("Zip") = "02090“
rsCustomers.Update
strCriteria = "Country = 'Germany'“
rsCustomers.Find strCriteria
Do While Not rsCustomers.EOF
rsCustomers.Find strCriteria, 1
Loop
strSQL = "SELECT * FROM Customers“
rsCustomers.Open strSQL, cnDatabase, adOpenForwardOnly
Do While Not rsCustomers.EOF
Debug.Print rsCustomers.Fields("CustomerID").Value
rsCustomers.MoveNext
Loop
Open Method
The Open method is the most powerful and versatile method of retrieving data
from your database. You can set the ActiveConnection, Source, LockType,
and CursorType properties on the Recordset prior to using the Open method,
or you can supply this data in its parameters, all of which are optional:
* Source
This parameter accepts a Variant. You can use the Source
parameter to specify the query string or Command object
you want to use. This parameter can also contain a table
name, a stored procedure call, a URL, a filename.
ActiveConnection This parameter accepts a Variant in the form of a
connection string or an open Connection object, just like the
ActiveConnection property.
CursorType
later …
LockType
Options
CommandTypeEnum value and/or a combination of
asynchronous ExecuteOptionEnum constants
rsCustomers.Open "Customers", cnNorthwind, _
adOpenStatic, adLockReadOnly, adCmdTable + adAsyncExecute
ADO Recordset Object Events
Event Name
EndOfRecordset
Description
Fires when you navigate beyond the last record of
data in your Recordset
FieldChangeComplete Fires after you've modified the value for a field
MoveComplete
Fires after the current position of the Recordset
changes
RecordChangeComplete Fires after you modify a record
RecordsetChangeComplete Fires after the Recordset object has changed
WillChangeField
Fires before the contents of a field change
WillChangeRecord
Fires before the contents of a record change
WillChangeRecordset
Fires before the Recordset object changes
WillMove
Fires before the current position in the Recordset
changes
ADO Fields Collection for Recordset
Like all collections, the Fields collection exposes a Count property and an Item
property (the default). With the Item property, you can return a particular Field by
name or index.
Method Name
Description
Append
Adds a new Field ( for Recordset) to the collection (without DB)
CancelUpdate
Cancels the pending changes for a record
Delete
Deletes a Field from the collection
Refresh
Refreshes the Fields collection
Resync
Resynchronizes the current record
Update
Submits the pending changes in a record
Append Method
You can use the Append method on the Fields collection to create your own
Recordset object without using a database. You can populate the Fields collection
with Field objects in this fashion and then call the Recordset.Open method to start
adding records to your Recordset. If you're not trying to communicate with a
database but would like to maintain your data in a Recordset object, this method
is for you. Its parameters are as follows:
Name
Type
DefinedSize
Attributes
FieldValue
ADO Field Object Properties
Property Name
Data Type
Description
ActualSize
Long
Returns the actual size of a field's value
Attributes
Long
Describes characteristics of the field
DataFormat
Object Can be used to format your data
DefinedSize
Long
Returns the defined size for a field
Name
String Contains the name of the field
NumericScale
Byte
Indicates the numeric scale for numeric data
OriginalValue
Variant Contains the original value for the field
Precision
Byte
Indicates the precision for numeric data
Properties
Collection of Property objects
Collection of dynamic
properties
Type
Byte
Returns the data type for the field
UnderlyingValue
Variant Indicates the most recently retrieved value
from the database for the field
Value
Variant Contains the current value for the field
ADO Field Object Methods
Method Name
Description
AppendChunk Appends data to a large string or binary field
GetChunk
Retrieves data from a large string or binary field
The ADO Command and Parameter Objects
This object's primary use is for repeated execution of a single query or
multiple similar queries. The Command object exposes a Parameters
collection, with each Parameter object corresponding to a parameter in a
query
ADO Command Object Properties and Collections
Prop. or Coll. Name Data Type Description
ActiveConnection String or ConnectionSpecifies the Connection object
used to communicate with your database
CommandText
String
Contains the query string or the name of the
table, view, or stored procedure you want to
execute
CommandTimeout Long
Controls the number of seconds the query
will run before timing out
Name
String
the name of the Command object
Parameters
Collection of Parameter objects Contains parameter
information for the query
CommandType Property
Constant
Value
Description
adCmdText
1
The query will not be modified by ADO.
adCmdTable
2
ADO will append "select * from " to the query.
adCmdStoredProc4
ADO will format the query as a call to a stored
procedure; for example: {? = CALL MyProc (?)}.
With cmdStoredProc
'Specify that the Command object will call a stored procedure.
.CommandType = adCmdStoredProc
'Specify the stored procedure name.
.CommandText = "MySP"
name
'CommandText property now contains "{ call MySP }".
'Populate the Parameters collection.
.Parameters.Append .CreateParameter("@RetVal", adInteger, _
In/out
adParamReturnValue)
.Parameters.Append .CreateParameter("@Param1", adInteger, _
adParamInput)
.Parameters.Append .CreateParameter("@Param2", adInteger, _
adParamInput)
'CommandText property now contains "{ ? = call MySP (?, ?) }".
End With
ADO Command Object Methods
Method Name
Description
Cancel
Cancels an asynchronous query
CreateParameter
Creates a Parameter object for the Command
object's Parameters collection
Execute
Executes your query
ADO Parameters Collection
Method Name
Description
Append
Appends a Parameter object to the Parameters
collection
Refresh
Refreshes the information for Parameter
object & collection, connected with current
command
ADO Parameter Object Properties and Collections
to enable you to reuse a query while changing a small piece of the query. For
example, execute that query multiple times, changing only the value of the
CustomerID each time the query is executed:
SELECT * FROM Customers WHERE CustomerID = ?
Prop.or Coll. Name
Data Type
Description
Direction
ParameterDirectionEnum Indicates which type of parameter
you're using—input, output,
input/output, or return
Name
String
Contains the name of the Parameter
object
Size
Long
Returns the defined size for a field
Type
DataTypeEnum
Returns the data type for a field
Value
Variant
the current value for a field
ADO Parameter Object Method
Method Name
Description
AppendChunk Adds chunks of string or binary data to the Parameter object
The ADO Record and Stream Objects
Which OLE DB Providers Support the ADO Record Object?
• OLE DB Provider For Internet Publishing
• Microsoft Internet Explorer 5 ships with an OLE DB provider designed to
communicate with web servers -IIS 5. There's a growing standard
among web servers called Web Distributed Authoring and Versioning
(WebDAV), which defines a method of interaction with the files
maintained by the web server. This standard set of interfaces allows web
development tools such as Microsoft FrontPage to post new or modified
files to your web site.
• The OLE DB Provider For Internet Publishing lets you use WebDAV to
communicate with your web site by using ADO.
• OLE DB Provider For Microsoft Exchange Server
• The Record and Stream objects are designed to make working with
"document" data stores (such as file systems and message stores). You
could use such a provider to communicate with your mail server by
using ADO to build e-mail applications like Microsoft Outlook.
ADO Record Object
OLE DB providers for traditional relational databases don't support
Record object
Hierarchical Data
File systems, for example, contain files and directories.
While a file might resemble a row in a table in a traditional relational database, a directory
resembles both a row in a table and a table.
Call a Record object's GetChildren method, and you'll receive a Recordset object that
contains the child data (the records) associated with that Record object.
• Nonrectangular Data
• Take data in a directory as an example. Files and subdirectories
have some of the same attributes, such as the name and the date
created, but they also expose unique attributes. For example, files
generally have an application associated with them, and directories
generally contain information about whether they're visible as a
network share. Because this structure of files and subdirectories
within a directory exposes different attributes, the attribute data is
considered nonrectangular.
• With Recordset object, you'd see only the common attributes
(columns of data) that are exposed by both the files and
subdirectories. Examining a file and a subdirectory as individual
Record objects will expose all the attributes of both structures
ADO Record Object Functions and Methods
Func or Method Name
Cancel
Close
CopyRecord
DeleteRecord
GetChildren
MoveRecord
Open
Description
Cancels an asynchronous action on the Record object
Closes an open Record object
Copies the Record object to another location
Deletes the Record object
Retrieves the child data associated with the Record object
Moves the Record object to another location
Opens an existing Record object or creates a new Record
object
ADO Recorset object Properties & collections
ActiveConnection
Fields
Mode
ParentURL
Properties
Source
specify permissions for modification
of Record object
parent of the Record object
collection of dynamic properties
ADO Stream Object
Use Stream object in conjunction with the Record object to access documentbased data.
Working with Document Data
While the Record object allows you to interact with the structure of documents,
the Stream object lets you access the contents of those documents.
Stream.Open Record, adModeReadWrite, adOpenStreamFromRecord
Stream.Position = 0
Stream.LoadFromFile strPathToFile
Stream.Flush
ADO Stream Object Functions and Methods
Func or Method Name
Description
Cancel
Cancels a pending asynchronous call to a Stream object
Close
Closes an open Stream object
Flush
Flushes the contents stored in the Stream object's buffer
LoadFromFile Loads the contents of a file into the stream
Open
Opens the Stream object
Read
Reads binary data from the stream
SaveToFile
Persist data
Write
Append data to the stream
Open Method
The Open method opens a Stream Object from a Record object or URL
Cursors
Forward-Only Cursors
The adOpenForwardOnly constant, a CursorTypeEnum type, corresponds
to this type of cursor. It is the default value for a Recordset object's
CursorType property when you use the default value (adUseServer) for the
Recordset object's CursorLocation property. ADO retrieves from the cursor
up to the number of records specified by the CacheSize property in a
Variant array, and then when you navigate beyond the data in the cache,
ADO retrieves the next set of records
Firehose Cursors
forward-only, read-only, and one record at a time.
No cursor like structure to store results.
Microsoft SQL Server is optimized for this type of query.
SQL Server can support only one active query on a connection. If you open
a firehose cursor and do not fetch all of the data, and then close that cursor,
you've tied up that connection.
OLE DB—the technology on which ADO is based— provider will simply
request another connection. See three separate connections to your SQL
Server database:
Set cnNorthwind = New ADODB.Connection
cnNorthwind.CursorLocation = adUseServer
cnNorthwind.Open strConn
Set rsCustomers = cnNorthwind.Execute("SELECT * FROM Customers")
Set rsOrders = cnNorthwind.Execute("SELECT * FROM Orders")
Set rsProducts = cnNorthwind.Execute("SELECT * FROM Products")
/Adding New ADODB.Recordset before rs.Open” SQLstring” for the
code above, results in constructing 3 separate static cursors /
Static Cursors
supports scrolling forward and backward. As the cursor name implies,
the data is static
Static cursors are traditionally defined as read-only
Keyset Cursors
Not only does a keyset cursor allow you to update data, but it also
lets you see changes made by other users.
You can open a keyset cursor as read-only or updatable.
Although you can see changes made by another user after you've opened your
keyset cursor, you can't see new records . The data in the keyset (remember
that this is the set of key values, not the cursor itself) is static.
Records deleted by other users will be removed from your keyset cursor the
next time you refresh the cache. With a deleted record in a keyset cursor you
will receive a run-time error if you're using the SQL Server ODBC driver but not
if you're using the OLE DB provider.
Dynamic Cursors
Can contain records that other users have added since initially
submitted the query
Client-Side Cursors
a static cursor.
•you will not see changes made to the database by other users
• OLEDB provider uses for results a firehose cursor
* However, a client-side recordset can be updatable
* this static cursor is maintained by the ADO Cursor Engine rather than by the
database system.
* ask ADO to update the database, by means of the Update or UpdateBatch
method
Database-Specific Cursor Considerations
Server-Side Cursors with SQL Server
1."cursors are evil,"
2. When you use a server-side cursor with the SQL Server OLE DB provider or
ODBC driver, you're using a cursor that's maintained by SQL Server itself.
3. It makes much more sense for your database system to do what it's designed to
do—store your data and process queries—rather than expend its resources
storing the results of your queries
4. if you're using server-side cursors in your application, you need a live
connection to the database
5. As you add more users, you add more connections to your database, and the
same instance of SQL Server needs to maintain the cursors for each user.
6. server-side cursors in your ADO and SQL Server application is a bad idea.
Server-Side Cursors with Access
1. Both the Access OLE DB provider and the Access ODBC driver support
server-side cursors.
2. The term "server" is a little misleading when it comes to server-side
cursors in Access.
3. With SQL Server, the database server maintains the cursor With Access,
the OLE DB provider and ODBC driver have to do a great deal more work
4. When using a client-side cursor with an Access database, you're
essentially moving data from the Access cursor engine to the ADO Cursor
Engine. The Jet 4.0 OLE DB Provider or ODBC driver processes the query,
generates the results, and then has to pass all of this data to the ADO Cursor
Engine one record at a time.
5. So should you simply not use client-side cursors with Access databases?
Not so fast. Some of ADO's functionality (persisting Recordsets to file, batch
updating, sorting Recordsets..) is available only with client-side Recordsets.
Plus, if you're using a keyset or dynamic cursor to store the results of your
Access queries, the OLE DB provider or ODBC driver still needs to examine
the database every time
Server-Side Cursors with Oracle
1. there are no OLE DB providers or ODBC drivers for Oracle that
support cursors outside stored procedures yet.
2. Microsoft ODBC driver for Oracle has always supported cursors.
You can get a keyset cursor with the Microsoft ODBC driver for
Oracle. How is this possible?The Microsoft ODBC driver for Oracle
actually implements the cursor in a way that is somewhat similar to
how the Access OLE DB provider and ODBC driver implement
cursors. For a keyset cursor, the Microsoft ODBC driver for Oracle
requests keyset information for the records that satisfy the query's
criteria
3. less stress on the database server. The data in the cursor is
cached in the Microsoft ODBC driver for Oracle, and the Oracle
server does what it does best—it maintains data and processes
queries.
Updating Your Database
1. Action Queries
UPDATE Customers SET BalanceDue = 100 WHERE CustomerID = 7
It's easy to execute action queries using the ADO object model
(Execute method in Connection or Command objects):
Dim cnDatabase As ADODB.Connection
strSQL = "UPDATE Customers SET BalanceDue =100 WHERE CustomerID=7“
cnDatabase.Execute strSQL, intRowsAffected, _
adCmdExecuteNoRecords + adCmdText
MsgBox intRowsAffected & " record(s) affected.“
pro&cons: flexibility, universal support, easy multi-user support, great deal of code
• 2. Stored Procedures
• Many database administrators (DBAs) allow users to
perform updates only through stored procedures
because of the level of control they offer.
•SQL Server allows you to pass query results back from the stored procedure.
Oracle doesn't. However, the Microsoft ODBC driver for Oracle and the OLE DB Provider For Oracle can
retrieve an array from an Oracle stored procedure and transform that data into a structure that ADO will
use to create a Recordset object.
* Stored procedures are faster than action queries.
* use stored procedures to isolate business rules from your application.
* As a general rule, think of your stored procedure as a COM component.
* don’t move all your logic into stored procedures: hard migration in DB systems
example of the ADO code required to call a stored procedure in SQL Server:
strSQL = "CALL SetBalanceDue('ALFKI', 150.00)“
cnDatabase.Execute strSQL, , adCmdText + adExecuteNoRecords
And here's the SQL Server stored procedure that was called from the ADO code:
CREATE PROCEDURE SetBalanceDue
(@CustomerID varchar(5), @BalanceDue money) AS
UPDATE Customers SET BalanceDue = @BalanceDue
WHERE CustomerID = @CustomerID
if two users retrieve the same customer's balance due, each user's update will succeed. This
isn't a desirable scenario. The following is a better choice:
CREATE PROCEDURE SetBalanceDue
(@CustomerID varchar(5), @Delta money) AS
UPDATE Customers SET BalanceDue = BalanceDue + @Delta
WHERE CustomerID = @CustomerID
pros&cons: flexibility, faster than action queries, security, modification outside the
application, //specific to server, another prog. language
3. Using Updatable Recordsets
Used properly, updatable Recordsets can save you more time than
anything sold in an infomercial.
strSQL = "SELECT * FROM Customers“
Set rsCustomers = New ADODB.Recordset
rsCustomers.Open strSQL, cnDatabase, adOpenKeyset, _
adLockOptimistic, adCmdText
rsCustomers("BalanceDue").Value = rsCustomers("BalanceDue").Value + 50
rsCustomers.Update
• Updatable Server-Side Recordsets
•
•
•
•
When you modify the Value property of the various Field objects in your Recordset and
then call the Recordset's Update method, ADO passes that information to the server-side
cursor through the OLE DB provider or ODBC driver. But who updates the database?
Whoever manages the cursor.
SQL Server actually manages the cursor. SQL Server also updates data in your database
as you modify the contents of the cursor.
Access OLE DB provider and ODBC driver manage the cursor & directly communicate with
database.
MS ODBC driver for Oracle manage the cursor.(Someday OLE DB provider will exist to do
the same) After changes in cursor, ODBC driver tells the Oracle DB server to make
modifications in the DB.
disadvantages of updating your database by using server-side Recordsets:
1. Server-side Recordsets require a live connection to your database.
2. Server-side Recordsets sometimes scale poorly in multiuser situations.
3. Because server-side Recordsets rely on the database system, the OLE DB provider,
or the ODBC driver to actually update the database, you might need to develop code
that is specific to the type of database you're using. For example, Microsoft Access and
SQL Server do not handle optimistic updates from live cursors the same way.
•
Updatable Client-Side Recordsets
•
•
Functionality between action queries & server side Recordsets.
They behave the same way as server-side Recordsets. However, instead of communicating with a
cursor that’s maintained by the database, OLEDB provider or ODBC driver, ADO retrieves the
results of your query and stores that data in its own Cursor Engine.
The data in your Recordset is static
The ADO Cursor Engine examines the changes you make to the Recordset and translates those
changes into action queries. Cursor Engine determines whether the action query successfully
updated the data in your database.
•
•
There's only one drawback to using client-side Recordsets . By allowing the
ADO Cursor Engine to maintain the results of your queries and update your
database, you still give up some control.
Comparison of ADO.NET and ADO
• In-memory Representations of Data
• In ADO, the in-memory representation of data is the recordset. In
ADO.NET, it is the dataset. There are important differences between
them.
• Number of Tables
• A recordset looks like a single table. If a recordset is to contain data
from multiple database tables, it must use a JOIN query, which
assembles the data from the various database tables into a single
result table.
• In contrast, a dataset is a collection of one or more tables. The tables
within a dataset are called data tables; specifically, they are DataTable
objects. If a dataset contains data from multiple database tables, it will
typically contain multiple DataTable objects.
• A dataset usually also contains relationships. A relationship within a
dataset is analogous to a foreign-key relationship in a database
Data Navigation and Cursors
In ADO you scan sequentially through the rows of the recordset using the ADO
MoveNext method. In ADO.NET, rows are represented as collections, so you can
loop through a table as you would through any collection, or access particular
rows via ordinal or primary key index. DataRelation objects maintain information
about master and detail records and provide a method that allows you to get
records related to the one you are working with.
A cursor is a database element that controls record navigation, the ability to
update data, and the visibility of changes made to the database by other users.
ADO.NET does not have an inherent cursor object, but instead includes data
classes that provide the functionality of a traditional cursor. For example, the
functionality of a forward-only, read-only cursor is available in the ADO.NET
DataReader object.
Minimized Open Connections
In ADO.NET you open connections only long enough to perform a database
operation, such as a Select or Update. You can read rows into a dataset and then
work with them without staying connected to the data source. In ADO the
recordset can provide disconnected access, but ADO is designed primarily for
connected access.
There is one significant difference between disconnected processing in ADO and
ADO.NET. In ADO you communicate with the database by making calls to an OLE
DB provider. In ADO.NET you communicate with the database through a data
adapter (an OleDbDataAdapter or SqlDataAdapter object),
Sharing Data Between Applications
To transmit an ADO disconnected recordset from one component to another, you
use COM marshalling. To transmit data in ADO.NET, you use a dataset, which can
transmit an XML stream.
The transmission of XML files offers the following advantages over COM
marshalling:
Richer data types
COM marshalling provides a limited set of data types — those defined by the COM
standard. Because the transmission of datasets in ADO.NET is based on an XML
format, there is no restriction on data types.
Performance
Transmitting a large ADO recordset or a large ADO.NET dataset can consume
network resources. ADO.NET offers performance advantage, in that ADO.NET
does not require data-type conversions. ADO, which requires COM marshalling to
transmit records sets among components, does require that ADO data types be
converted to COM data types.
Penetrating Firewalls
A firewall can interfere with two components trying to transmit disconnected ADO
recordsets. Remember, firewalls are typically configured to allow HTML text to
pass, but to prevent system-level requests (such as COM marshalling) from
passing.
Because components exchange ADO.NET datasets using XML, firewalls can allow
datasets to pass.