在SQL中避免两步插入

时间:2011-10-13 19:02:45

标签: sql sql-server database tsql

假设我的表格定义如下:

CREATE TABLE SomeTable
(
P_Id int PRIMARY KEY IDENTITY,
CompoundKey varchar(255) NOT NULL,
)

CompoundKey是一个字符串,其主键P_Id连接到末尾,如Foo00000001,来自“Foo”+ 00000001.此时,插入此表的条目分两步进行。

  1. 为CompoundKey插入带有占位符字符串的虚拟记录。
  2. 使用生成的复合键更新CompoundKey。
  3. 我正在寻找一种完全避免第二次更新的方法,并使用一个insert语句完成所有操作。这可能吗?我正在使用MS SQL Server 2005。

    P.S。我同意这不是世界上最明智的架构,这个架构将被重构(并且正确规范化)但我现在无法对架构进行更改。

4 个答案:

答案 0 :(得分:5)

您可以使用计算列;将架构更改为:

CREATE TABLE SomeTable
(
P_Id int PRIMARY KEY IDENTITY,
CompoundKeyPrefix varchar(255) NOT NULL,
CompoundKey AS CompoundKeyPrefix + CAST(P_Id AS VARCHAR(10))
)

这样,SQL Server将自动为您提供新列中的复合键,并自动为您维护。您可能还需要查看计算列的PERSIST关键字,这将导致SQL Server实现数据文件中的值,而不必动态计算它。您也可以根据需要为该列添加索引。

答案 1 :(得分:1)

trigger很容易实现这个

答案 2 :(得分:1)

这根本不可能。
“下一个ID”不会存在,因此在插入行之前无法读取UPDATE

现在,如果您从其他地方采购自动编号,但我认为这不是您问题的良好答案。

即使你想使用触发器,即使没有手动执行它,仍会执行UPDATE。 您可以隐藏 CompoundKey的数量,但在一天结束时它仍然是UPDATE

我认为您最安全的做法是确保UPDATEINSERT处于同一交易中或使用触发器。但是,对于它的学术论证,UPDATE仍然存在。

答案 3 :(得分:1)

两件事:

1)如果您最终使用两个插入,则必须使用事务!否则,其他进程可能会看到数据库处于不一致状态(即看到没有CompoundKey的记录)。

2)我不会尝试在事务,触发器等中将Id粘贴到CompoundKey的末尾。如果需要,可以在输出处执行它更清晰,例如在查询中(select concat(CompoundKey, Id) as CompoundKeyId ...)。如果您需要它作为其他表中的外键,只需使用该对(CompoundKey,Id)。