Конференция "Базы" » Автоинкрементные поля в MS SQL [MSSQL]
 
  • kaif © (08.09.08 00:49) [0]
    Обычно в IB Или ORACLE для этой цели я юзал генераторы. Генератор - вещь понятная. По сути это глобальная переменная вне контекста транзакции.

    В MSSQL для этой цели предлагается юзать тип поля IDENTITY.
    А после вставки проверять значение глобальной переменной @@IDENTITY, которая хранит значение "последнего" значения   присвоенного полю IDENTITY  в данной сессии.

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

    Вот, что я делал в хранимой процедуре:

    1. Вставляю запись в главную таблицу.
    2. Сохраняю @@IDENTITY во временной переменной
    3. В цикле пытаюсь вставить записи в подчиненную, используя сохраненное значение IDENTITY в локальной переменной.

    На самом же деле происходило следующее. По условиям техзадания мне нужно было зачем-то в триггере той самой главной таблицы сделать инсерт еще в одну таблицу. И этот триггер делал этот инсерт. И вот он-то и портил "последнее значение" глобальной переменной @@IDENTITY, так как в той таблице тоже есть полде типа IDENTITY.

    Вот такой вот интересный маразм получается.
    Если кто-то повесит триггер на таблицу, который вставит что-то в другую таблицу, то закончиться это может потерей правильного значения @@IDENTITY . Причем откуда его тогда брать, уже неизвестно. Похоже нужно воспользоваться запросом по альтернативному ключу к вставленной записи. Но тогда лучше вообще не юзать эту глобальную переменную @@IDENTITY. Или строго-настрого запретить себе и всем остальным что-либо вставлять из триггеров куда-либо. Даже в таблицу логов, если кто-то захочет. А то вдруг какая-то процедура юзает этот @@IDENTITY и он будет запорчен?

    Вот так вот.

    Готов выслушать битье ногами по полной программе. Просто 10 минут смотрел как ошалелый на то, как "сразу после вставки" в тексте процедуры @@IDENTITY меняет свое значение до неузнаваемости. Пока сообразил, что происходит.
  • sniknik © (08.09.08 01:31) [1]
    > Вот, что я делал в хранимой процедуре:
    т.е. ничего? тут одни слова, в процедуре это не более чем коментарии.

    > Причем откуда его тогда брать, уже неизвестно.
    известно. в справке написано, если пройти по ссылкам из @@IDENTITY.
    но ты опять просился делать "по аналогиям" не читая как оно на самом деле...

    > Но тогда лучше вообще не юзать эту глобальную переменную @@IDENTITY.
    это как ложка, в обед ее очень полезно юзать, во время секса она практически бесполезна и лучше ее не юзать, а у Нео ее вообще нет...
  • sniknik © (08.09.08 01:35) [2]
    > просился
    бросился
  • Германн © (08.09.08 01:52) [3]

    > а у Нео ее вообще нет...

    Это как? Он что, палочками пользуется?
    :)
  • kaif © (08.09.08 03:26) [4]
    sniknik ©   (08.09.08 01:31) [1]
    > Вот, что я делал в хранимой процедуре:
    т.е. ничего? тут одни слова, в процедуре это не более чем коментарии.


    Я думал, что хотя бы здесь я с людьми беседую, а не с SQL-сервером.
    :)
  • Вариант (08.09.08 08:12) [5]

    > kaif ©   (08.09.08 00:49)

    SCOPE_IDENTITY

    Электронная документация по MSSQL Server 2005

    "...Допуская, что столбец идентификаторов имеется в обеих таблицах, T1 и T2, функции @@IDENTITY и SCOPE_IDENTITY вернут разные значения в конце инструкции INSERT в таблице T1. Функция @@IDENTITY возвращает значение столбца идентификаторов, добавленное в текущем сеансе последним во всех областях. Это значение, вставленное в таблицу T2. Функция SCOPE_IDENTITY() возвратит значение IDENTITY, вставленное в таблицу T1. Это было последним добавлением, произошедшим в заданной области. Функция SCOPE_IDENTITY() вернет значение NULL, если функция была вызвана до того, как какая-либо инструкция INSERT была выполнена для столбца идентификаторов в этой области..."
  • Anatoly Podgoretsky © (08.09.08 08:35) [6]
    > kaif  (08.09.2008 0:49:00)  [0]

    Читаешь BOL по теме @@IDENTITY и смотришь See ALso по двум другим фунциям из данного раздела, затем выбираешь нужную.
  • Медвежонок Пятачок © (08.09.08 09:07) [7]
    на 2005 вообще есть ретурн параметры после инсерта/апдейта. но это скорее для "на клиенте"
  • sniknik © (08.09.08 11:27) [8]
    > Это как? Он что, палочками пользуется?
    внутривенно.
 
Конференция "Базы" » Автоинкрементные поля в MS SQL [MSSQL]
Есть новые Нет новых   [134435   +34][b:0][p:0]