Использование Scope_Identity () для добавления 2 внешних ключей на SQL Сервер - PullRequest
1 голос
/ 30 мая 2020

У меня вопрос о Scope_Identity() и транзакциях.

У меня есть эти три таблицы, а PK в MemberDetails - это 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

1 Ответ

0 голосов
/ 30 мая 2020

По сути, у вас есть два варианта:

  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;
У вас может быть три отдельные хранимые процедуры, первая из которых вставляется в «главную» таблицу и возвращает вновь созданное значение идентификатора обратно в вызывающий код. Оттуда, используя возвращенное значение, вы можете вызвать вторую и третью хранимые процедуры для вставки во вторую и третью таблицу. Обязательно заверните эти три вызова в транзакцию на стороне клиента, чтобы обеспечить правильную вставку данных.
...