2015-06-25 2 views
3

Я получаю сообщение об ошибке «Идентификация не может быть определена для вновь вставленных строк» ​​при попытке изменить поле записи ADO RecordSet после вызова AddNew и Update в файле .vbs. Однако я могу получить доступ к первичному ключу, который был возвращен из базы данных.«Идентификация не может быть определена для вновь вставленных строк» ​​после добавления ADO RecordSet AddNew и обновления

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

Dim connString : connString = "Provider=SQLOLEDB.1;Persist Security Info=True;Data Source=localhost;Initial Catalog=;User Id=;Password=" 

Dim conn, rsTaskLog, sSQL 

Set conn = CreateObject("ADODB.Connection") 
conn.Open connString 

' Create a new task log entry. 
Set rsTaskLog = CreateObject("ADODB.Recordset") 
sSQL = "SELECT * FROM Test" 
rsTaskLog.Open sSQL, conn, 1, 3, 1 'adOpenKeyset, adLockOptimistic, adCmdText 
rsTaskLog.AddNew 
rsTaskLog.Update 

' Set the task log result. 
rsTaskLog.Fields("test_int").Value = 1 ' Error occurs on this line. 
rsTaskLog.Update 

rsTaskLog.Close 
Set rsTaskLog = Nothing 

UPDATE:

Я был в состоянии сделать этот код работать, добавив следующую строку после первого обновления:

rsTaskLog.AbsolutePosition = rsTaskLog.AbsolutePosition 

Кое-что о перемещении текущей записи ставит RecordSet обратно в состояние, в котором можно редактировать (MoveLast и MoveFirst также работали). Кто-нибудь знает, что происходит за кулисами, которые вызывают это?

+0

На первый взгляд это не похоже на что-то не так с вашим кодом, поэтому проблема должна лежать в другом месте. На самом деле, я просто попробовал это, в том числе наличие двух наборов записей в одном и том же соединении, и у меня не было никаких проблем - я мог бы обновлять свою недавно добавленную запись столько раз, сколько захочу. Вы уверены, что в таблице ScheduledTaskLog указан первичный ключ, т. Е. Не только автогенерированный идентификатор? – Martha

+0

Честно говоря, я нахожу этот метод обновления записи действительно бедной. Почему бы вам (если можно) создать хранимую процедуру в целевой БД и передать значения этой формы? У вас может быть один SP для записи новой записи в журнале и возврата записи PK, а затем другой для ее обновления. Если вы не можете сделать это так, напишите параметризированную вставку и обновление непосредственно в свой код. – Paul

+0

Пол, я уже это сделал, код закончен. Я прошу с чисто академической точки зрения, какой основной механизм мешает работе этого кода. Марта, я упростил код достаточно, чтобы я не верил, что что-то еще затрагивает его, но завтра я попытаюсь выполнить простейшую возможную реализацию, чтобы быть уверенным. – David

ответ

1

Решение, которое я придумал добавлял следующую строку кода сразу после первого обновления вызывается на RecordSet:

rsTaskLog.AbsolutePosition = rsTaskLog.AbsolutePosition 

По какой-то причине движущемся положение курсора ставит RecordSet обратно в состояние, в котором Обновление можно вызывать снова без генерации ошибки (MoveFirst и MoveLast также работали, но, установив AbsolutePosition для себя, мы можем поддерживать текущую позицию). Я не совсем уверен, что происходит за кулисами здесь, не стесняйтесь уточнять, если вы знаете в комментариях.