我正在尝试使用一些旧的VB6代码来使用SQL Server Compact。
我可以连接,打开数据库,一切似乎都很好。我可以运行插入选择命令。
但是ADODB.Recordset RecordCount属性总是返回-1,即使我可以访问Fields并查看数据。更改CursorLocation = adUseClient会在执行SQL时产生问题(多步操作生成错误)。
Option Explicit
Private Const mSqlProvider As String = "Provider=Microsoft.SQLSERVER.CE.OLEDB.3.5;"
Private Const mSqlHost As String = "Data Source=C:\Database.sdf;"
Private mCmd As ADODB.Command ' For executing SQL
Private mDbConnection As ADODB.Connection
Private Sub Command1_Click()
Dim rs As ADODB.Recordset
Set rs = New ADODB.Recordset
Dim DbConnectionString As String
DbConnectionString = mSqlProvider & _
mSqlHost
Set mDbConnection = New ADODB.Connection
mDbConnection.CursorLocation = adUseServer
Call mDbConnection.Open(DbConnectionString)
If mDbConnection.State = adStateOpen Then
Debug.Print (" Database is open")
' Initialise the command object
Set mCmd = New ADODB.Command
mCmd.ActiveConnection = mDbConnection
mCmd.CommandText = "select * from myTestTable"
mCmd.CommandType = adCmdText
Set rs = mCmd.Execute
Debug.Print rs.RecordCount ' Always returns -1 !!
Debug.Print rs.Fields(0) ' returns correct data for first row, first col
Debug.Print rs.Fields(1) ' returns correct data for first row, 2nd col
Debug.Print rs.Fields(2) ' returns correct data for first row, 3rd col
End If
End Sub
任何建议都会被感激地接受。
答案 0 :(得分:5)
实际上CursorLocation
在这种情况下起着重要作用。使用rs.CursorLocation = adUseClient
设置光标位置并尝试。
Set rs = New ADODB.Recordset
rs.CursorLocation = adUseClient
Dim DbConnectionString As String
DbConnectionString = mSqlProvider & _
mSqlHost
Set mDbConnection = New ADODB.Connection
mDbConnection.CursorLocation = adUseServer
Call mDbConnection.Open(DbConnectionString)
If mDbConnection.State = adStateOpen Then
Debug.Print (" Database is open")
' Initialise the command object
Set mCmd = New ADODB.Command
mCmd.ActiveConnection = mDbConnection
mCmd.CommandText = "select * from myTestTable"
mCmd.CommandType = adCmdText
Set rs = mCmd.Execute
Debug.Print rs.RecordCount ' This should now return the right value.
Debug.Print rs.Fields(0) ' returns correct data for first row, first col
Debug.Print rs.Fields(1) ' returns correct data for first row, 2nd col
Debug.Print rs.Fields(2) ' returns correct data for first row, 3rd col
End If
End Sub
答案 1 :(得分:3)
这是用于访问数据的游标类型的结果,这篇文章涵盖了问题和可能的修复。
http://www.devx.com/tips/Tip/14143
修改强>
我为没有更加关注您处理Compact的事实而道歉。使用Compact时,情况类似于我引用的情况,因为它默认使用仅向前游标(不支持行计数),但是有两种其他游标类型可用,如下面的链接所示。
答案 2 :(得分:2)
检查记录集属性
以下是com.status.live代码
返回的RecordCount值的结果+------------------+-------------------+-------------+---------------+--------------+
| CursorTypeEnum|adOpenForwardOnly=0|dOpenKeyset=1|adOpenDynamic=2|adOpenStatic=3|
|CursorLocationEnum| |
+------------------+-------------------+-------------+---------------+--------------+
|adUseServer = 2 | X | O | X | O |
|adUseClient = 3 | O | O | O | O |
+------------------+-------------------+-------------+---------------+--------------+
答案 3 :(得分:2)
以下是我使用
的解决方案Dim recordnumber As Long
Dim SalRSrec As New ADODB.Recordset
Set SalRSrec = Nothing
SalRSrec.Open ("SELECT count(*) from SALARY where EMPID= '" & cmb_empid & "' ;"), Dbase, adOpenKeyset, adLockOptimistic
recordnumber = SalRSrec.GetString
MsgBox recordnumber
答案 4 :(得分:1)
很久以前,在使用VB6 / ADO的内存中,.RecordCount字段在您移动到记录集的末尾之前不会返回有意义的数据。
rs.MoveLast
rs.MoveFirst
Debug.Print rs.RecordCount
虽然有了这个,你需要确保你有适当的光标类型(即,不仅仅是向前)。
我能想到的唯一其他解决方案是单独执行SELECT COUNT(*)FROM myTestTable等,但这会导致该调用与实际返回行之间数据发生变化的问题。
答案 5 :(得分:1)
使用Compact,默认光标属性为adOpenForwardOnly,以提高性能。因此,RecordCount返回为“-1”,这意味着它不可用,而不是空白。这是设计原因,因为动态游标中的记录数可以更改并导致在客户端服务器之间来回ping以保持准确性。但是,如果记录计数至关重要,请尝试将其设置为使用adOpenKeyset或adOpenStatic与服务器端游标。
答案 6 :(得分:1)
你可以尝试这样的事情......
Set rs = mCmd.Execute
rs.MoveFirst
Do Until rs.EOF = true
Debug.Print rs.RecordCount ' Always returns -1 !!
Debug.Print rs.Fields(0) ' returns correct data for first row, first col
Debug.Print rs.Fields(1) ' returns correct data for first row, 2nd col
Debug.Print rs.Fields(2) ' returns correct data for first row, 3rd col
counter = counter + 1
rs.MoveNext
Loop
答案 7 :(得分:0)
将Set rs = mCmd.Execute
替换为:
set rs = new ADODB.Recordset
rs.Open "select * from myTestTable", mDBConnection, adOpenDynamic, adLockOptimistic
adOpenDynamic
将允许向前/向后阅读以获取您的记录数。
答案 8 :(得分:0)
下面的代码可能对您有帮助,
set conn = CreateObject("ADODB.Connection")
conn.open "<connection string>"
set rs = CreateObject("ADODB.Recordset")
sql = "SELECT columns FROM table WHERE [...]"
rs.open sql,conn,1,1
if not rs.eof then
nr = rs.recordcount
response.write "There were " & nr & " matches."
' ... process real results here ...
else
response.write "No matches."
end if
rs.close: set rs = nothing
conn.close: set conn = nothing
答案 9 :(得分:0)
如果仍然返回-1
,请尝试使用以下代码Set Conn = createobject("ADODB.connection")
Set Rs = createobject("ADODB.recordset")
Conn.Open "DSN=DSN_QTP"
'Rs.Open "Select * From orders",Conn,adOpenDynamic,adLockBatchOptimistic
Rs.Open "Select * from [QTP-Table]",Conn,1 'Use either 1 or 3
'I tried using adopendynamic but it still returned -1. Using 1 it gave me correct count. 'Though I am using this code in QTP (Vbscript) same should work for VB6 also.
msgbox Rs.RecordCount
答案 10 :(得分:0)
Set cn = CreateObject("ADODB.Connection")
strVerb = "Provider=Microsoft.ACE.OLEDB.12.0;" & _
"Data Source=C:\test.accdb"
tab1 = "tabelle1"
strSQL = "SELECT Count(*) FROM " & tab1
Debug.Print strSQL
cn.Open strVerb
Set rs = cn.Execute(strSQL)
Debug.Print rs.Fields(0)
rs.Close
Set rs = Nothing
cn.Close
Set cn = Nothing
答案 11 :(得分:-1)
以下代码完全返回recortcount ...
Public Sub test()
Dim cn As New ADODB.Connection()
Dim sPath As String = Application.ExecutablePath
sPath = System.IO.Path.GetDirectoryName(sPath)
If sPath.EndsWith("\bin") Then
sPath = sPath.Substring(0, Len(sPath) - 4)
End If
Dim DbConnectionString As String
DbConnectionString = "provider=microsoft.jet.oledb.4.0;data source=" & sPath & "\students.mdb"
cn.ConnectionString = DbConnectionString
cn.Open()
Dim rs As New ADODB.Recordset()
rs.CursorLocation = ADODB.CursorLocationEnum.adUseClient
rs.CursorType = ADODB.CursorTypeEnum.adOpenStatic
rs.LockType = ADODB.LockTypeEnum.adLockBatchOptimistic
rs.Open("select * from students", cn)
MsgBox(rs.RecordCount)
rs.ActiveConnection = Nothing
cn.Close()
End Sub