![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
bigint и @@identity [MSSQL]
девушка © (2008-06-04 09:17:00)Добрый день!
База на 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 выдает неверный результат??? ТРИГГЕРОВ НЕТ!
stud (2008-06-04 14:49:00) [1]
> что результаты одних и тех же действий в разных клиентах
> дают разный результат
не может такого быть. ужеж объяснили, что клиент получает то, что ему возвращает сервер. а поля типа идентити - ну никак не клиентская часть.
единственное разумное объяснение - что происходит событие, вызывающее увеличение повторное "срабатывание" идентити, например еще одна вставка.
да и наверное нужен ПОЛНЫЙ текст процедуры с которой экспериментируете.
девушка (2008-06-04 12:08:00) [2]
> Это никаким образом не связано с тем, что @@Identity и Scope_Identity()
> могут выдавать разные значения.
но это может быть связано с тем, что результаты одних и тех же действий в разных клиентах дают разный результат
Ega23 (2008-06-04 12:07:00) [3]
> Неудачно завершившиеся инструкции и транзакции могут изменить
> текущий идентификатор таблицы и создать пропуски в значениях
> столбца идентификаторов. Для значения идентификатора никогда
> не производится откат, несмотря на то, что транзакция, пытавшаяся
> вставить в таблицу значение, не была зафиксирована. Например,
> если инструкция INSERT привела к ошибке из-за нарушения
> ограничения IGNORE_DUP_KEY, текущий идентификатор для таблицы
> все равно увеличивается.
>
Это никаким образом не связано с тем, что @@Identity и Scope_Identity() могут выдавать разные значения.
девушка (2008-06-04 12:05:00) [4]
> совершенно нормальный инструмент. очень много раз проверял
> его с identity все нормально. скорее причина в другом.
> наверное есть смысл внимательнее прочитать
>
> > Ega23 © (04.06.08 10:40) [11]
там же написано:
Неудачно завершившиеся инструкции и транзакции могут изменить текущий идентификатор таблицы и создать пропуски в значениях столбца идентификаторов. Для значения идентификатора никогда не производится откат, несмотря на то, что транзакция, пытавшаяся вставить в таблицу значение, не была зафиксирована. Например, если инструкция INSERT привела к ошибке из-за нарушения ограничения IGNORE_DUP_KEY, текущий идентификатор для таблицы все равно увеличивается.
stud (2008-06-04 11:06:00) [5]
> В стандартном инструментарии вывод print совпадает со значением,
> вставленым в таблицу, а в EMS SQL Manager - нет.
совершенно нормальный инструмент. очень много раз проверял его с identity все нормально. скорее причина в другом.
наверное есть смысл внимательнее прочитать
> Ega23 © (04.06.08 10:40) [11]
sniknik (2008-06-04 10:58:00) [6]> Думаю, что в EMS SQL Manager это связано с транзакциями.
т.е. типа он самовольно свои делает о которых ты не знаеш? если так, то это противоречит
> SCOPE_IDENTITY тоже не спасает.
причина в другом. т.е. допускаю, что EMS SQL Manager делает чтото не то, но это не транзакции. проверять его не могу (нету) да и не хочу, поэтому верю на слово.
девушка (2008-06-04 10:51:00) [7]В стандартном инструментарии вывод print совпадает со значением, вставленым в таблицу, а в EMS SQL Manager - нет.
девушка (2008-06-04 10:49:00) [8]
> странные выводы... говоришь неверно работает сервер в какихто
> случаях, а грешишь на инструмент.
> ну вот какая разница откуда запрос пришел (если он одинаковый),
> если сервер неправильно данные по нему говоришь пишет?
я не говорю что неверно работает @@IDENTITY. Кстати, SCOPE_IDENTITY тоже не спасает.
Я подозреваю EMS SQL Manager потомучто вызов одной и тойже процедуры из него и из инструментария MS SQL дают разные результаты.
Думаю, что в EMS SQL Manager это связано с транзакциями.
sniknik (2008-06-04 10:44:00) [9]> придется похоже процедуру тестировать родными инструментами M$...
странные выводы... говоришь неверно работает сервер в какихто случаях, а грешишь на инструмент.
ну вот какая разница откуда запрос пришел (если он одинаковый), если сервер неправильно данные по нему говоришь пишет?
> Я бы всё равно воздержался от @@IDENTITY в данной ситуации.
в процедурах да, хотя бы просто ради того чтобы после иметь возможность добавлять триггеры не меняя больше ничего.
но не изза того, что @@IDENTITY работает неверно (на что сдесь жалоба), не может он верно работать в одном случае и неверно в другом... просто есть причина которую автор не учитывает, а не учитывая неправильно интерпретирует "неверный" вариант...
Ega23 (2008-06-04 10:40:00) [10]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.
девушка (2008-06-04 10:38:00) [11]
> Хрен его знает. Я бы всё равно воздержался от @@IDENTITY
> в данной ситуации.
в какой ситуации?
а как воздержаться от @@IDENTITY, елс имне нужно в процедуре B_EDIT вставить запись в таблицу А (вызвав процедуру A_ADD), и связать запись в таблице А с таблицей B.
Ega23 (2008-06-04 10:35:00) [12]
> ну триггеров нет, показанный автором код выводит @@IDENTITY
> сразу после инсерта... ты что ему не веришь? ;о))
Хрен его знает. Я бы всё равно воздержался от @@IDENTITY в данной ситуации.
девушка (2008-06-04 10:31:00) [13]
> ну триггеров нет, показанный автором код выводит @@IDENTITY
> сразу после инсерта... ты что ему не веришь?
я сама себе не верила, когда все это видела... придется похоже процедуру тестировать родными инструментами M$...
sniknik (2008-06-04 10:28:00) [14]> нумерация всеравно идет только по четным :(
гдето ты ошибся...
проверка
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 сразу после инсерта... ты что ему не веришь? ;о))
Ega23 (2008-06-04 10:26:00) [15]Рекомендую использовать не @@identity а scope_identity(). Розница небольшая, но - есть. Читай BOL.
девушка (2008-06-04 10:17:00) [16]Дело оказалось в EMS SQL Manager.
В стандартной Managment Studio все отработало, да и через самописный клиент все проходит...
Ega23 (2008-06-04 10:08:00) [17]А что будет, если заменить @@IDENTITY на Scope_Identity() ?
девушка (2008-06-04 10:01:00) [18]как ни странно
select @@IDENTITY;
выдает правильно значение, например 12
а
select @id_finplan_tmp=@@IDENTITY;
выдает значение 11
нумерация всеравно идет только по четным :(
Ega23 (2008-06-04 09:51:00) [19]Проверяй лучше.
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
Всё нормально отрабатывает.
Anatoly Podgoretsky (2008-06-04 09:49:00) [20]> девушка (04.06.2008 9:17:00) [0]
Вопрос в форум по MSSQL, например на sql.ru