Seb*_*ine 10
我假设这个问题是关于如何将一堆行更新为更高的值而不相互踩踏。如果您将第一行中的 id=1 更新为 id=2,而第二行(id=2)仍然存在,您将得到主键违规,因为现在您有两行 id=2。
为了防止这种类型的碰撞,您只需要从最大值开始并将其增加一。这为第二大值开辟了一个缺口,而这又为第三大值开辟了一个缺口,依此类推。
然而,在 SQL Server 中,您不必担心,因为引擎会自动处理:
MS SQL Server 2008 架构设置:
CREATE TABLE dbo.Employee(Id INT PRIMARY KEY CLUSTERED, Name NVARCHAR(MAX));
INSERT INTO dbo.Employee(Id,Name)
VALUES(1,'John'),(2,'Jane'),(3,'Max');
Run Code Online (Sandbox Code Playgroud)
查询 1:
SELECT * FROM dbo.Employee;
Run Code Online (Sandbox Code Playgroud)
结果:
| ID | NAME |
|----|------|
| 1 | John |
| 2 | Jane |
| 3 | Max |
Run Code Online (Sandbox Code Playgroud)
查询 2:
UPDATE dbo.Employee
SET Id = Id + 1;
Run Code Online (Sandbox Code Playgroud)
查询 3:
SELECT * FROM dbo.Employee;
Run Code Online (Sandbox Code Playgroud)
结果:
| ID | NAME |
|----|------|
| 2 | John |
| 3 | Jane |
| 4 | Max |
Run Code Online (Sandbox Code Playgroud)
查询 4:
UPDATE dbo.Employee
SET Id = Id - 1;
Run Code Online (Sandbox Code Playgroud)
查询 5:
SELECT * FROM dbo.Employee;
Run Code Online (Sandbox Code Playgroud)
结果:
| ID | NAME |
|----|------|
| 1 | John |
| 2 | Jane |
| 3 | Max |
Run Code Online (Sandbox Code Playgroud)
如果你真的按照SQL Fiddle链接,你还可以看到两个更新语句的执行计划。第一个看起来像这样:
在那里,您可以在左侧相当远的地方看到一个Table Spool
操作员。该运算符基本上创建了所有行的副本,这些行在被旁边的实际“聚集索引更新”运算符写回之前已更新。因此,SQL Server 能够处理“重叠”更新而不会被自身绊倒。
一个额外的好处(以及实施此行为的最初原因)是这两个步骤的方法提供了万圣节保护。
如果没有关于数据库结构的更多详细信息,这里有大量变量。
如果任何其他包含员工 ID 的表作为对该表的引用,并且外键被正确设置并设置为,那么ON UPDATE CASCADE
只需执行UPDATE EmployeeTable SET EmployeeID = EmployeeID + 1
即可完成任务 - FK 关系将根据需要更新其他所有内容。如果没有ON UPDATE CASCADE
这种情况,您将收到错误并且语句将失败。
如果您有引用员工 ID 且不存在外键约束的表,那么您也必须使用 来更新这些表UPDATE AnotherTable SET EmployeeID = EmployeeID + 1
。您应该将所有表更新包装在单个事务中(使用错误处理来确保事务回滚,或者SET XACT_ABORT ON
如果您不需要对该过程进行任何更精细的控制)以保持一致性(因此,如果出现故障,则所有内容都会回滚)后退)。
我想问你为什么要这样做。员工标识符通常是一个代理键(也称为伪键),除了识别给定人员之外没有任何意义(它很可能是 UUID 而不是数字,除了它可能用于现实世界中的书面形式之外)下来,所以 UUID 不太方便)。有关于此的更多讨论,请参阅 SQL Antipatterns 中的“psuedo-key clean-freak”一章。
归档时间: |
|
查看次数: |
3349 次 |
最近记录: |