如何在表不是Identity列的表中插入Identity列而不是常量?

时间:2019-12-25 04:02:57

标签: sql sql-server

CREATE PROCEDURE spCustomerDetails
    @FirstName NVARCHAR(30),
    @LastName NVARCHAR(30),
    @Phone CHAR(30),
    @Email NVARCHAR(30)
AS
BEGIN
    BEGIN TRY
        SET TRANSACTION ISOLATION LEVEL SERIALIZABLE

        BEGIN TRANSACTION
            INSERT INTO Person.Person (BusinessEntityID, PersonType, NameStyle,Title, FirstName, MiddleName, LastName, Suffix, EmailPromotion, AdditionalContactInfo)
            VALUES (20778, 'SC', 0, 'NULL', '@FirstName', '@MiddleName', '@LastName', 'NULL', '0', 'NULL');

            INSERT INTO Person.PersonPhone(BusinessEntityID, PhoneNumber, PhoneNumberTypeID)
            VALUES (20778, '@Phone', 2);

            INSERT INTO Person.EmailAddress (BusinessEntityID, EmailAddressID, EmailAddress)
            VALUES (20778, '1', '@Email');

            COMMIT TRANSACTION
    END TRY
    BEGIN CATCH
        ROLLBACK TRANSACTION

        PRINT 'Roll back transaction'
    END CATCH
END

我不打算将值20778插入BusinessEntity的列中。如何使用原始表(Person.BusinessEntity)中的最后一个插入项从原始表(MaterialApp)中调用它?

3 个答案:

答案 0 :(得分:1)

由于第一个表中的列是一个标识字段,因此您应该在第一个INSERT语句之后立即使用scope_idenity()来获取结果。然后在后续的INSERT语句中使用该结果。

Create Procedure spCustomerDetails
    @FirstName nvarchar (30),
    @LastName nvarchar(30),
    @Phone Char(30),
    @Email nvarchar(30)
    As
Begin
    Begin Try
        SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
        Begin Transaction

        DECLARE @NewBusEntityID int;

        INSERT INTO Person.Person(PersonType, NameStyle,Title, FirstName, MiddleName,  LastName, Suffix, EmailPromotion, AdditionalContactInfo)
        VALUES('SC', 0, 'NULL', '@FirstName', '@MiddleName', '@LastName', 'NULL', '0', 'NULL');

        SELECT @NewBusEntityID = scope_idenity();

        INSERT INTO Person.PersonPhone(BusinessEntityID, PhoneNumber, PhoneNumberTypeID)
        VALUES(@NewBusEntityID, '@Phone', 2);

        INSERT INTO Person.EmailAddress(BusinessEntityID,EmailAddressID,EmailAddress)
        VALUES(@NewBusEntityID, '1', '@Email');

        COMMIT TRANSACTION

    End Try
    Begin Catch
        Rollback Transaction
        Print 'Roll back transaction'
    End Catch
End

如果它不是标识字段,则可以改用SEQUENCE。然后,您可以在过程开始时选择NEXT VALUE FOR序列,并将该值用于所有三个INSERT语句。

答案 1 :(得分:0)

我建议您使用OUTPUT子句。不管表,其他事务,会话等上的触发器如何,这都行得通。

CREATE PROCEDURE spCustomerDetails (
    @FirstName NVARCHAR(30),
    @LastName NVARCHAR(30),
    @Phone CHAR(30),
    @Email NVARCHAR(30)
) AS
BEGIN
    DECLARE TABLE @id (BusinessEntityId INT);
    BEGIN TRY
        SET TRANSACTION ISOLATION LEVEL SERIALIZABLE

        BEGIN TRANSACTION

            INSERT INTO Person.Person (BusinessEntityID, PersonType, NameStyle, Title, FirstName, MiddleName, LastName, Suffix, EmailPromotion, AdditionalContactInfo)
                OUTPUT inserted.BusinessEntityId) INTO @ids
                VALUES (20778, 'SC', 0, NULL, @FirstName, @MiddleName, @LastName, NULL, '0', NULL);

            INSERT INTO Person.PersonPhone (BusinessEntityID, PhoneNumber, PhoneNumberTypeID)
                SELECT i.BusinessEntityID, @Phone, 2
                FROM @ids i;

            INSERT INTO Person.EmailAddress (BusinessEntityID, EmailAddressID, EmailAddress)
                SELECT i.BusinessEntityID, 1, @Email
                FROM @ids;

            COMMIT TRANSACTION;
    END TRY
    BEGIN CATCH
        ROLLBACK TRANSACTION

        PRINT 'Roll back transaction';
    END CATCH;
END;

请注意,这还会删除参数和NULL周围的单引号。我假设您想要的是参数值,而不是常量字符串。

答案 2 :(得分:-2)

您可以使用MAX:

DECLARE @id int = (select max(BusinessEntityId) From Person.BusinessEntity)