有没有更好的方法一次插入相关表?

时间:2012-01-25 02:54:31

标签: sql-server

多年以来我一直在研究如何插入相关表格。我总是通过编写存储过程来完成它,但在过去8年左右的时间里,我从未尝试过看看是否有更好的方法。我想知道是否有更好的方法可能是一个连接插入。

所以说我有这两张桌子。

[用户]

UserID (Identity, Primary Key)
Name
UserExtendedPropertyID (Foreign Key, Indexed)

[UserExtendedProperty]

UserExtendedPropertyID (Identity, Primary Key)
Address
Phone

说我想插入一个新用户。我传统上会编写一个存储过程,它会执行以下操作:

insert into UserExtendedPropertyID (Address, Phone) values('123 Fake St.', '867-5309')
set @myidentity = select @@identity
insert into Users (Name, UserExtendedPoerpertyID) values('John Doe', @myidentity)

总觉得应该有一个查询可以让我做一个连接插入,但我从来没有找到过这样的东西。

1 个答案:

答案 0 :(得分:0)

我同意Oleg Dok的回应。除此之外,我想指出现有脚本可能存在的问题。

建议使用@@ Identity或SCOPE_IDENTITY()而不包括

OPTION (MAXDOP 1)

请检查此http://connect.microsoft.com/SQL/feedback/ViewFeedback.aspx?FeedbackID=328811

从以上链接中摘录:

  

微软于2008年3月18日下午1:10发布

     戴夫,感谢你能够提供的非常详细和愚蠢的报告   找到问题。 是的,这是一个错误 - 只要是并行查询计划   生成的@@ IDENTITY和SCOPE_IDENTITY()未更新   一致而且不能依赖。我可以提供的一些解决方法   你现在:

     
      
  1. 使用MAX_DOP = 1,因为您已经在使用。这可能会损害查询的SELECT部分​​的性能。
  2.   
  3. 将SELECT部分​​的值读入一组变量(或单个tabel变量),然后使用MAX_DOP = 1插入目标表。   由于INSERT计划不会平行,您将获得正确的权利   语义,但你的SELECT将并行实现性能   如果你真的需要它。
  4.   
  5. 使用INSERT的OUTPUT子句获取您要查找的值,如下面的示例所示。事实上,我非常推荐   在所有情况下都使用OUTPUT而不是@@ IDENTITY。这是最好的   方式是阅读身份和时间戳。
  6.   
  7. 更改自动停止不是一个好的解决方法。它可能会暂时隐藏问题,但最终会产生一个平行的计划。
  8.   
  9. 通过sp_configure“max degree of parallelism”选项强制整个服务器的串行计划。
  10.   
相关问题