C# 在表中插入数据之前,是否可以获取Id(IDENTITY)的新值?

C# 在表中插入数据之前,是否可以获取Id(IDENTITY)的新值?,c#,sql,sql-server,foreign-keys,identity,C#,Sql,Sql Server,Foreign Keys,Identity,在表中插入数据之前,是否可以获取Id(IDENTITY)的新值 可以这样写: INSERT INTO Table1 SELECT *GET_NEW_IDENTITY*, Field1, Field2 FROM Table2 我需要Id的值,因为我想在表1中插入数据,然后在另一个表中插入数据,该表有一个外键链接到表1(带Id)否,因为添加一行会创建新的标识值 做你想做的事 SELECT newid = @@identity FROM table 就在插入之后为什么在执行插入之前需要获取标识值?

在表中插入数据之前,是否可以获取Id(IDENTITY)的新值

可以这样写:

INSERT INTO Table1
SELECT *GET_NEW_IDENTITY*, Field1, Field2 FROM Table2

我需要Id的值,因为我想在表1中插入数据,然后在另一个表中插入数据,该表有一个外键链接到表1(带Id)

否,因为添加一行会创建新的标识值

做你想做的事

SELECT newid = @@identity FROM table

就在插入之后

为什么在执行插入之前需要获取标识值?只需执行表2的插入返回,然后使用结果Id值插入表1。

IDENT\u CURRENT
。返回为指定表或视图生成的最后一个标识值。最后生成的标识值可以用于任何会话和任何作用域

SCOPE\u IDENTITY
。返回插入到同一范围内标识列中的最后一个标识值。作用域是一个模块:存储过程、触发器、函数或批处理


输出
。从受INSERT、UPDATE、DELETE或MERGE语句影响的每一行返回信息或基于这些行的表达式。[…]在执行INSERT或UPDATE操作后,OUTPUT子句可能有助于检索identity或computed列的值。

您也可以让INSERT语句返回新插入的值以供以后使用。比如说

create table demo( Id int identity primary key, data varchar(10))
go
insert into demo(data) output inserted.Id values('something')

这只是一个快速的演示。您可以使用新ID进行插入更新、插入到另一个表中、以另一种方式进行查询等。希望我在格式化、编辑文章时不会在脚本中插入错误

-- run [1] before this script once to have environment

--create temporary table once if not dropped after 
-- really only ID field is needed, the others are for illustration
create table #temp_id (Id int, d1 int, d2 int)

select * from Table2;-- this is read-only, filled once here source  
select * from Table1;--interesting for following runs 

insert into Table1 
  OUTPUT INSERTED.id 
  -- really only ID is needed, the rest is for illustration
    , inserted.d1, inserted.d2 INTO #temp_id   
select field1, field2,  null-- null to be merged later
-- or inserted/updated into another table 
  from Table2;

select * from Table1; 
select * from #temp_id; 


MERGE Table1 AS TARGET 
   USING #temp_id AS SOURCE
      ON (TARGET.id = SOURCE.id) 
   WHEN MATCHED 
 --AND OR  are redundant if Table1.ID is PK    
   THEN 
     UPDATE SET TARGET.IDnew = SOURCE.id;


select * from Table1;


--drop table  #temp_id
--drop table  table1
--drop table  table2

[1]
从问题中复制表格并填入数据

create table Table1( Id int identity primary key, d1 int, d2 int, IDnew int)
create table Table2( field1 int, field2 int)
insert into table2 values(111,222)
insert into table2 values(333,444)
IDENT_CURRENT('tableName')返回给定表的标识的当前值。插入时将分配的标识值将是IDENT_CURRENT('tableName')+IDENT_INCR('tableName')


因为我想为perf执行批插入(而不是逐行插入)。在这种情况下,不,您不能这样做。正如@smirkingman在回答中指出的那样,您必须在每次行插入后获得标识。您可以使用Ident_Current来获得标识,但除非您锁定整个表以禁止其他用户执行插入,否则该值对于批插入将不可靠。更好的方法是插入XX个空行或伪行,返回identity insertm使用的pks,然后对这些行执行批更新以将数据放入,而不是批处理Insert@Charles布雷塔纳-说得好,我考虑过这一点,但对于一个可能不符合良好实践的场景来说,这似乎是一个很大的挑战。@AJ,@Patrice批量插入时更好的方法是在
INSERT
语句中使用
OUTPUT
子句(有关更多详细信息,请参阅@Ralph或@Developer Art的答案),在任何情况下都不要为此使用ident_current,如果有多个用户,它将不会返回正确的结果!如果您的版本不支持Output子句,则Output是最佳选择或作用域_identity()。@@identity使用起来非常危险,不能可靠地返回正确的结果。你不应该把它用于这个目的。
SELECT IDENT_CURRENT('tableName') + IDENT_INCR('tableName')