使用Scope_Identity()在SQL Server中添加2个外键

问题描述 投票:1回答:1

我对Scope_Identity()和交易有疑问。

我有这三个表,MemberDetails中的PK是其他两个表中的FK。

我一直在尝试使用Scope_Identity()创建存储过程,以便将FK自动添加到表中,但是我不知道该怎么做。

你有什么想法吗?

提前感谢

CREATE TABLE [MarketingTarget] 
(
    [MTid] int identity (5000,1) NOT NULL UNIQUE,
    [MDOB] date NOT NULL,
    [MSex] char (1) NOT NULL CHECK (MSex IN ('M','F')) DEFAULT 'M',
    [MemberID] int NULL,
    [MTUpdate] Date Null DEFAULT Getdate(),
    PRIMARY KEY ([MTid]),
    FOREIGN KEY (MemberID) REFERENCES [MemberDetails] ([MemberID]) 
            ON DELETE SET NULL 
            ON UPDATE CASCADE
);

CREATE TABLE [MembershipDetails] 
(
    [MDid] int identity (2000,1) NOT NULL UNIQUE,
    [MType] varchar(10) NOT NULL CHECK (MType IN ('Monthly','Quaterly','Yearly'))  DEFAULT 'Monthly',
    [JoinDate] Date NOT NULL DEFAULT GETDATE(),
    [ExpiryDate] Date NULL,
    [MsUpdate] Date DEFAULT GETDATE(),
    [MemberID] int NULL,
    PRIMARY KEY ([MDid]),
    FOREIGN KEY (MemberID) REFERENCES [MemberDetails] ([MemberID]) 
            ON DELETE SET NULL
            ON UPDATE CASCADE  
);

CREATE TABLE [MemberDetails] 
(
    [MemberID] int identity (1000,1) NOT NULL UNIQUE,
    [MName] varchar(100) NOT NULL,
    [MSurname] varchar(100) NOT NULL,
    [MPhone] varchar(20) NOT NULL UNIQUE,
    [MEmail] varchar(200) NOT NULL UNIQUE,
    [MAddress] varchar(250) NOT NULL,
    [MActive] char (1) NOT NULL CHECK (MActive IN ('Y','N')) DEFAULT 'Y',
    [MUpdateDate] Date NOT NULL DEFAULT GETDATE(),
    [MPhoto] Image NOT NULL
    PRIMARY KEY ([MemberID])
);
CREATE PROC spInsertMarketingTarget_test1
    @MDOB date,
    @MSex char (1),
    @MemberID int,
    @MTUpdate Date
AS
    BEGIN TRY
        IF (SELECT COUNT(*) FROM MarketingTarget mt 
            WHERE MemberID = @MemberID) > 0
            RAISERROR ('Fatal error. Member already exist.', 16, 1)

        BEGIN TRANSACTION
            INSERT INTO MarketingTarget
                SELECT
                    @MDOB, @MSex, @MemberID, @MTUpdate
            COMMIT TRANSACTION
END TRY
BEGIN CATCH
    SELECT
        ERROR_NUMBER() AS ErrorNumber,
        ERROR_STATE() AS ErrorState,
        ERROR_SEVERITY() AS ErrorSeverity,
        ERROR_PROCEDURE() AS ErrorProcedure,
        ERROR_LINE() AS ErrorLine,
        ERROR_MESSAGE() AS ErrorMessage;

    -- Transaction uncommittable
    IF (XACT_STATE()) = -1
        ROLLBACK TRANSACTION

    -- Transaction committable
    IF (XACT_STATE()) = 1
        COMMIT TRANSACTION
END CATCH;
GO

CREATE PROCEDURE spInsertMemberDetails
    @MemberID int = 0,
    @MName varchar(100),
    @MSurname varchar(100),
    @MPhone varchar(20),
    @MEmail varchar(200),
    @MAddress varchar(250),
    @MActive char (1),
    @MUpdateDate Date,
    @MPhoto image
AS
BEGIN
    SET NOCOUNT ON;

    INSERT INTO [MemberDetails] (MName, MSurname, MPhone, MEmail, MAddress, MActive, MUpdateDate, MPhoto)
    VALUES (@MName, @MSurname, @MPhone, @MEmail, @MAddress, @MActive, @MUpdateDate, @MPhoto)

    SET @MemberID = SCOPE_IDENTITY()
END
GO
sql-server stored-procedures transactions foreign-keys primary-key
1个回答
0
投票

基本上,您有两个选择:

  1. 您可以编写一个存储过程,该存储过程采用将值插入三个表所需的所有参数。然后在该存储过程中,插入到第一个表中,获取标识值,然后使用该标识值插入到第二个和第三个表中。
CREATE PROCEDURE dbo.InsertAllData
    (--list all the parameters needed for all three inserts--)
AS
BEGIN
    INSERT INTO [MemberDetails] (MName, MSurname, MPhone, MEmail, MAddress, MActive, MUpdateDate, MPhoto)
    VALUES (@MName, @MSurname, @MPhone, @MEmail, @MAddress, @MActive, @MUpdateDate, @MPhoto)

    SELECT @MemberID = SCOPE_IDENTITY()

    INSERT INTO dbo.MarketingTarget (MemberID, -- other columns --)
    VALUES (@MemberID, -- other values);

    INSERT INTO dbo.MembershipDetails (MemberID, -- other columns --)
    VALUES (@MemberID, -- other values);
END;
  1. 您可以具有三个独立的存储过程,第一个存储过程将插入“主”表中,并将新创建的标识值返回给调用代码。从那里,使用返回的值,然后可以调用第二个和第三个存储过程以插入到第二个和第三个表中。确保将这三个调用包装到客户端事务中,以确保正确插入数据。
© www.soinside.com 2019 - 2024. All rights reserved.