web-dev-qa-db-ja.com

VB6 ADODB.RecordsetRecordCountプロパティは常に-1を返します

SQL ServerCompactで動作する古いVB6コードを取得しようとしています。

接続してデータベースを開くことができますが、すべて問題ないようです。動作する挿入選択コマンドを実行できます。

ただし、フィールドにアクセスしてデータを表示できる場合でも、ADODB.RecordsetRecordCountプロパティは常に-1を返します。 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

どんなアドバイスでもありがたく受け入れられます。

10
Belliez

実際、この場合、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
5
Kangkan

これは、データへのアクセスに使用されるカーソルの種類の結果です。この投稿では、問題と可能な修正について説明します。

http://www.devx.com/tips/Tip/1414

[〜#〜]編集[〜#〜]

あなたがコンパクトを扱っていたという事実にもっと注意を払わなかったことをお詫びします。 Compactの場合、デフォルトで順方向のみのカーソル(行数をサポートしない)を使用するため、状況は私が参照した状況と似ていますが、以下のリンクに記載されているように、他に2つのカーソルタイプを使用できます。

http://support.Microsoft.com/kb/272067

3
cmsjr

Recordsetプロパティを確認する

以下は、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      |
+------------------+-------------------+-------------+---------------+--------------+
2
YHkim

これが私が使ったあなたのための解決策です

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
2
Syagin Cdit

ずっと前にVB6/ADOを操作していたメモリから、レコードセットの最後に移動するまで、.RecordCountフィールドは意味のあるデータを返しません。

rs.MoveLast
rs.MoveFirst
Debug.Print rs.RecordCount

ただし、これを使用する場合は、適切なカーソルタイプがあることを確認する必要があります(つまり、前方だけではありません)。

私が考えることができる他の唯一の解決策は、myTestTableなどから個別のSELECT COUNT(*)を実行することですが、これには、その呼び出しと実際に行を返す呼び出しの間でデータが変更されるという問題があります。

1
Gareth Wilson

それでも-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
1
Shailendra Sah

あなたはこのようなことを試みるかもしれません。

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
1
Kentot

Compactでは、パフォーマンスを向上させるために、デフォルトのカーソル属性はadOpenForwardOnlyです。そのため、RecordCountは「-1」として返されます。これは、空白ではなく、使用できないことを意味します。これは仕様によるものです。動的カーソルのレコード数が変更され、クライアントサーバー間でpingが実行されて、精度が維持される可能性があるためです。ただし、レコード数が重要な場合は、サーバー側カーソルでadOpenKeysetまたはadOpenStaticを使用するように設定してみてください。

1
jasonk

以下のコードが役立つかもしれません、

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 
0
Ashfak Balooch

Set rs = mCmd.Executeを次のように置き換えます。

set rs = new ADODB.Recordset
rs.Open "select * from myTestTable", mDBConnection, adOpenDynamic, adLockOptimistic

adOpenDynamicを使用すると、順方向/逆方向のリードスルーでレコード数を取得できます。

0
C-Pound Guru