2012-06-21 56 views
1

早上好。我有两张桌子,一张是另一张。当我插入到主表中时,主键是自动生成的,即标识字段。我需要将这个值插入到第二个表中。将标识列值插入另一个表中

我发现使用OUTPUT子句会给我刚才插入的身份值,所以我试了这个。

insert into owners (pId) 
    insert into personal (firstName) 
    output inserted.pId 
    values ('fn') 

虽然不起作用。我得到一个错误:

Incorrect syntax near the keyword 'insert'

个人表是主表,所有者表包含外键。 如何在SQL Server中执行所需的操作?

我卡住了,在这里对过去两天...

+0

你可以发布这两个表的结构吗? –

+0

你想让我发布整个结构,还是只有相应的字段? –

回答

3

尝试以下步骤

1)上的插入

2应用事务级别)获取上次使用SCOPE_IDENTITY()函数插入ID。

当您应用事务级别时,它将锁定您的表,并且其他/同一用户此时无法插入值。

试试这个,它会为你工作。

+0

你可以解释事务级别?我相信我明确地锁定了这些故事,但我想知道这是否容易出错...... –

+0

当您应用事务级别时,它会锁定您在此事务中使用的表,并在完成后释放表锁交易。在事务期间,其他请求将由Sql服务器排队,并且在完成此事务之后,其他请求将完成。 我建议你必须使用事务级别,即Begin Trans .......在代码中提交Trans,这将避免任何其他用户在同一时间执行插入。谢谢 – Asif

+0

交易是否确实锁定了涉及的表格?我的意思是,不会是一个真正的性能瓶颈? –

2

可以使用SCOPE_IDENTITY()函数返回插入的标识值。

DECLARE @id INT 
INSERT INTO [Personal] (Colums ....) VALUES (this, that, stuff) 
SET @id = SCOPE_IDENTITY() 

INSERT INTO [Owners] (Colums ....) VALUES (@id ....) 
+0

我知道SCOPE_IDENTITY给出了给定范围内的最后插入的标识,但不一定在给定的表上......应用程序托管在网络上,并且多个用户的行为不会给我准确的结果。例如,在我更新表**个人**之后,其他/相同的用户可以在插入到**所有者**之前更新其他表。然后,SCOPE_IDENTITY将给我最新的身份值,但不会从个人表中。 还是我错了? –

+0

对不起,我不确定我是否理解你在说什么,你能澄清你的问题吗? – Kane

+0

不同的用户有不同的范围。所以SCOPE_IDENTITY()将从同一范围返回标识。你永远不会有这种冲突,你提到 – Rab

2

我觉得你的选择是使用SCOPE_IDENTITY()但对方最接近你的选择是IDENT_CURRENT(‘tablename’),所以我想,我张贴的其他身份选项的详细细节,以及它可能会帮助你了解你的选择和力量有帮助其他时间

@@IDENTITY It returns the last IDENTITY value produced on a connection, regardless of the table that produced the value, and regardless of the scope of the statement that produced the value.


SCOPE_IDENTITY() It returns the last IDENTITY value produced on a connection and by a statement in the same scope, regardless of the table that produced the value.


IDENT_CURRENT(‘tablename’) It returns the last IDENTITY value produced in a table, regardless of the connection that created the value, and regardless of the scope of the statement that produced the value.

+0

我认为所有三个都不会做...问题是,多个用户将从不同的范围工作在不同的表上。我需要找到我刚插入的给定元组的标识值。请注意** I **和**给出的元组**。我的意思是我不能从其他表的结果或范围干扰... –

3

由于OUTPUT条款不能直接使用,因为外键,您可以添加生成的ID到一个临时表,然后将这些值到owners表:

BEGIN TRANSACTION 

CREATE TABLE #ids(ID INT) 
INSERT INTO personal(firstName) 
    OUTPUT inserted.pid INTO #ids 
    SELECT 'A' 
    UNION SELECT 'B' 

INSERT INTO owners(pid) 
    SELECT ID FROM #ids 

COMMIT TRANSACTION 

SCOPE_IDENTITY也可以工作,但它的限于一个值。

+0

什么是一个临时表的生命期和范围?我的意思是,可以用其他类似的语句,但用不同的范围插入iy? –

+0

本地临时表仅适用于当前连接。您可以拥有全局临时表(标有'##'),它们可用于所有连接。请参阅[MSDN](http://msdn.microsoft.com/zh-cn/library/ms190315.aspx)。 –

4

我认为你的语法稍微偏离了一点 - 你可以确定将值插入主表中,并使用OUTPUT子句将其插入辅助表中。

INSERT INTO dbo.personal(firstName) 
OUTPUT INSERTED.pId INTO dbo.owners(pId) 
VALUES('fn') 

这将插入新行personalfirstName设置列fn。然后插入的行的标识列pId被插入到另一个表owners中,作为该表的pId列。

有关更多详细信息,请参阅MSDN documentation on the OUTPUT clause - 您可以将任何插入的值输出到控制台(例如SQL Server Mgmt Studio),也可以将这些值输出到临时或永久表中。

更新:为“dradu”所指出的那样 - 这种做法不会在你的情况在这里工作,因为在owners表中的列是一个FK约束的一部分(我错过了这一点从你的问题) 。所以你需要使用一些其他的方式来做到这一点 - 可能输出的必要信息到一个临时表/表变量在你的代码

+1

我不认为'OUTPUT'子句会直接工作,因为'owner'表参与外键约束。从[MSDN链接](http://msdn.microsoft.com/zh-cn/library/ms177564.aspx)您提到: output_table不能:已启用在其上定义的触发器;参与FOREIGN KEY约束的任何一方;有CHECK约束或启用的规则。 –

+0

@marc_s不,所有者表不包含字段pId。我需要这个自动更新,并且其他值,我自己插入。 –

+0

@Anudeep Bulla:所以你开始时使用了错误的SQL语句,你在某些条件下得到了正确的答案,但是你对他们不满意,因为它们在某些你没有指定的情况下不起作用。也许你应该让问题更清楚,或者想出你真正想达到的目标。提取有关您的问题的信息不是社区工作。 –

相关问题