SQL Server:将数据集插入带有标识列的表中

时间:2017-06-08 01:25:08

标签: sql sql-server

我有一个带有自动递增标识列的表。通常我可以按如下方式插入数据

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"将数据放入具有自动递增标识列的表中。并希望以某种方式识别我刚插入的值。

3 个答案:

答案 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