Будет ли SCOPE_IDENTITY работать в этом случае?

У меня есть PK, который является самоинкрементным ключом. Мне нужно вставить запись в базу данных, а затем вернуть этот ПК и использовать его в другой вставке.

Однако я хотел бы сделать это в одной транзакции. Это возможно. Идея состоит в том, что если что-то выйдет из строя в каком-либо из обновлений/вставок, которые я должен сделать, я могу откатить все, но у меня сложилось впечатление, что мне нужно сделать фиксацию.

Сначала я собирался сделать это в ado.net, но затем переключился на хранимую процедуру, так как подумал, что, возможно, это решит эту проблему.

Поможет ли мне в этом случае ИП?


person chobo2    schedule 10.10.2012    source источник


Ответы (2)


Да, scope_identity предоставит вам последний вставленный идентификатор. В качестве альтернативы, если вы используете sql server 2005+, вы можете использовать предложение вывода.

INSERT INTO [MyTable]([MyCol])
OUTPUT INSERTED.ID
SELECT [MyCol] FROM [MySourceTable];
person Paul Fleming    schedule 10.10.2012

Как насчет:

BEGIN TRANSACTION
BEGIN TRY

   INSERT INTO dbo.YourFirstTable(.....)
   VALUES(.......)

   DECLARE @newID INT
   SELECT @newID = SCOPE_IDENTITY()

   INSERT INTO dbo.YourSecondTable(ID, .......)
   VALUES(@newID, ........)

   COMMIT TRANSACTION
END TRY
BEGIN CATCH
    SELECT 
        ERROR_NUMBER() AS ErrorNumber,
        ERROR_SEVERITY() AS ErrorSeverity,
        ERROR_STATE() AS ErrorState,
        ERROR_PROCEDURE() AS ErrorProcedure,
        ERROR_LINE() AS ErrorLine,
        ERROR_MESSAGE() AS ErrorMessage

    ROLLBACK TRANSACTION
END CATCH

Должен работать в любой версии SQL Server 2005 или новее.

Просто извлекая значение SCOPE_IDENTITY(), вы определенно не "ломаете" транзакцию... заверните это, например, в хранимую процедуру или просто вызовите ее из кода вызова.

person marc_s    schedule 10.10.2012
comment
@ chobo2: поместите это в хранимую процедуру и вызовите эту процедуру - это, безусловно, самое простое решение ... - person marc_s; 11.10.2012
comment
Хорошо, если проще. 2 вопроса. Что произойдет, если вы завернете хранимую процедуру ado.net в транзакцию и выполните откат. Вам это все еще нужно в SP? Во-вторых, что произойдет, если вам нужно вернуть идентификаторы из двух вставок, будет ли Scope_Identity работать? - person chobo2; 11.10.2012
comment
@chobo2: SCOPE_IDENTITY() возвращает последнее вставленное значение IDENTITY — последнее значение ONE. Если вставить две строки - нет, то не работает (просто возвращает последнее вставленное значение). Не уверен, что вы имеете в виду, заключая это в транзакцию - здесь уже есть транзакция. Но если внутри этой хранимой процедуры есть откат, то любая оберточная транзакция также будет отброшена - SQL Server на самом деле не имеет настоящих вложенных/независимых транзакций... - person marc_s; 11.10.2012
comment
Хм, как я могу это сделать, тогда я не могу: вставить, прицел, вставить прицел :) - person chobo2; 11.10.2012
comment
@chobo2: в этом случае вам нужно предложение OUTPUT для вывода вновь вставленного ID — вместе с чем-то еще, что можно использовать позже — в, например, табличная переменная (как Флем показал в своем ответе) - person marc_s; 11.10.2012
comment
вывод нарушит транзакцию? Похоже, запись уже вставлена ​​в это время. - person chobo2; 11.10.2012
comment
@chobo2: НЕТ - почему вы думаете, что все нарушает транзакцию? Если не произойдет ROLLBACK - ничто не нарушит транзакцию ..... - person marc_s; 11.10.2012
comment
вам не нужно делать фиксацию для вставки записи и получения сгенерированного ПК. Как я уже сказал, я использую nhibernate. Чтобы получить сгенерированный PK, запись должна быть зафиксирована, и это необходимо сделать на сервере. Как только происходит коммит, транзакция выполняется, и вы должны начать новую. Тем самым разорвав транзакцию - person chobo2; 11.10.2012
comment
@chobo2: НЕТ — данные будут вставлены — просто еще не зафиксированы. Но когда он вставлен, определяются новые значения IDENTITY - вы можете прочитать их. Теперь, если транзакция в конечном итоге будет отброшена, эти значения идентификатора PK будут забыты (например, они были использованы, но отброшены), и именно так могут возникать пробелы в столбце IDENTITY. Но вам обязательно нужно изучить транзакции и обработку транзакций в SQL Server! Проверьте соответствующую документацию MSDN. - person marc_s; 11.10.2012