CÓMO: Obtener el número de registros de un conjunto de registros de SQL Server CE


Resumen


Un planteamiento común, que es fuente de confusión en la programación de acceso a datos, es "Cómo obtener el número de registros".


Si abre un cursor de sólo avance en una tabla de SQL Server CE e intenta obtener el número de registros mediante el código siguiente, ADOCE devuelve -1 como número de registros:
rs.Open "SELECT * FROM mytable", cn, adOpenForwardOnly,
adLockReadOnly

Más información


Este comportamiento es una característica del diseño de la aplicación. Para que sea rápido, se disminuye la funcionalidad del cursor de sólo avance. A continuación se muestran algunos puntos importantes acerca de cómo obtener el número de registros:
  • La capacidad de obtener el número de registros depende del tipo de cursor. Algunos cursores resultan muy "económicos" porque son rápidos o utilizan poca memoria. Otros cursores son más lentos o utilizan más memoria, pero también proporcionan mayor funcionalidad, como la capacidad desplazarse hacia atrás u obtener el número de registros.
  • Un cursor de avance del resultado de la consulta en SQL Server CE no admite la obtención del número de registros. No contabiliza previamente cuántas filas se devolverán de la consulta. ADO devuelve -1 porque no puede alcanzar la interfaz que se utiliza para obtener el número de registros.
  • Los cursores de consulta desplazables son el único tipo de cursor que puede devolver el número exacto de registros. Estos cursores son más caros (en lo referente a la memoria, principalmente). Obtener el número de registros puede resultar una operación cara.
  • Dependiendo del escenario, puede realizar una operación " select count(*) from table.. " para obtener un número de registros antes de comenzar la búsqueda.

Cursores de sólo avance

Los cursores de avance de SQL Server CE no pueden determinar cuántos registros se van a devolver. Para proporcionar el cursor más rápido y el que utilice menos memoria, el procesador de consultas devuelve las filas al tiempo que las va determinando. No existe ningún paso de almacenamiento en búfer en el que se determine el número de filas.


Los cursores de consulta desplazables de SQL Server CE, por otro lado, almacenan las filas en búfer cuando éstas se obtienen. Si el usuario solicita un recuento de filas, las filas se almacenan en el búfer para que puedan contarse. No obstante, dado que puede desplazarse en sentido contrario por el conjunto de resultados, es posible volver a leer los valores de las filas una vez que se han almacenado en el búfer para el recuento.


El código siguiente muestra cómo utilizar cursores de tabla base, de sólo avance y desplazables para abrir conjuntos de registros mediante ADOCE y eVB. Los cursores desplazables son los únicos que proporcionan un número exacto de registros:
Dim cn As ADOCE.Connection
Dim rs1 As ADOCE.Recordset
Dim rs2 As ADOCE.Recordset
Dim rs3 As ADOCE.Recordset
Dim catalog

Private Sub Form_Load()

Dim str1 As String
Dim str2 As String
Dim str3 As String
Set cn = CreateObject("ADOCE.Connection.3.1")
Const strConnect = "Provider=microsoft.sqlserver.oledb.ce.1.0;Data Source=\ssce.sdf"


cn.Open strConnect

cn.Execute "Create table mytable (col1 int NOT NULL)"
cn.Execute "CREATE UNIQUE INDEX idx1 ON mytable(col1)"
cn.Execute "insert mytable values (70)"
cn.Execute "insert mytable values (71)"

' For Base table cursor, just supply table name as source, DO NOT WRITE A SELECT * statement.
' Should use adOpenDynamic and adLockOptimistic with adCmdTableDirect flag.

Set rs1 = CreateObject("ADOCE.Recordset.3.1")
rs1.Open "mytable", cn, adOpenDynamic, adLockOptimistic, adCmdTableDirect

str1 = rs1.RecordCount
rs1.Close
MsgBox "Record count: " & str1

' Forward-only cursor does not support record count.
' Forward-only cursors should use adOpenForwardOnly and adLockOptimistic.
' The adCmdTableDirect flag should not be used.

Set rs2 = CreateObject("ADOCE.Recordset.3.1")
rs2.Open "Select * from mytable", cn, adOpenForwardOnly, adLockOptimistic
str2 = rs2.RecordCount
rs2.Close
MsgBox "Record count: " & str2

' Scrollable cursors can use either adOpenStatic or adOpenKeyset.
' These cursors should use adLockReadOnly and not specify the adCmdTableDirect flag.
Set rs3 = CreateObject("ADOCE.Recordset.3.1")
rs3.Open "Select * from mytable", cn, adOpenStatic, adLockReadOnly
str3 = rs3.RecordCount
rs3.Close
MsgBox "Record count: " & str3

cn.Close<BR/>
Set rs1 = Nothing
Set rs2 = Nothing
Set rs3 = Nothing
Set cn = Nothing

End Sub