Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / Microsoft SQL Server Новый топик    Ответить
 SQL Server + ADO + Delphi - проблема с автоинкрементными полями  [new]
crossa
Member

Откуда:
Сообщений: 98
Есть старый проект с использованием Delphi 7 и SQL Server 2005. Перевожу его с BDE на ADO. Есть таблица:
CREATE TABLE  table1  (
    ddd  INT IDENTITY NOT NULL,
    ttt  VARCHAR(100),
    CONSTRAINT table1_PK PRIMARY KEY(ddd) )

Редактирую ее при помощи TADOTable + TDataSetProvider + TClientDataSet. Есть необходимость присваивать первичному ключу свои собственные значения, поэтому использую такую команду для SQL Server:
SET IDENTITY_INSERT table1 ON

Код на Delphi выглядит так:
procedure SetIdentity(const s: String); 
begin                                      
      ADOQuery1.SQL.Text:='SET IDENTITY_INSERT table1 '+s;
      ADOQuery1.ExecSQL;
      ADOQuery1.Close; 
end;
...
ClientDataSet1.Append;
ClientDataSet1.FieldByName('ddd').ReadOnly:=False;
ClientDataSet1.FieldByName('ddd').AsInteger:=NewID;
ClientDataSet1.Post;
...
ADOTable.FieldByName('ddd').ReadOnly:=False;
SetIdentity('ON');
ClientDataSet1.ApplyUpdates(-1);
SetIdentity('OFF');

При выполнении "ClientDataSet1.ApplyUpdates" возникает ошибка с текстом: "Для столбца идентификаторов таблицы "table1" явное значение необходимо указывать в тех случаях, когда либо IDENTITY_INSERT имеет значение ON, либо когда пользователь репликации осуществляет вставку в столбец идентификаторов, отмеченный как NOT FOR REPLICATION."

Но в программе как раз и устанавливается IDENTITY_INSERT в значение ON; при отслеживании в Profiler видно, что SQL-команда на изменение этого параметра была выполнена. Также, Profiler показывает, что все запросы выполняются в рамках одной сессии, с одним и тем же SPID. При работе через BDE всё было нормально, программа вставляла в таблицу свои значения для автоинкрементного поля.

Подскажите, в чем может быть проблема. Задавал такой же вопрос в разделе форума о Delphi, но там решения найти не сумели.
26 фев 14, 13:49    [15632313]     Ответить | Цитировать Сообщить модератору
 Re: SQL Server + ADO + Delphi - проблема с автоинкрементными полями  [new]
Гавриленко Сергей Алексеевич
Member

Откуда: Moscow
Сообщений: 37224
Команду из профайлера покажите, которая уходит на сервер.
26 фев 14, 13:52    [15632338]     Ответить | Цитировать Сообщить модератору
 Re: SQL Server + ADO + Delphi - проблема с автоинкрементными полями  [new]
crossa
Member

Откуда:
Сообщений: 98
SET IDENTITY_INSERT table1 ON

SET NO_BROWSETABLE ON

exec sp_executesql N'SET NOCOUNT OFF; INSERT INTO "test".."table1" ("ttt") VALUES (@P1); SELECT SCOPE_IDENTITY() AS SCOPE_ID_COLUMN',N'@P1 varchar(4)','test'

SET NO_BROWSETABLE OFF

SET IDENTITY_INSERT table1 OFF
26 фев 14, 14:05    [15632445]     Ответить | Цитировать Сообщить модератору
 Re: SQL Server + ADO + Delphi - проблема с автоинкрементными полями  [new]
crossa
Member

Откуда:
Сообщений: 98
А раньше, при работе через BDE, это выглядело так:
SET IDENTITY_INSERT table1 ON

SET TRANSACTION ISOLATION LEVEL READ COMMITTED

exec sp_executesql N'INSERT INTO "TABLE1" ("ddd" ,"ttt" )  VALUES (@P1, @P2)',N'@P1 int,@P2 varchar(100)',1,'test'

SET IDENTITY_INSERT table1 OFF
26 фев 14, 14:13    [15632518]     Ответить | Цитировать Сообщить модератору
 Re: SQL Server + ADO + Delphi - проблема с автоинкрементными полями  [new]
Гавриленко Сергей Алексеевич
Member

Откуда: Moscow
Сообщений: 37224
Ну так и где явная вставка identity-значения в таблицу table1?
26 фев 14, 14:14    [15632529]     Ответить | Цитировать Сообщить модератору
 Re: SQL Server + ADO + Delphi - проблема с автоинкрементными полями  [new]
Гавриленко Сергей Алексеевич
Member

Откуда: Moscow
Сообщений: 37224
crossa
А раньше, при работе через BDE, это выглядело так:
SET IDENTITY_INSERT table1 ON

SET TRANSACTION ISOLATION LEVEL READ COMMITTED

exec sp_executesql N'INSERT INTO "TABLE1" ("ddd" ,"ttt" )  VALUES (@P1, @P2)',N'@P1 int,@P2 varchar(100)',1,'test'

SET IDENTITY_INSERT table1 OFF
Сервер не может влиять на неправильный тект запросов, которое ему присылает приложение.
26 фев 14, 14:14    [15632538]     Ответить | Цитировать Сообщить модератору
 Re: SQL Server + ADO + Delphi - проблема с автоинкрементными полями  [new]
Glory
Member

Откуда:
Сообщений: 104751
crossa
А раньше, при работе через BDE, это выглядело так:

Сервер не может заставить клиента формировать тексты команд.
А также не может подменять их на другие.
26 фев 14, 14:15    [15632551]     Ответить | Цитировать Сообщить модератору
 Re: SQL Server + ADO + Delphi - проблема с автоинкрементными полями  [new]
crossa
Member

Откуда:
Сообщений: 98
Понятно, спасибо. Значит, это ADO не дает возможность вставить свои значения в автоинкрементное поле. Надо искать способ, как сообщить ему, что IDENTITY_INSERT уже имеет значение ON. :(
26 фев 14, 14:28    [15632640]     Ответить | Цитировать Сообщить модератору
 Re: SQL Server + ADO + Delphi - проблема с автоинкрементными полями  [new]
Glory
Member

Откуда:
Сообщений: 104751
crossa
Надо искать способ, как сообщить ему, что IDENTITY_INSERT уже имеет значение ON. :(

Дело не в IDENTITY_INSERT, а в отсутствии в тексте запроса поля identity и значения для него
26 фев 14, 14:30    [15632662]     Ответить | Цитировать Сообщить модератору
 Re: SQL Server + ADO + Delphi - проблема с автоинкрементными полями  [new]
crossa
Member

Откуда:
Сообщений: 98
Glory
Дело не в IDENTITY_INSERT, а в отсутствии в тексте запроса поля identity и значения для него

Запрос формирую не я сам, он генерится ADO или BDE при выполнении команды "ApplyUpdates". По этой команде может создаваться множество SQL-запросов, который сохранят в базе данных все те изменения, которые пользователь только что проделал с данными в памяти компьютера.
26 фев 14, 14:37    [15632717]     Ответить | Цитировать Сообщить модератору
 Re: SQL Server + ADO + Delphi - проблема с автоинкрементными полями  [new]
Glory
Member

Откуда:
Сообщений: 104751
crossa
Запрос формирую не я сам, он генерится ADO или BDE при выполнении команды "ApplyUpdates".

Код то вы пишите, а не ADO или BDE
26 фев 14, 14:38    [15632734]     Ответить | Цитировать Сообщить модератору
 Re: SQL Server + ADO + Delphi - проблема с автоинкрементными полями  [new]
Гавриленко Сергей Алексеевич
Member

Откуда: Moscow
Сообщений: 37224
crossa
Glory
Дело не в IDENTITY_INSERT, а в отсутствии в тексте запроса поля identity и значения для него

Запрос формирую не я сам, он генерится ADO или BDE при выполнении команды "ApplyUpdates". По этой команде может создаваться множество SQL-запросов, который сохранят в базе данных все те изменения, которые пользователь только что проделал с данными в памяти компьютера.
Тогда надо копаться в ADO, чтобы заставить его делать явную вставку в identity-поле.

Кстати, когда делаете кросспостинг, неплохо бы приводить ссылки на тему в другом форуме.
26 фев 14, 14:39    [15632743]     Ответить | Цитировать Сообщить модератору
 Re: SQL Server + ADO + Delphi - проблема с автоинкрементными полями  [new]
alexeyvg
Member

Откуда: Moscow
Сообщений: 31863
crossa
Запрос формирую не я сам, он генерится ADO или BDE при выполнении команды "ApplyUpdates". По этой команде может создаваться множество SQL-запросов, который сохранят в базе данных все те изменения, которые пользователь только что проделал с данными в памяти компьютера.
Или разбираетесь с ADO/BDE, что бы они правильно генерили запрос, либо делаете прямую отсылку команд, это уж точно можно.
26 фев 14, 20:20    [15635547]     Ответить | Цитировать Сообщить модератору
 Re: SQL Server + ADO + Delphi - проблема с автоинкрементными полями  [new]
ziktuw
Member

Откуда:
Сообщений: 3552
ADO Connection не умеет одновременно держать открытый недофетченный набор данных и в той же сессии выполнять какие-то другие запросы. Он для этого открывает временные другие соединения, выполняет в них запросы и закрывает эти временные сессии. Поэтому ваши инструкции SET IDENTITY_INSERT выполняются в других сессиях, а не в той что вы ожидаете.
В общем, пересмотрите решение.
28 фев 14, 17:11    [15648011]     Ответить | Цитировать Сообщить модератору
 Re: SQL Server + ADO + Delphi - проблема с автоинкрементными полями  [new]
crossa
Member

Откуда:
Сообщений: 98
ziktuw
ADO Connection не умеет одновременно держать открытый недофетченный набор данных и в той же сессии выполнять какие-то другие запросы.

Да, опытным путем теперь в этом убедился. Пришлось отказаться от вставки своих значений в автоинкрементное поле. Спасибо за разъяснения.
3 мар 14, 14:12    [15662838]     Ответить | Цитировать Сообщить модератору
 Re: SQL Server + ADO + Delphi - проблема с автоинкрементными полями  [new]
Glory
Member

Откуда:
Сообщений: 104751
crossa
Да, опытным путем теперь в этом убедился. Пришлось отказаться от вставки своих значений в автоинкрементное поле.

Офигительный вывод.
Вы точно прочитали "и в той же сессии выполнять какие-то другие запросы" ?
Другие запросы подразумевает вообще любые запросы.
Кроме того, если соединение занято недофетченным набором, то ошибка будет вида "соединение занято выполнением запроса", а не "Для столбца идентификаторов таблицы "table1" явное значение необходимо указывать в тех случаях,..."
3 мар 14, 14:33    [15662998]     Ответить | Цитировать Сообщить модератору
 Re: SQL Server + ADO + Delphi - проблема с автоинкрементными полями  [new]
ziktuw
Member

Откуда:
Сообщений: 3552
Glory
Кроме того, если соединение занято недофетченным набором, то ошибка будет вида "соединение занято выполнением запроса", а не "Для столбца идентификаторов таблицы "table1" явное значение необходимо указывать в тех случаях,..."


В данном случае такой ошибки не будет. Объект ADODB.Connection тупо откроет дополнительное соединение и в нем выполнит запрос. Впрочем, это поведение лечится установкой динамической пропертью (какой не помню сейчас), и тогда объект соединения не сможет открыть параллельный коннект. Вот тогда и выплывет ошибка о занятости соединения.
3 мар 14, 15:55    [15663802]     Ответить | Цитировать Сообщить модератору
Все форумы / Microsoft SQL Server Ответить