Конференция "Базы" » bigint и @@identity [MSSQL]
 
  • девушка (04.06.08 09:17) [0]
    Добрый день!

    База на 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 выдает неверный результат??? ТРИГГЕРОВ НЕТ!
  • Anatoly Podgoretsky © (04.06.08 09:49) [1]
    > девушка  (04.06.2008 9:17:00)  [0]

    Вопрос в форум по MSSQL, например на sql.ru
  • Ega23 © (04.06.08 09:51) [2]
    Проверяй лучше.

    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



    Всё нормально отрабатывает.
  • девушка (04.06.08 10:01) [3]
    как ни странно
    select @@IDENTITY;

    выдает правильно значение, например 12

    а
    select @id_finplan_tmp=@@IDENTITY;

    выдает значение 11

    нумерация всеравно идет только по четным :(
  • Ega23 © (04.06.08 10:08) [4]
    А что будет, если заменить @@IDENTITY на  Scope_Identity()  ?
  • девушка (04.06.08 10:17) [5]
    Дело оказалось в EMS SQL Manager.
    В стандартной Managment Studio  все отработало, да и через самописный клиент все проходит...
  • Ega23 © (04.06.08 10:26) [6]
    Рекомендую использовать не @@identity а scope_identity(). Розница небольшая, но - есть. Читай BOL.
  • sniknik © (04.06.08 10:28) [7]
    > нумерация всеравно идет только по четным :(
    гдето ты ошибся...

    проверка
    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 сразу после инсерта... ты что ему не веришь? ;о))
  • девушка (04.06.08 10:31) [8]

    > ну триггеров нет, показанный автором код выводит @@IDENTITY
    > сразу после инсерта... ты что ему не веришь?


    я сама себе не верила, когда все это видела... придется похоже процедуру тестировать родными инструментами M$...
  • Ega23 © (04.06.08 10:35) [9]

    > ну триггеров нет, показанный автором код выводит @@IDENTITY
    > сразу после инсерта... ты что ему не веришь? ;о))


    Хрен его знает. Я бы всё равно воздержался от @@IDENTITY в данной ситуации.
  • девушка (04.06.08 10:38) [10]

    > Хрен его знает. Я бы всё равно воздержался от @@IDENTITY
    > в данной ситуации.


    в какой ситуации?
    а как воздержаться от @@IDENTITY, елс имне нужно в  процедуре B_EDIT вставить запись в  таблицу А (вызвав процедуру A_ADD),  и связать запись в таблице А с таблицей B.
  • Ega23 © (04.06.08 10:40) [11]
    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.
  • sniknik © (04.06.08 10:44) [12]
    > придется похоже процедуру тестировать родными инструментами M$...
    странные выводы... говоришь неверно работает сервер в какихто случаях, а грешишь на инструмент.
    ну вот какая разница откуда запрос пришел (если он одинаковый), если сервер неправильно данные по нему говоришь пишет?

    > Я бы всё равно воздержался от @@IDENTITY в данной ситуации.
    в процедурах да, хотя бы просто ради того чтобы после иметь возможность добавлять триггеры не меняя больше ничего.
    но не изза того, что @@IDENTITY работает неверно (на что сдесь жалоба), не может он верно работать в одном случае и неверно в другом... просто есть причина которую автор не учитывает, а не учитывая неправильно интерпретирует "неверный" вариант...
  • девушка (04.06.08 10:49) [13]

    > странные выводы... говоришь неверно работает сервер в какихто
    > случаях, а грешишь на инструмент.
    > ну вот какая разница откуда запрос пришел (если он одинаковый),
    >  если сервер неправильно данные по нему говоришь пишет?

    я не говорю что неверно работает @@IDENTITY. Кстати,  SCOPE_IDENTITY тоже не спасает.
    Я подозреваю EMS SQL Manager потомучто вызов одной и тойже процедуры из него и из инструментария MS SQL дают разные результаты.

    Думаю, что в  EMS SQL Manager это связано с транзакциями.
  • девушка (04.06.08 10:51) [14]
    В стандартном инструментарии вывод print совпадает со значением, вставленым в таблицу, а в EMS SQL Manager  - нет.
  • sniknik © (04.06.08 10:58) [15]
    > Думаю, что в  EMS SQL Manager это связано с транзакциями.
    т.е. типа он самовольно свои делает о которых ты не знаеш? если так, то это противоречит
    > SCOPE_IDENTITY тоже не спасает.

    причина в другом. т.е. допускаю, что EMS SQL Manager делает чтото не то, но это не транзакции. проверять его не могу (нету) да и не хочу, поэтому верю на слово.
  • stud © (04.06.08 11:06) [16]

    > В стандартном инструментарии вывод print совпадает со значением,
    >  вставленым в таблицу, а в EMS SQL Manager  - нет.

    совершенно нормальный инструмент. очень много раз проверял его с identity все нормально. скорее причина в другом.
    наверное есть смысл внимательнее прочитать

    > Ega23 ©   (04.06.08 10:40) [11]
  • девушка (04.06.08 12:05) [17]

    > совершенно нормальный инструмент. очень много раз проверял
    > его с identity все нормально. скорее причина в другом.
    > наверное есть смысл внимательнее прочитать
    >
    > > Ega23 ©   (04.06.08 10:40) [11]

    там же написано:
    Неудачно завершившиеся инструкции и транзакции могут изменить текущий идентификатор таблицы и создать пропуски в значениях столбца идентификаторов. Для значения идентификатора никогда не производится откат, несмотря на то, что транзакция, пытавшаяся вставить в таблицу значение, не была зафиксирована. Например, если инструкция INSERT привела к ошибке из-за нарушения ограничения IGNORE_DUP_KEY, текущий идентификатор для таблицы все равно увеличивается.
  • Ega23 © (04.06.08 12:07) [18]

    > Неудачно завершившиеся инструкции и транзакции могут изменить
    > текущий идентификатор таблицы и создать пропуски в значениях
    > столбца идентификаторов. Для значения идентификатора никогда
    > не производится откат, несмотря на то, что транзакция, пытавшаяся
    > вставить в таблицу значение, не была зафиксирована. Например,
    >  если инструкция INSERT привела к ошибке из-за нарушения
    > ограничения IGNORE_DUP_KEY, текущий идентификатор для таблицы
    > все равно увеличивается.
    >


    Это никаким образом не связано с тем, что @@Identity и Scope_Identity() могут выдавать разные значения.
  • девушка (04.06.08 12:08) [19]

    > Это никаким образом не связано с тем, что @@Identity и Scope_Identity()
    > могут выдавать разные значения.

    но это может быть связано с тем, что результаты одних и тех же действий в разных клиентах дают разный результат
  • stud © (04.06.08 14:49) [20]

    >  что результаты одних и тех же действий в разных клиентах
    > дают разный результат

    не может такого быть. ужеж объяснили, что клиент получает то, что ему возвращает сервер. а поля типа идентити - ну никак не клиентская часть.
    единственное разумное объяснение - что происходит событие, вызывающее увеличение повторное "срабатывание" идентити, например еще одна вставка.
    да и наверное нужен ПОЛНЫЙ текст процедуры с которой экспериментируете.
 
Конференция "Базы" » bigint и @@identity [MSSQL]
Есть новые Нет новых   [134434   +29][b:0][p:0.001]