Ode*_*ded 1056 sql t-sql sql-server
IDENTITY
插入行的最佳方法是什么?
我知道@@IDENTITY
和IDENT_CURRENT
和SCOPE_IDENTITY
,但不明白连接到每个利弊.
有人可以解释一下这些差异,以及何时应该使用它们?
bdu*_*kes 1363
@@IDENTITY
返回在所有范围内为当前会话中的任何表生成的最后一个标识值. 你需要在这里小心,因为它跨越范围.您可以从触发器获取值,而不是当前语句.
SCOPE_IDENTITY()
返回为当前会话中的任何表和当前范围生成的最后一个标识值. 一般你想要使用什么.
IDENT_CURRENT('tableName')
返回在任何会话和任何范围内为特定表生成的最后一个标识值.这使您可以指定您想要该值的表,以防上述两个不是您需要的(非常罕见).此外,正如@ Guy Starbuck所提到的,"如果你想获得未插入记录的表的当前IDENTITY值,你可以使用它."
该OUTPUT
条款的的INSERT
声明将让您访问每一个经该语句插入行.由于它的范围是特定的声明,因此它比上面的其他函数更直接.但是,它更冗长(您需要插入表变量/临时表然后查询),即使在回滚语句的错误情况下,它也会给出结果.也就是说,如果您的查询使用并行执行计划,这是获取身份的唯一保证方法(不能关闭并行性).但是,它在触发器之前执行,不能用于返回触发器生成的值.
Orr*_*rry 171
我相信检索插入的id的最安全和最准确的方法是使用输出子句.
例如(摘自以下MSDN文章)
USE AdventureWorks2008R2;
GO
DECLARE @MyTableVar table( NewScrapReasonID smallint,
Name varchar(50),
ModifiedDate datetime);
INSERT Production.ScrapReason
OUTPUT INSERTED.ScrapReasonID, INSERTED.Name, INSERTED.ModifiedDate
INTO @MyTableVar
VALUES (N'Operator error', GETDATE());
--Display the result set of the table variable.
SELECT NewScrapReasonID, Name, ModifiedDate FROM @MyTableVar;
--Display the result set of the table.
SELECT ScrapReasonID, Name, ModifiedDate
FROM Production.ScrapReason;
GO
Run Code Online (Sandbox Code Playgroud)
Ori*_*rds 104
我说的和其他人一样,所以每个人都是对的,我只是想让它更清楚.
@@IDENTITY
返回客户端连接到数据库的最后一个东西的id.
大部分时间这种方法都可以正常工作,但有时触发器会插入一个你不知道的新行,你将从这个新行中获取ID,而不是你想要的那个
SCOPE_IDENTITY()
解决了这个问题.它返回您在发送到数据库的SQL代码中插入的最后一个内容的id .如果触发器去创建额外的行,它们将不会导致返回错误的值.万岁
IDENT_CURRENT
返回任何人插入的最后一个ID.如果某个其他应用程序恰好在不合适的时间插入另一行,您将获得该行的ID而不是您的ID.
如果您想安全地玩,请始终使用SCOPE_IDENTITY()
.如果您坚持使用@@IDENTITY
并且有人决定稍后添加触发器,则所有代码都将中断.
Ian*_*emp 63
获取新插入行的标识的最佳(读取:最安全)方法是使用以下output
子句:
create table TableWithIdentity
( IdentityColumnName int identity(1, 1) not null primary key,
... )
-- type of this table's column must match the type of the
-- identity column of the table you'll be inserting into
declare @IdentityOutput table ( ID int )
insert TableWithIdentity
( ... )
output inserted.IdentityColumnName into @IdentityOutput
values
( ... )
select @IdentityValue = (select ID from @IdentityOutput)
Run Code Online (Sandbox Code Playgroud)
小智 23
加
SELECT CAST(scope_identity() AS int);
Run Code Online (Sandbox Code Playgroud)
到插入sql语句的末尾,然后
NewId = command.ExecuteScalar()
Run Code Online (Sandbox Code Playgroud)
将检索它.
Ian*_*oyd 15
使用Entity Framework时,它在内部使用该OUTPUT
技术返回新插入的ID值
DECLARE @generated_keys table([Id] uniqueidentifier)
INSERT INTO TurboEncabulators(StatorSlots)
OUTPUT inserted.TurboEncabulatorID INTO @generated_keys
VALUES('Malleable logarithmic casing');
SELECT t.[TurboEncabulatorID ]
FROM @generated_keys AS g
JOIN dbo.TurboEncabulators AS t
ON g.Id = t.TurboEncabulatorID
WHERE @@ROWCOUNT > 0
Run Code Online (Sandbox Code Playgroud)
输出结果存储在临时表变量中,连接回表,并将行值返回表中.
注意:我不知道为什么EF会将短暂的表连接回真实表(在什么情况下两者不匹配).
但这就是EF所做的.
此技术(OUTPUT
)仅适用于SQL Server 2008或更高版本.
Jak*_*urc 14
@@ IDENTITY,SCOPE_IDENTITY和IDENT_CURRENT是类似的函数,因为它们返回插入表的IDENTITY列的最后一个值.
@@ IDENTITY和SCOPE_IDENTITY将返回当前会话中任何表中生成的最后一个标识值.但是,SCOPE_IDENTITY仅在当前范围内返回值; @@ IDENTITY不限于特定范围.
IDENT_CURRENT不受范围和会话的限制; 它仅限于指定的表格.IDENT_CURRENT返回在任何会话和任何范围内为特定表生成的标识值.有关更多信息,请参阅IDENT_CURRENT.
Guy*_*uck 13
@@ IDENTITY是使用当前SQL连接插入的最后一个标识.这是从插入存储过程返回的一个很好的值,您只需要为新记录插入标识,并且不关心以后是否添加了更多行.
SCOPE_IDENTITY是使用当前SQL连接插入的最后一个标识,并且在当前范围内 - 也就是说,如果在插入后基于触发器插入了第二个IDENTITY,则它不会反映在SCOPE_IDENTITY中,只会反映您执行的插入.坦率地说,我从来没有理由使用它.
无论连接或范围如何,IDENT_CURRENT(tablename)都是插入的最后一个标识.如果要获取尚未插入记录的表的当前IDENTITY值,可以使用此方法.
Mar*_*ese 12
我无法与其他版本的SQL Server通信,但在2012年,直接输出工作正常.您不需要打扰临时表.
INSERT INTO MyTable
OUTPUT INSERTED.ID
VALUES (...)
Run Code Online (Sandbox Code Playgroud)
顺便说一下,这种技术在插入多行时也有效.
INSERT INTO MyTable
OUTPUT INSERTED.ID
VALUES
(...),
(...),
(...)
Run Code Online (Sandbox Code Playgroud)
产量
ID
2
3
4
Run Code Online (Sandbox Code Playgroud)
总是使用scope_identity(),不需要任何其他东西.
归档时间: |
|
查看次数: |
797560 次 |
最近记录: |