0

我有两张桌子: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插入到 FK 中。TableB

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

有人可以告诉我一个更有效的方法吗?也许在存储过程中使用 scope_identity()?触发器不起作用,因为我需要在我的 C# 中返回新的 PK,因此我可以在插入TableB. 另外,我想在运行时锁定两个表。

谢谢你,罗伯特

4

3 回答 3

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 子句

Insert TableA( ... )
    Output Inserted.TableAId, @TableBCol1, @TableBCol2, ...
    Into TableB
Values( ... )
于 2012-06-26T04:25:26.127 回答
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 
于 2012-06-26T14:43:16.967 回答
0

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

DECLARE @id INT

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

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

如果您使用的是原始 ADO,则设置@id为 OUTPUT 参数并在第二个 DB 调用中使用返回值。有关如何使用输出参数的示例,请参阅此处。

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

于 2012-06-26T04:24:29.420 回答