批量插入返回无序标识字段

时间:2011-03-05 11:13:03

标签: sql sql-server tsql identity-insert

我有(tableA)有一个标识字段(ID),我需要一次插入多行插入操作,所以我使用表结构作为我的存储过程的传递参数

我需要插入顺序的插入ID,所以我在我的SP中运行以下查询 (tableB与tableA具有相同的结构):

CREATE PROCEDURE ssp_Test
(
    tableA tableAType
)
AS
BEGIN

INSERT INTO tableB(field1, field2, ...)
OUTPUT INSERTED.ID
SELECT field1, field2, ... from tableA

END

如果我用100条记录运行上面的过程,它会返回新的标识字段及其插入到tableB的顺序,但是当我用500条记录运行它时,所有插入的id都没有合理的顺序返回,为什么会发生这种情况呢? / p>

我不需要另外一个临时表将它放在那里并对其进行排序并返回,我只是想知道它为什么会发生并且是否有任何解决方案而不使用额外的临时表进行排序?

4 个答案:

答案 0 :(得分:3)

如果你想要订购的东西,你必须使用ORDER BY子句。试图依赖物理秩序是没有价值的(即使你认为你知道存在一个物理秩序(即由于聚集索引)

答案 1 :(得分:3)

通常,没有 ordered INSERT这样的东西,但SQL Server确实支持一种指定操作分配IDENTITY值的顺序的方法。此保证仅适用于inserted-into表,仅适用于INSERT ... SELECT(不是SELECT INTO),并且没有说明存储引擎实际执行行插入的“顺序”。

如果您需要按特定顺序分配标识值,并按顺序返回生成的标识值,则可以使用带有OUTPUT子句的表变量:


-- New data values
DECLARE @Data
TABLE   (
        some_value BIGINT NOT NULL
        )
;
-- Table to be inserted to
DECLARE @Destination
TABLE   (
        row_id  INTEGER IDENTITY PRIMARY KEY CLUSTERED,
        data    BIGINT NOT NULL
        )
;
-- Table to hold IDs generated
DECLARE @IDs
TABLE   (
        row_id  INTEGER NOT NULL PRIMARY KEY CLUSTERED
        )
;
-- Sample new data values to add to destination
INSERT  @Data
VALUES  (1001), (996), (108), (250), (2000)
;
-- Do the insert, assign identity values
-- in the order of values going in,
-- and save the IDs generated in @IDs
INSERT  @Destination (data)
OUTPUT  inserted.row_id
INTO    @IDs (row_id)
SELECT  D.some_value
FROM    @Data AS D
ORDER   BY
        D.some_value ASC
;
-- Return the IDs in a particular order
SELECT  I.row_id
FROM    @IDs AS I
ORDER   BY
        I.row_id ASC
;

有关详细信息,请参阅:Ordering Guarantees in SQL ServerNo Seatbelt - Expecting Order without ORDER BY

答案 2 :(得分:1)

看看这篇文章: http://technet.microsoft.com/en-us/library/ms177564.aspx

它说: “无法保证更改应用于表的顺序以及将行插入输出表或表变量的顺序将对应。”

我建议在插入后使用select来检索ID。

答案 3 :(得分:0)

要使用数字序列填充列,请使用ROW_NUMBER()(或SQL Server 2012中的序列)。不要试图依赖IDENTITY列,因为它的行为不能总是被控制。