-
Добрый день! База на MS SQL Server 2005. Ни одного триггера. Процедуры для добавления записей в таблицу элементарные типа:
CREATE PROCEDURE [dbo].[pFINPLAN_ADD](
@rec_name varchar(256)
)
AS
BEGIN
insert into FINPLAN(
rec_name
)
values(
@rec_name
);
print(@@IDENTITY);
END
ПРоблема в следующем: Если тип первичного ключа [id_finplan] int IDENTITY(1, 1) NOT NULL то строка print(@@IDENTITY); выдает то же самое значение, что идет в таблицу. Инкимент идет правильно - 1, 2, 3... Если тип первичного ключа [id_finplan] bigint IDENTITY(1, 1) NOT NULL то строка print(@@IDENTITY); выдает например 11, а в таблицу вставляется 12. Т.е. все записи в таблице идут как 2, 4, 6... В чем проблема? Может для полей bigint нужно иначе настраивать автоинкремент? Но почему @@IDENTITY выдает неверный результат??? ТРИГГЕРОВ НЕТ!
-
> девушка (04.06.2008 9:17:00) [0]
Вопрос в форум по MSSQL, например на sql.ru
-
Проверяй лучше.
create table xxx (unid bigint identity (1,1), aVal int)
Set NoCount ON
insert into xxx (aVal) Values (1)
SELECT @@IDENTITY
insert into xxx (aVal) Values (2)
SELECT @@IDENTITY
insert into xxx (aVal) Values (3)
SELECT @@IDENTITY
insert into xxx (aVal) Values (4)
SELECT @@IDENTITY
drop table xxx
Всё нормально отрабатывает.
-
как ни странно select @@IDENTITY;
выдает правильно значение, например 12
а select @id_finplan_tmp=@@IDENTITY;
выдает значение 11
нумерация всеравно идет только по четным :(
-
А что будет, если заменить @@IDENTITY на Scope_Identity() ?
-
Дело оказалось в EMS SQL Manager. В стандартной Managment Studio все отработало, да и через самописный клиент все проходит...
-
Рекомендую использовать не @@identity а scope_identity(). Розница небольшая, но - есть. Читай BOL.
-
> нумерация всеравно идет только по четным :( гдето ты ошибся... проверка DECLARE @id_finplan_tmp bigint
IF OBJECT_ID('Table1') IS NULL
CREATE TABLE Table1 (ID bigint Identity(1, 1) PRIMARY KEY, Name VarChar(50))
INSERT INTO Table1 (Name) VALUES ('1')
SELECT @@IDENTITY
INSERT INTO Table1 (Name) VALUES ('2')
SELECT @@IDENTITY
INSERT INTO Table1 (Name) VALUES ('3')
SELECT @id_finplan_tmp = @@IDENTITY
SELECT @id_finplan_tmp
INSERT INTO Table1 (Name) VALUES ('4')
SELECT @id_finplan_tmp = @@IDENTITY
SELECT @id_finplan_tmp выдает строго по порядку, 1 2 3 4 и последующий SELECT * FROM Table1 подтверждает что в таблицу вставилось именно так, а не только четные. т.е. все соответствует. > А что будет, если заменить @@IDENTITY на Scope_Identity() ? ну триггеров нет, показанный автором код выводит @@IDENTITY сразу после инсерта... ты что ему не веришь? ;о))
-
> ну триггеров нет, показанный автором код выводит @@IDENTITY > сразу после инсерта... ты что ему не веришь?
я сама себе не верила, когда все это видела... придется похоже процедуру тестировать родными инструментами M$...
-
> ну триггеров нет, показанный автором код выводит @@IDENTITY > сразу после инсерта... ты что ему не веришь? ;о))
Хрен его знает. Я бы всё равно воздержался от @@IDENTITY в данной ситуации.
-
> Хрен его знает. Я бы всё равно воздержался от @@IDENTITY > в данной ситуации.
в какой ситуации? а как воздержаться от @@IDENTITY, елс имне нужно в процедуре B_EDIT вставить запись в таблицу А (вызвав процедуру A_ADD), и связать запись в таблице А с таблицей B.
-
SCOPE_IDENTITY Returns the last IDENTITY value inserted into an IDENTITY column in the same scope. A scope is a module -- a stored procedure, trigger, function, or batch. Thus, two statements are in the same scope if they are in the same stored procedure, function, or batch.
Syntax SCOPE_IDENTITY( )
Return Types sql_variant
Remarks SCOPE_IDENTITY, IDENT_CURRENT, and @@IDENTITY are similar functions in that they return values inserted into IDENTITY columns.
IDENT_CURRENT is not limited by scope and session; it is limited to a specified table. IDENT_CURRENT returns the value generated for a specific table in any session and any scope. For more information, see IDENT_CURRENT.
SCOPE_IDENTITY and @@IDENTITY will return last identity values generated in any table in the current session. However, SCOPE_IDENTITY returns values inserted only within the current scope; @@IDENTITY is not limited to a specific scope.
For example, you have two tables, T1 and T2, and an INSERT trigger defined on T1. When a row is inserted to T1, the trigger fires and inserts a row in T2. This scenario illustrates two scopes: the insert on T1, and the insert on T2 as a result of the trigger.
Assuming that both T1 and T2 have IDENTITY columns, @@IDENTITY and SCOPE_IDENTITY will return different values at the end of an INSERT statement on T1.
@@IDENTITY will return the last IDENTITY column value inserted across any scope in the current session, which is the value inserted in T2.
SCOPE_IDENTITY() will return the IDENTITY value inserted in T1, which was the last INSERT that occurred in the same scope. The SCOPE_IDENTITY() function will return the NULL value if the function is invoked before any insert statements into an identity column occur in the scope.
See Examples for an illustration.
-
> придется похоже процедуру тестировать родными инструментами M$... странные выводы... говоришь неверно работает сервер в какихто случаях, а грешишь на инструмент. ну вот какая разница откуда запрос пришел (если он одинаковый), если сервер неправильно данные по нему говоришь пишет?
> Я бы всё равно воздержался от @@IDENTITY в данной ситуации. в процедурах да, хотя бы просто ради того чтобы после иметь возможность добавлять триггеры не меняя больше ничего. но не изза того, что @@IDENTITY работает неверно (на что сдесь жалоба), не может он верно работать в одном случае и неверно в другом... просто есть причина которую автор не учитывает, а не учитывая неправильно интерпретирует "неверный" вариант...
-
> странные выводы... говоришь неверно работает сервер в какихто > случаях, а грешишь на инструмент. > ну вот какая разница откуда запрос пришел (если он одинаковый), > если сервер неправильно данные по нему говоришь пишет?
я не говорю что неверно работает @@IDENTITY. Кстати, SCOPE_IDENTITY тоже не спасает. Я подозреваю EMS SQL Manager потомучто вызов одной и тойже процедуры из него и из инструментария MS SQL дают разные результаты.
Думаю, что в EMS SQL Manager это связано с транзакциями.
-
В стандартном инструментарии вывод print совпадает со значением, вставленым в таблицу, а в EMS SQL Manager - нет.
-
> Думаю, что в EMS SQL Manager это связано с транзакциями. т.е. типа он самовольно свои делает о которых ты не знаеш? если так, то это противоречит > SCOPE_IDENTITY тоже не спасает.
причина в другом. т.е. допускаю, что EMS SQL Manager делает чтото не то, но это не транзакции. проверять его не могу (нету) да и не хочу, поэтому верю на слово.
-
> В стандартном инструментарии вывод print совпадает со значением, > вставленым в таблицу, а в EMS SQL Manager - нет.
совершенно нормальный инструмент. очень много раз проверял его с identity все нормально. скорее причина в другом. наверное есть смысл внимательнее прочитать
> Ega23 © (04.06.08 10:40) [11]
-
> совершенно нормальный инструмент. очень много раз проверял > его с identity все нормально. скорее причина в другом. > наверное есть смысл внимательнее прочитать > > > Ega23 © (04.06.08 10:40) [11]
там же написано: Неудачно завершившиеся инструкции и транзакции могут изменить текущий идентификатор таблицы и создать пропуски в значениях столбца идентификаторов. Для значения идентификатора никогда не производится откат, несмотря на то, что транзакция, пытавшаяся вставить в таблицу значение, не была зафиксирована. Например, если инструкция INSERT привела к ошибке из-за нарушения ограничения IGNORE_DUP_KEY, текущий идентификатор для таблицы все равно увеличивается.
-
> Неудачно завершившиеся инструкции и транзакции могут изменить > текущий идентификатор таблицы и создать пропуски в значениях > столбца идентификаторов. Для значения идентификатора никогда > не производится откат, несмотря на то, что транзакция, пытавшаяся > вставить в таблицу значение, не была зафиксирована. Например, > если инструкция INSERT привела к ошибке из-за нарушения > ограничения IGNORE_DUP_KEY, текущий идентификатор для таблицы > все равно увеличивается. >
Это никаким образом не связано с тем, что @@Identity и Scope_Identity() могут выдавать разные значения.
-
> Это никаким образом не связано с тем, что @@Identity и Scope_Identity() > могут выдавать разные значения.
но это может быть связано с тем, что результаты одних и тех же действий в разных клиентах дают разный результат
-
> что результаты одних и тех же действий в разных клиентах > дают разный результат
не может такого быть. ужеж объяснили, что клиент получает то, что ему возвращает сервер. а поля типа идентити - ну никак не клиентская часть. единственное разумное объяснение - что происходит событие, вызывающее увеличение повторное "срабатывание" идентити, например еще одна вставка. да и наверное нужен ПОЛНЫЙ текст процедуры с которой экспериментируете.
|