我在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语句本身的自动增量。这是否可能(没有遇到竞争条件)?如果是这样,怎么样?
答案 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