我有一个带有自动递增标识列的表。通常我可以按如下方式插入数据
INSERT INTO [dbo].[table]
DEFAULT VALUES;
SET @value = SCOPE_IDENTITY();
这样我知道我刚刚插入的身份值。但是我需要插入" set"值到该表中。优选地还能够识别刚刚插入的值。我希望有类似于以下的东西是可能的......
INSERT INTO dbo.table DEFAULT VALUES
OUTPUT INSERTED.id INTO @output
SELECT SCOPE_IDENTITY() -- obviously this isn't possible and doesn't actually make sense
FROM @records
WHERE somecolumn IS NULL
我知道我可能需要set identity_insert on
...我不愿意,如果我不必要的话。我也知道也许我也可以使用某种递归CTE,虽然我暂时没有使用其中一种。任何帮助,将不胜感激。
编辑:要清楚我要问的问题是:如何插入" SET"将数据放入具有自动递增标识列的表中。并希望以某种方式识别我刚插入的值。
答案 0 :(得分:1)
INSERT INTO [dbo].[table]
DEFAULT VALUES;
SET @value = SCOPE_IDENTITY();
一个人不“通常”做任何这样的事情。插入一行只包含默认值的行是非常不寻常的(温和)。插入数百或数千行甚至更加可疑。我认为你选择了一条完全没有意义的道路。
但是我们假设你没有失去理智。遗憾的是,您无法使用“默认值”语法(直接或间接)插入多行。但是我们可以使用Gordon和Sachin建议的输出子句(使用计数表逻辑here)将一个“有点”的脚本拼凑在一起(假设)。
set nocount on;
declare @id int;
declare @outputtable table (id int);
create table #x (id int not null identity(1,1), descr varchar(20) null, dd int not null default(2));
insert #x (descr, dd) values ('test', 4), ('zork', 2), (null, 55); -- some extra fluff for demonstartion
insert #x default values;
set @id = SCOPE_IDENTITY();
select @id;
select * from #x order by id;
WITH E00(N) AS (SELECT 1 UNION ALL SELECT 1),
E02(N) AS (SELECT 1 FROM E00 a, E00 b),
E04(N) AS (SELECT 1 FROM E02 a, E02 b),
E08(N) AS (SELECT 1 FROM E04 a, E04 b),
E16(N) AS (SELECT 1 FROM E08 a, E08 b),
E32(N) AS (SELECT 1 FROM E16 a, E16 b),
cteTally(N) AS (SELECT ROW_NUMBER() OVER (ORDER BY N) FROM E32)
insert #x (descr, dd)
output inserted.id into @outputtable(id)
select src.descr, src.dd
from #x as src cross join cteTally
where src.id = @id and cteTally.N < 5;
select x.*
from @outputtable as ids inner join #x as x on ids.id = x.id order by x.id;
if object_id('tempdb..#x') is not null drop table #x;
go
这可能不起作用,具体取决于您的表DDL。我会让你找到这个逻辑中的假设。
答案 1 :(得分:0)
你真的很亲密:
INSERT INTO dbo.table
OUTPUT INSERTED.id INTO @output
DEFAULT VALUES;
SELECT *
FROM @output;
INSERT
将值放入@output
。然后,您可以参考它们。请记住将@output
定义为具有正确类型列的表变量。
Here是其工作的rextester示例。
编辑:
我认为问题是使用@output
,因为您的示例没有正确执行此操作。如果您的表具有单个标识列,那么我不认为SQL Server提供了用于插入多个值的单一查询机制,除非您关闭标识插入。
一个选项是循环:
CREATE TABLE t (id int identity);
DECLARE @output table (id int);
DECLARE @i int = 1;
WHILE @i < 10
BEGIN
INSERT INTO t
OUTPUT INSERTED.id INTO @output
DEFAULT VALUES;
SET @i = @i + 1;
END;
SELECT *
FROM @output;
另一种选择是包含另一列(甚至是假人),这样你就可以插入一些东西了。
最后,也许你根本不需要一张桌子。也许一个序列就足以满足你的目的。
答案 2 :(得分:0)
尝试此查询 -
CREATE TABLE StudentPassMarks (ID INT identity(1, 1))
DECLARE @OutputTable TABLE (ID INT)
INSERT INTO StudentPassMarks
OUTPUT inserted.ID
INTO @OutputTable(ID)
DEFAULT VALUES
SELECT * FROM @OutputTable
Go 20;
SELECT * FROM StudentPassMarks