Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 使用Scope_Identity()在SQL Server中添加2个外键_Sql Server_Stored Procedures_Transactions_Foreign Keys_Primary Key - Fatal编程技术网

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])
);

基本上,您有两种选择:

  • 您可以编写一个存储过程,获取将值插入三个表所需的所有参数。然后在该存储过程中,插入到第一个表中,获取标识值,然后使用该标识值插入到第二个和第三个表中
  • 您可以有三个单独的存储过程,第一个存储过程插入到“master”表中,并将新创建的标识值返回给调用代码。然后,使用返回的值调用第二个和第三个存储过程以插入到第二个和第三个表中。确保将这三个调用包装到客户端事务中,以确保正确插入数据

  • 基本上,您有两种选择:

  • 您可以编写一个存储过程,获取将值插入三个表所需的所有参数。然后在该存储过程中,插入到第一个表中,获取标识值,然后使用该标识值插入到第二个和第三个表中
  • 您可以有三个单独的存储过程,第一个存储过程插入到“master”表中,并将新创建的标识值返回给调用代码。然后,使用返回的值调用第二个和第三个存储过程以插入到第二个和第三个表中。确保将这三个调用包装到客户端事务中,以确保正确插入数据

  • 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;