INSERT自动将TableAU中的主键增加到表的FK中

时间:2012-06-26 04:17:26

标签: sql-server primary-key

我有两张表:TableATableB

CREATE TABLE TableA (
[TableAId] [int] IDENTITY(1,1) NOT NULL...

CREATE TABLE TableB (
[TableBId] [int] IDENTITY(1,1) NOT NULL,
[TableAID] [int] NOT NULL... -- this is the FK

问题:(作为C#开发人员)

我正在写一个插入TableA的函数。我需要在TableA中抓取新创建的主键,并将其与其他数据一起插入TableB的FK。

我以前做过这个,但我不喜欢我在插入后立即查找TableA PK值,将其存储为变量然后将其插入TableB

有人能告诉我更有效的方法吗?也许在存储过程中使用scope_identity()?触发器不起作用,因为我需要在我的C#中使用新PK,因此我可以在插入TableB之前添加其他数据。另外,我希望在运行时锁定两个表。

谢谢你, 罗伯特

3 个答案:

答案 0 :(得分:1)

Declare @TableAId int

Insert TableA ( ... )
Values( ... )

Set @TableAId = Scope_Identity();

Insert TableB( TableAId, ... )
Values( @TableAId, ... )

应该注意,可以在一个批处理中将其发送到SQL Server。即,您可以将整个命令文本发送到SQL Server并立即执行。当然,您需要为表A 表B的所有非标识列使用参数。例如:

const string sql = @"Declare @TableAId int

Insert TableA ( ... )
Values( ... )

Set @TableAId = Scope_Identity();

Insert TableB( TableAId, ... )
Values( @TableAId, ... )";

using ( var conn = new SqlConnection( ... ) )
{
    using ( var cmd = new SqlCommand( sql, conn ) )
    {
        cmd.Parameters.AddWithValue( @TableACol, ... );
        cmd.Parameters.AddWithValue( @TableACol2, ... );
        ...
        cmd.Parameters.AddWithValue( @TableBCol, ... );

        cmd.ExecuteNonQuery();
    }
}

如果您使用的是SQL Server 2005或更高版本,则另一种选择可能是使用OUTPUT clause

Insert TableA( ... )
    Output Inserted.TableAId, @TableBCol1, @TableBCol2, ...
    Into TableB
Values( ... )

答案 1 :(得分:0)

如果您有一个存储过程同时插入两组数据,请使用此代码。

DECLARE @id INT

INSERT INTO [dbo].[TableA] VALUES (...)
SET @id = SCOPE_IDENTITY()

INSERT INTO [dbo].[TableB] VALUES (@id ...)

如果您使用的是原始ADO,请将@id设置为OUTPUT参数,并在第二次数据库调用中使用返回值。有关如何使用输出参数的信息,请参阅here for an example

至于锁定两个表,您可以在事务(TSQL或ADO.NET)中包装调用,也可以为存储过程设置SET TRANSACTION ISOLATION LEVEL SERIALIZABLE

答案 2 :(得分:0)

这有效......


USE [TestDB01] 

GO 

SET ANSI_NULLS ON 

GO 

SET QUOTED_IDENTIFIER ON 

GO

CREATE PROCEDURE [dbo].[sp_INSERT_INTO_Cars_And_Owners] 

- 在此处添加存储过程的参数

         @PartnerId INT  
        , @Title NVARCHAR(100)  
        , @Description TEXT  
        , @IPAddress NVARCHAR(16)   
        , @IsCarOwner BIT
        , @OwnerTypeTypeID INT

AS 

BEGIN 

-- SET NOCOUNT ON added to prevent extra result sets from interfering with SELECT statements.
SET NOCOUNT ON; 


DECLARE @CarId INT 


INSERT INTO [dbo].[Cars] ( 
    PartnerId 
    , Title 
    , Description 
    , IPAddress 
    , IsCarOwner 
    ) 
VALUES ( 
    @PartnerId 
    , @Title 
    , @Description 
    , @IPAddress 
    , @IsCarOwner 
    )  


SET @CarId = SCOPE_IDENTITY() 


INSERT INTO [dbo].[Owners] ( 
    OwnerTypeTypeID 
    , CarId 
    ) 

VALUES ( 
    @OwnerTypeTypeID 
    , @CarId 
    )  

END