

Introduction There are two
reasons why I've written this article. Firstly there are a number of
people who seem to be unaware of the consequences of specifying
adUseClient as a cursor location on the resultant cursor
type. Secondly, there are a number of people who suggest using
adUseClient in order to get an accurate .RecordCount from an ADO
Recordset object.
Whilst it is true that specifying adUseClient will return an
accurate recordcount (I've written the same here),
it appears that some people are missing the point as to why the
record count is accurate (because the cursor type becomes
adOpenStatic). As such they believe that there is no performance
penalty in using adUseClient (in that an adOpenForwardOnly cursor
can still be used).
In fact the reverse is true. Specifying adUseClient results in
two possible performance penalties. Firstly, the cursor type is set
to adOpenStatic, which is about twice as expensive as
adOpenForwardOnly. Secondly, in situtations where the DB and web
servers are physically separate, additional network traffic is
generated as the OLEDB Cursor Service located on the web server is
now managing the cursor, not the DBMS.
The following code can be used to connect to any database you
wish (adjust the connection string and table name in the Main
routine). It will output the requested and actual cursor types. The
code below was tested against an SQL Server 2000 database, and
returned adOpenStatic as the actual cursor type for every requested
cursor type.
<% Option Explicit Response.Buffer = True
Call Main()
Sub Main
Dim strConnect Dim objConn Dim strTableName Dim arrCursorTypes(3) Dim i
Dim objRS
strConnect = _
"Provider=SQLOLEDB.1;" &
_ "Integrated Security=SSPI;"
& _ "Persist Security
Info=False;" & _ "Initial
Catalog=Pubs;" & _ "Data
Source=Test;"
strTableName =
"Authors"
arrCursorTypes(0) =
adOpenForwardOnly arrCursorTypes(1) =
adOpenStatic arrCursorTypes(2) =
adOpenKeyset arrCursorTypes(3) =
adOpenDynamic
Call subDBConnOpen(objConn,
strConnect)
For i = 0 to
UBound(arrCursorTypes) Call subDBRSOpen(objRS, strTableName,
objConn,
arrCursorTypes(i)) Call subDBRSPropertiesWrite(objRS,
arrCursorTypes(i)) Call
subADOClose(objRS) Next
Call subADOClose(objConn)
End Sub
Sub subDBRSOpen(
_ ByRef objRS,
_ ByVal
strSource, _ ByRef objConn, _ ByVal varCursorType
_ )
Set objRS =
Server.CreateObject("ADODB.Recordset") objRS.CursorLocation
= adUseClient objRS.CursorType =
varCursorType objRS.Open strSource,
objConn,,adLockReadOnly, adCmdTable
End Sub
Sub subDBRSPropertiesWrite(
_ ByRef objRS,
_ ByVal
constRequestedCursorType
_ )
With
Response .Write("<p>Requested
Cursor Type: " &
fncGetPrettyCursorName(constRequestedCursorType) & "<br
/>" &
vbCrLf) .Write("Actual Cursor
Type: " & fncGetPrettyCursorName(objRS.CursorType) &
"</p>" & vbCrLf) End With
End
Sub
Function fncGetPrettyCursorName(
_ ByVal
constCursorType
_ )
Select Case
constCursorType Case
0 fncGetPrettyCursorName
= "adOpenForwardOnly" Case
1 fncGetPrettyCursorName
= "adOpenKeyset" Case
2 fncGetPrettyCursorName
= "adOpenDynamic" Case
3 fncGetPrettyCursorName
= "adOpenStatic" Case
Else fncGetPrettyCursorName
= "unknown cursor type!" End Select
End
Function
Sub subDBConnOpen(
_ ByRef objConn,
_ ByVal
strConnect _ )
Set objConn =
Server.CreateObject("ADODB.Connection") objConn.Open
strConnect
End Sub
Sub subADOClose(
_ ByRef
objToClose _ )
On Error Resume
Next objToClose.Close Set objToClose = Nothing
End
Sub %<
Back to Experiments
Listing |