【问题标题】:TSQL Trigger to maintain incremental order integrityTSQL 触发器维护增量订单完整性
【发布时间】:2017-01-07 06:43:04
【问题描述】:

我试图解开 SQL Server 数据库中的触发器。我是一名从事暑期项目的学生,所以我不是这方面的专家,但可以轻松学习。

这是我的数据库表的简化版本,按排名排序:

ID 作为主键

ID   |   RANK
--------------
2    |  NULL
1    |  1
3    |  2
4    |  3
7    |  4

我现在的目标是能够插入/删除/更新排名并在数据库中维护排名的递增顺序,而可用位置中没有任何丢失的数字,并且没有重复。

/* Insert new row */

INSERT INTO TABLE (ID, RANK) VALUES (6, 4)

/* AFTER INSERT */

ID   |   RANK
--------------
2    |  NULL
1    |  1
3    |  2
4    |  3
6    |  4   <- new
7    |  5   <- notice how the rank increased to make room for the new row

我认为在触发器中执行此操作是最有效/最简单的方式;虽然我可能是错的。

作为触发器的替代方案,我制作了一个临时解决方案,当任何等级发生变化时,它使用前端代码在每一行上运行更新。

如果您知道触发器如何或是否可以做到这一点,请分享。

编辑:添加场景 被插入的排名将始终采用其分配的编号。大于或等于插入的所有内容都会增加。

导致触发的排名将始终优先声明其编号,而其他所有内容的排名都会增加以适应。

如果排名是最高数字,则触发器将确保该数字是最大值的 +1。

【问题讨论】:

  • 那将是一个增加。身份证正好是为了?如果插入是 (2, 5) 怎么办?
  • 这会影响你的桌子的性能。
  • 尝试将 RANK 列设为计算列
  • @KamranFarzami 同意了。但是对于规模,并非所有行都有排名,最多只有 100 个排名。其他所有内容都将为空。
  • @KamranFarzami 计算字段来自什么?我不确定它是否适用于空等级。

标签: sql-server database tsql triggers sql-server-2012


【解决方案1】:

这可能对你有用。告诉我。

DROP TABLE dbo.test

CREATE  TABLE dbo.test (id int, ranke int)

INSERT INTO test VALUES (2, NULL)
INSERT INTO test VALUES (1, 1)
INSERT INTO test VALUES (3, 2)
INSERT INTO test VALUES (4, 3)
INSERT INTO test VALUES (7, 4)

GO

CREATE TRIGGER t_test 
ON test
AFTER INSERT
AS
UPDATE test set ranke += 1 WHERE ranke >= (select max(ranke) from inserted) and id <> (select max(id) from inserted)

GO

INSERT INTO test values (6,4)
INSERT INTO test values (12,NULL)

SELECT * FROM test

【讨论】:

  • 我认为这不能正确处理inserted中有多行的情况。
  • 不,绝对不会处理插入多于一行。你可以在触发器内写一个光标:O
  • 您不需要游标(性能不佳)来处理触发器中的多条记录。例如,您可以创建一个数据集,其中将 ROW_NUMBER 函数添加到前一个 MAX id 中,并且可以一次性将它们全部插入。并不是说我认为手动输入排名的整个概念有意义,但请不要使用光标。
  • 我猜是一次插入一个行。特别是考虑到插入的顺序会影响结果。如果你能想出一个基于集合的解决方案来解释插入顺序,我会印象深刻。
猜你喜欢
  • 2018-06-21
  • 1970-01-01
  • 1970-01-01
  • 2019-07-30
  • 1970-01-01
  • 2011-11-26
  • 2011-06-15
  • 1970-01-01
  • 2017-05-27
相关资源
最近更新 更多