Sql server 使用Scope_Identity()在SQL Server中添加2个外键
我有一个关于Sql server 使用Scope_Identity()在SQL Server中添加2个外键,sql-server,stored-procedures,transactions,foreign-keys,primary-key,Sql Server,Stored Procedures,Transactions,Foreign Keys,Primary Key,我有一个关于Scope\u Identity()和事务的问题 我有这三个表,MemberDetails中的PK是其他两个表中的FK 我一直在尝试使用Scope\u Identity()创建存储过程,以便将FK自动添加到表中,但我不知道如何执行 你知道吗 提前谢谢 CREATE TABLE [MarketingTarget] ( [MTid] int identity (5000,1) NOT NULL UNIQUE, [MDOB] date NOT NULL, [MSe
Scope\u Identity()
和事务的问题
我有这三个表,MemberDetails
中的PK是其他两个表中的FK
我一直在尝试使用Scope\u 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])
);
基本上,您有两种选择:
基本上,您有两种选择:
image
数据类型将在SQL Server的未来版本中删除。避免在新的开发工作中使用此数据类型,并计划修改当前使用它的应用程序。改用varbinary(max)
。如果不存在,则spInsertMarketingTarget_test1中的插入逻辑正在为您创建竞争条件。您可以将它们合并到一个语句中以避免该问题,然后仅在未插入行时(即:它已存在)才会引发错误。不要捕获错误,而只是将其作为过程中的结果集来选择。这样做会对调用方隐藏错误,并且不会调用调用方处理的任何错误。只需重新显示错误。你为什么需要交易呢?您只有一条DML语句—它要么工作要么失败,不需要任何事务。而且,您不应该仅仅为了确定是否存在而计数,这通常是非常低效的。image
数据类型将在SQL Server的未来版本中删除。避免在新的开发工作中使用此数据类型,并计划修改当前使用它的应用程序。改用varbinary(max)
。如果不存在,则spInsertMarketingTarget_test1中的插入逻辑正在为您创建竞争条件。您可以将它们合并到一个语句中以避免该问题,然后仅在未插入行时(即:它已存在)才会引发错误。不要捕获错误,而只是将其作为过程中的结果集来选择。这样做会对调用方隐藏错误,并且不会调用调用方处理的任何错误。只需重新显示错误。你为什么需要交易呢?您只有一条DML语句—它要么工作要么失败,不需要任何事务。你不应该仅仅为了确定存在而计算——这通常是非常低效的。
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
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;