SQL Server - 如何在多行INSERT事务中手动增加PK

时间:2017-02-02 21:53:15

标签: sql-server

我在SQL Server中工作。我有一个具有PK int列的表。此列没有启用自动增量,我不允许更改架构。我需要手动将大量行(可能是数千行)插入此表中。插入的数据都不会来自任何现有表。但是,我需要确保每列新行的PK列增加+1。我目前的脚本如下:

BEGIN TRAN
    INSERT INTO DB1.dbo.table1
    (PK_col, col1)
    VALUES
    (10, 'a')
    ,(11, 'something')
    ,(12, 'more text')
    ;

我通过预查询(SELECT MAX(PK_col) + 1)知道PK_col当前是9。

我的问题是确保每列新行的PK列增加+1。因为可能要插入数千行,所以我希望减少跳过值或抛出PK约束违规的可能性。我知道只要在运行SQL脚本之前验证PK值,我就可以在DB之外(通过Excel)实现这一点。但是,我想创建一个解决方案来处理TRAN语句本身的自动增量。这是否可能(没有遇到竞争条件)?如果是这样,怎么样?

2 个答案:

答案 0 :(得分:1)

以下应该做你想做的事:

INSERT INTO DB1.dbo.table1(PK_col, col1)
    SELECT COALESCE(l.max_pk_col, 0) + row_number() over (order by (select null)) as PK_col,
           col1
    FROM (VALUES ('a'), ('something'), ('more text')) v(col1) CROSS JOIN
         (SELECT MAX(pk_col) as max_pk_col FROM DB1.dbo.table1) l;

你需要小心这种安排。在INSERT期间锁定整个表可能是一个好主意 - 如果还有其他任何东西可以更新表。

答案 1 :(得分:0)

执行此操作的一种方法是创建一个带有标识列和数据列的新临时表,执行插入操作,然后将此表的内容插回到所需的原始表中。然后清理它

BEGIN TRAN

DECLARE @initialIndex INT

SELECT @initialIndex = MAX(PK_col) + 1)
FROM DB1.dbo.table1

CREATE TABLE #tempData(
  PK_col INT IDENTITY(@initialIndex, 1),
  col1 VARCHAR(MAX)
)

INSERT INTO #tempData (col1)
VALUES
('a')
,('something')
,('more text')

INSERT INTO DB1.dbo.table1
SELECT PK_col, col1
FROM #tempData

DROP TABLE #tempData