Вставка 2 внешних ключей в таблицу на SQL сервере - PullRequest
0 голосов
/ 27 мая 2020

У меня есть следующие 3 таблицы. Они связаны:

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,
    [MDid] int NULL UNIQUE,
    [MTid] int NULL UNIQUE,

    PRIMARY KEY ([MemberID]),
    FOREIGN KEY (MDid) REFERENCES [MembershipDetails] ([MDid]) 
                ON DELETE SET NULL
                ON UPDATE CASCADE,
    FOREIGN KEY (MTid) REFERENCES [MarketingTarget] ([MTid]) 
                ON DELETE SET NULL
                ON UPDATE CASCADE    
);

CREATE TABLE [MarketingTarget] 
(
    [MTid] int identity (5000,1) NOT NULL UNIQUE,
    [MDOB] date NOT NULL,
    [MSex] char NOT NULL CHECK (MSex IN ('M','F')) DEFAULT 'M',

    PRIMARY KEY ([MTid]),
);

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,
    [MsUpdateDate] Date DEFAULT GETDATE(),

    PRIMARY KEY ([MDid])
 );

Я хотел бы знать, можно ли автоматически вставить FK в таблицу MemberDetails из двух других таблиц? Я пытаюсь написать хранимые процедуры.

Я проверял Scope_Identity, который может получить последнее сгенерированное удостоверение, но я не уверен, как его правильно использовать.

Любые предложения были бы очень признательны.

1 Ответ

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

Вот пример (таблица была сокращена): Поскольку требуются оба значения IDENTITY, я бы сохранил их в переменной, а затем вставил вместе в MemberDetail. Я бы рекомендовал провести транзакцию для этой операции. И посмотрите TRY..CATCH. В зависимости от вашей ситуации вы можете проверить XACT_STATE ().

https://docs.microsoft.com/en-us/sql/t-sql/language-elements/try-catch-transact-sql?view=sql-server-ver15

, и есть примеры с использованием триггера https://docs.microsoft.com/en-us/sql/t-sql/functions/scope-identity-transact-sql?view=sql-server-ver15

CREATE TABLE [_TEST_MemberDetails] (
[MemberID] int identity (1000,1) NOT NULL UNIQUE,
[MDid] int NULL UNIQUE,
[MTid] int NULL UNIQUE,
PRIMARY KEY ([MemberID]),
FOREIGN KEY (MDid) REFERENCES [_TEST_MembershipDetails] ([MDid]) ON DELETE SET NULL
                                                         ON UPDATE CASCADE,
FOREIGN KEY (MTid) REFERENCES [_TEST_MarketingTarget] ([MTid]) ON DELETE SET NULL
                                                        ON UPDATE CASCADE    
);


 CREATE TABLE [_TEST_MarketingTarget] (
 [MTid] int identity (5000,1) NOT NULL UNIQUE,
 [MDOB] date NOT NULL,
 [MSex] char NOT NULL CHECK (MSex IN ('M','F')) DEFAULT 'M',
 PRIMARY KEY ([MTid]),
 );


 CREATE TABLE [_TEST_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,
 [MsUpdateDate] Date DEFAULT GETDATE(),
 PRIMARY KEY ([MDid])
 );

 -- SP CODE START HERE
 SET XACT_ABORT ON;
 BEGIN TRY
     BEGIN TRANSACTION
     DECLARE @MTID int = 0, @MDID int = 0

     INSERT INTO _TEST_MarketingTarget ([MDOB], [MSex])
     VALUES ('Jan 1, 2020', 'M')
     SELECT @MTID = SCOPE_IDENTITY()

     INSERT INTO [_TEST_MembershipDetails] ([MType], [JoinDate], [ExpiryDate], [MsUpdateDate])
     VALUES (DEFAULT, DEFAULT, 'Jan 1, 2020', DEFAULT)
     SELECT @MDID = SCOPE_IDENTITY()

     INSERT INTO [_TEST_MemberDetails] (Mdid, MTid)
     SELECT @MDID, @MTID

     COMMIT TRANSACTION
END TRY
BEGIN CATCH
    IF @@TRANCOUNT <> 0 ROLLBACK TRANSACTION
END CATCH
go
...