【问题标题】:Using @@identity or output when inserting into SQL Server view?插入 SQL Server 视图时使用@@identity 或输出?
【发布时间】:2012-07-18 04:54:57
【问题描述】:

(原谅我 - 我是 StackOverflow 和 SQL 的新手) Tl;dr - 当使用@@identity(或任何其他选项,如 scope_identity 或输出变量)时,是否也可以使用视图?下面是一个使用@@identity的存储过程示例:

--SNIP--
DECLARE @AID INT
DECLARE @BID INT


INSERT INTO dbo.A (oct1)
VALUES
(@oct1)

SELECT @AID = @@IDENTITY;

INSERT INTO dbo.B (duo1)
VALUES
(@duo2)

SELECT @BID = @@IDENTITY

INSERT INTO dbo.tblAB (AID, BID)
VALUES
(@AID, @BID)
GO

更长:

插入表时,您可以使用@@identity 捕获标识种子的当前值。如果您想插入表 A 和 B,捕获标识值,然后插入与 A 和 B 相关的表 AB,这很有用。显然这是为了数据规范化。

假设您要使用一些对表执行内部联接的数据库架构进行抽象,以使数据更易于使用。在这种情况下,您将如何正确填充交叉引用表?是否可以以同样的方式完成,如果可以,如何?

【问题讨论】:

  • 最好避免使用@@identiy 或Scope_identity()。有一个与之相关的讨厌的错误 - vadivel.blogspot.in/2012/02/…
  • 您还有哪些其他选择?我已经编辑了问题以包含其他选项的选项:)
  • 使用 INSERT 的 OUTPUT 子句获取您要查找的值。示例可以在这里找到 - support.microsoft.com/kb/2019779
  • @vmvadivel - 说完全避免使用它们似乎有些危言耸听。该问题仅出现在并行计划中,我无法想象 OP 中的查询将获得并行计划。
  • @MartinSmith 是的,我同意。在我之前的评论中提供的链接中,我提到“如果您的系统使用并行计划,请避免使用 SCOPE_IDENTITY() 和 @@IDENTITY 函数。”。但是在发布答案时忘记提及它。现在改了。

标签: sql-server view identity seed


【解决方案1】:

如果您的系统正在使用并行计划,请避免使用 @@IDENTITY 或 SCOPE_IDENTITY(),因为存在严重的错误。请参考—— http://connect.microsoft.com/SQL/feedback/ViewFeedback.aspx?FeedbackID=328811

获取插入的身份 ID 的更好方法是使用 OUTPUT 子句。

CREATE TABLE tblTest
(         
    Sno         INT IDENTITY(1,1) NOT NULL,         
    FirstName   VARCHAR(20) 
)  

DECLARE @pk TABLE (ID INT)  

INSERT INTO tblTest(FirstName) 
OUTPUT INSERTED.Sno INTO @pk
SELECT 'sample' 

SELECT * FROM @pk 

编辑:

它也适用于视图。请参阅下面的示例。希望这就是你要找的。

CREATE VIEW v1
AS
SELECT sno, firstname FROM tbltest
GO

DECLARE @pk TABLE (ID INT)  

INSERT INTO v1(FirstName) 
OUTPUT INSERTED.Sno INTO @pk
SELECT 'sample' 

SELECT ID FROM @pk

【讨论】:

  • 但这会从视图而不是表中工作吗?想象一下,如果您有三个表 A、B 和一个交叉引用 AB。您的视图将根据 AB 的交叉引用将 A 连接到 B。如果您插入到视图中,因此插入到两个基础表中,这仍然适用吗?
  • 谢谢你!最后一个问题,如果您看到这个 - 如果您正在查看连接在一起的多个表(内部连接)怎么办?在这种情况下输出仍然有效吗?
【解决方案2】:

@@IDENTITY 返回在连接上生成的最后一个 IDENTITY 值,与生成该值的表无关,也与生成该值的语句的范围无关。

SCOPE_IDENTITY() 返回在连接上和同一范围内的语句生成的最后一个 IDENTITY 值,而与生成该值的表无关。 SCOPE_IDENTITY() 和@@IDENTITY 一样,会返回当前会话中创建的最后一个身份值,但也会将其限制在您当前的范围内

虽然 microsoft 解决了其中任何一个的问题,但我建议您应该使用“OUTPUT”,是的,它也可以与视图一起使用

【讨论】:

  • 感谢您的帮助!这也很有帮助。
猜你喜欢
  • 2016-08-30
  • 2021-12-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多