Записать значение столбца IDENTITY во время вставки и использовать в качестве значения для другого столбца в той же транзакции - PullRequest
1 голос
/ 21 марта 2019

При выполнении вставки в таблицу со столбцом IDENTITY возможно ли использовать значение IDENTITY в качестве значения для другого столбца в той же транзакции?

Например:

DECLARE @TestTable TABLE 
                   (
                        PrimaryId INT NOT NULL IDENTITY(1, 1), 
                        SecondaryId INT NOT NULL
                   );

INSERT INTO @TestTable (SecondaryId)
    SELECT 
        SCOPE_IDENTITY() + 1; -- set SecondaryId = PrimaryId + 1

SELECT * FROM @TestTable;

Ожидаемый:

| PrimaryId | SecondaryId |
+-----------+-------------+
|     1     |      2      |

Я думал, что смогу достичь этого с помощью системных функций SCOPE_IDENTITY или @@IDENTITY, но, к сожалению, это не работает, так как это NULL во время выполнения транзакции.

Невозможно вставить значение NULL в столбец «SecondaryId», таблица «@TestTable»; столбец не допускает пустых значений. Вставить не удается.

Я знаю, что мог бы использовать вычисляемый столбец для этого примера, но мне любопытно, возможно ли то, что я пытаюсь сделать .

Ответы [ 3 ]

0 голосов
/ 21 марта 2019

Я бы пошел с триггером, это также должно работать для многострочных вставок. Вам нужно будет удалить ненулевое значение для SecondaryID, не уверен, что это приемлемо.

create trigger trg_TestTable
   on    dbo.TestTable
   after insert 
AS 
BEGIN
    update TestTable
    set    SecondaryId = i.PrimaryId
    from   inserted  i
    join   TestTable a
      on   i.PrimaryId = a.PrimaryId;
END
GO
0 голосов
/ 21 марта 2019

Одна вещь, которую вы могли бы сделать, это использовать опцию OUTPUT INSERTED команды INSERT, чтобы захватить IDENTITY. В этом примере поле IDENTITY - это ScheduleID.

CREATE PROCEDURE dbo.spScheduleInsert
            (   @CustomerID int,
                @ItemID int,
                @StartDate Date,
                @TimeIn DateTime,
                @TimeOut DateTime,
                @ReturnIdentityValue int OUTPUT )
AS
BEGIN
            DECLARE @TempScheduleIdentity table ( TempScheduleID int )

            INSERT INTO Schedule ( CustomerID,ItemID,StartDate,TimeIn,TimeOut )
            OUTPUT INSERTED.ScheduleID into @TempScheduleIdentity
            VALUES  (@CustomerID,@ItemID,@StartDate,@TimeIn,@TimeOut)

            SELECT @ReturnIdentityValue = (SELECT TempScheduleID FROM @TempScheduleIdentity)

END

Когда у вас есть @ReturnIdentityValue ... вы можете затем обновить поле других записей значением.

0 голосов
/ 21 марта 2019

Не могли бы вы изменить свой подход и использовать SEQUENCE вместо IDENTITY столбца?

CREATE SEQUENCE TestSequence
    START WITH 1  
    INCREMENT BY 1 ;  
GO
CREATE TABLE TestTable (PrimaryId INT NOT NULL DEFAULT NEXT VALUE FOR TestSequence, SecondaryId INT NOT NULL);

GO

INSERT INTO TestTable (
    SecondaryId
)
SELECT  NEXT VALUE FOR TestSequence + 1; -- set SecondaryId = PrimaryId + 1;

GO 3

SELECT * FROM TestTable;

GO
DROP TABLE TestTable;
DROP SEQUENCE TestSequence;
...