使用 Scope_Identity() 在 SQL 服务器中添加 2 个外键
Using Scope_Identity() to add 2 foreign keys in SQL Server
我对 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
基本上,您有两个选择:
- 您可以编写一个存储过程,获取将值插入三个 table 所需的所有参数。然后在该存储过程中,插入第一个 table,获取标识值,然后使用该标识值插入第二个和第三个 table。
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;
- 您可以拥有三个独立的存储过程,第一个将新创建的标识值插入 "master" table 和 returns 返回调用代码。从那里,使用返回的值,您可以调用第二个和第三个存储过程以插入第二个和第三个 table。确保将这三个调用包装到客户端事务中,以确保正确插入数据。
我对 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
基本上,您有两个选择:
- 您可以编写一个存储过程,获取将值插入三个 table 所需的所有参数。然后在该存储过程中,插入第一个 table,获取标识值,然后使用该标识值插入第二个和第三个 table。
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;
- 您可以拥有三个独立的存储过程,第一个将新创建的标识值插入 "master" table 和 returns 返回调用代码。从那里,使用返回的值,您可以调用第二个和第三个存储过程以插入第二个和第三个 table。确保将这三个调用包装到客户端事务中,以确保正确插入数据。