MS Access 2019 - SQL Server 2017 - набор записей не может быть обновлен - PullRequest
2 голосов
/ 04 октября 2019

Я создал таблицу в базе данных SQL Server 2017. Затем я создал форму в MS Access 2019, которая использует объект ADO в качестве «источника записи». На форме есть текстовое поле со свойством controlsource = Field. Затем, когда я открываю форму, все работает должным образом (содержимое поля отображается в текстовом поле, я могу перемещать курсор назад и вперед и т. Д.), За исключением одного: невозможно изменять, добавлять или удалять записи.

Создание таблицы на сервере SQL (используйте SSMS):

CREATE TABLE Table1 (Field INT PRIMARY KEY)
INSERT INTO Table1 (Field) VALUES (15)
INSERT INTO Table1 (Field) VALUES (12)

В модуле доступа:

#Const EarlyBinding = -1

#If EarlyBinding Then
  ' Irrelevant in this context
#Else
  Global Const adUseClient As Long = 3
  Global Const adLockBatchOptimistic As Long = 4
  Global Const adOpenDynamic As Long = 2
#End If

В коде VBA формы доступа:

Private Sub Form_Load()
  Dim sqldb as Object, adocom as Object, rs As Object
  Set sqldb = CreateObject("ADODB.Connection")
  Set adocom = CreateObject("ADODB.Command")
  Set rs = CreateObject("ADODB.Recordset")
  SQLDB.Open "Driver={SQL Server Native Client 11.0};Server=SQL;Database=Test;Trusted_Connection=yes;"
  SQLDB.CursorLocation = adUseClient
  rs.LockType = adLockBatchOptimistic
  rs.CursorType = adOpenDynamic    
  adocom.CommandText = "SELECT Field FROM Table1"
  set rs = adcom.execute
  set Me.Recordset=rs
end sub

Эта проблема «сводится» к гораздо более сложному коду. Запрос, который я передаю SQL Server, выполняется в течение нескольких минут, если я использую DAO, поэтому большое значение имеет разрешение SQL Server выполнить запрос (занимает <1 сек). </p>

Так что же мне нужно сделать, чтобы можно было добавлять, изменять или удалять записи?

Команды DML, такие как

adocom.execute ”UPDATE Table1 SET Field=25 WHERE Field=15” 

, работают.

Но хорошо, дело в том, что я хочу, чтобы форма доступа действовала точно так же с набором записей ADO, подключенным к SQL Server, как это было бы, если бы набор записей обрабатывался объектом DAO, подключенным к бэкэнду .accdb-файл. Так что это набор записей, который должен быть обновляемым. Свойство rs.recordcount равно -1, что указывает на невозможность обновления набора записей. Если это свойство является чем-то еще, кроме -1 после строки adocom.execute, то мы дома.

1 Ответ

2 голосов
/ 07 октября 2019

Похоже, что метод .Execute возвращает набор записей курсора только для чтения.

Для получения набора записей не только для чтения необходимо использовать метод Recordset.Open.

Это работает для меня:

Private Sub Form_Load()

Dim sqldb As Object, adocom As Object, rs As Object
Set sqldb = CreateObject("ADODB.Connection")
Set adocom = CreateObject("ADODB.Command")
Set rs = CreateObject("ADODB.Recordset")
sqldb.Open "Driver={SQL Server Native Client 11.0};Server=SQL;Database=Test;Trusted_Connection=yes;"
sqldb.CursorLocation = adUseClient
rs.LockType = adLockBatchOptimistic
rs.CursorType = adOpenDynamic

rs.Open "SELECT Field FROM Table1", sqldb 'changed code

Set Me.Recordset = rs

End Sub

Как я уже говорил в моем комментарии выше, вы всегда должны проверять настройки набора записей в локальных окнах, так как они могут отличаться от вашихset!

В вашем коде наборы записей .LockType получают adLockReadOnly, что объясняет форму только для чтения.

Кстати, ваш код выглядит как использующий поздние ADODB, ноиспользование ADODB-Constants как adUseClient. Их нужно определять отдельно, если вы используете позднюю привязку ADODB

...