Свойство VB6 ADODB.Recordset RecordCount всегда возвращается-1

Я пытаюсь заставить некоторый старый код VB6 работать с Компактным SQL Server.

Я могу соединить, открыть базу данных, и все кажется хорошо. Я могу работать, вставляют избранные команды, которые работают.

Однако свойство ADODB.Recordset RecordCount всегда возвращается-1 даже при том, что я могу получить доступ к Полям и видеть данные. При изменении CursorLocation = adUseClient вызывает проблему, когда executung 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

Любой совет был бы с благодарностью принят.

9
задан SysDragon 11 March 2015 в 13:58
поделиться

6 ответов

Замените Set rs = mCmd.Execute на:

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

adOpenDynamic разрешит переход вперед / назад прочтите, чтобы узнать количество записей.

0
ответ дан 4 December 2019 в 13:47
поделиться

На самом деле 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
ответ дан 4 December 2019 в 13:47
поделиться

Это результат типа курсора, используемого для доступа к данным, в этом сообщении описывается проблема и возможные исправления.

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

РЕДАКТИРОВАТЬ

Прошу прощения за то, что не стал более внимательным к тому факту, что вы имели дело с Compact. С Compact ситуация аналогична той, на которую я ссылался, поскольку он по умолчанию использует курсоры только вперед (которые не поддерживают счетчик строк), но есть два других типа курсоров, доступных, как описано в приведенной ниже ссылке.

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

3
ответ дан 4 December 2019 в 13:47
поделиться

В Compact атрибутом курсора по умолчанию является adOpenForwardOnly для повышения производительности. В этом случае RecordCount возвращается как "-1", что означает, что он недоступен, а не пуст. Это сделано специально, потому что количество записей в динамическом курсоре может измениться и привести к необходимости пинговать туда-сюда между сервером и клиентом для поддержания точности. Однако, если количество записей очень важно, попробуйте настроить его на использование adOpenKeyset или adOpenStatic с курсором на стороне сервера.

1
ответ дан 4 December 2019 в 13:47
поделиться

Из памяти при работе с VB6 / ADO давным-давно поле .RecordCount не возвращает значимые данные, пока вы не переместитесь в конец набора записей.

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

Хотя при этом вам необходимо убедиться, что у вас есть соответствующий тип курсора (т.е. не только вперед).

Единственное другое решение, которое я могу придумать, - это выполнить отдельный SELECT COUNT (*) FROM myTestTable и т. Д., Но у этого есть проблемы с изменением данных между этим вызовом и тем, который фактически возвращает строки.

1
ответ дан 4 December 2019 в 13:47
поделиться

Этот следующий код точно возвращает счетчик пересчета ...

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
-1
ответ дан 4 December 2019 в 13:47
поделиться
Другие вопросы по тегам:

Похожие вопросы: