【发布时间】:2020-03-30 06:44:16
【问题描述】:
我有一个非常有趣的问题。我正在尝试根据“ID”(主键字段)的值生成“名称”字段的值。
例如,
'ID' 是 142
“名称”将为 19142。“19”表示当前年份。
为此,我编写了以下触发器(效果很好):
CREATE TRIGGER [dbo].[GenerateTheName]
ON [dbo].[Table1]
AFTER INSERT
AS
BEGIN
UPDATE [dbo].[Table1]
SET [Name] = (SELECT FORMAT(GETDATE(),'yy')) +
(SELECT CAST(FORMAT([ID],'000','en-US') AS VARCHAR(4)) FROM inserted)
WHERE ID = (Select [id] FROM inserted)
END
现在,当年份发生变化时,'Name' 字段值中的 id 部分需要从零重新开始,而实际 ID 应遵循标识并像往常一样加 1。
所以如果 2019 年的最后一条记录 ID=164,那么 2020 年的第一条记录应该是:
ID:165 姓名:20001
实现此目的的一种方法是创建一个新表“table2”并在其中存储(通过触发器)当前年份(2019 年)的“ID”的最后一个值。那么2020年整个明年,这个记录的数据都可以作为参考。
所以,如果 2020 年的第一条记录的 ID 为:165 在“table1”中插入新记录后,另一个触发器将从“ID”的值中减去 table2 中的唯一值 (164)。
165-164=1
166-164=2
167-164=3
....
当 2020 年也结束时,“table2”中的这条唯一记录将被删除,并再次将 2020 年的最后一个 id 存储在其中。
这是解决问题的正确方法吗?请建议我解决它的可能方法。
提前致谢。
【问题讨论】:
-
您正在使用
inserted伪表,就好像只包含一条记录一样。但事实并非如此。如果多行受到影响,inserted也将包含尽可能多的行,您的触发器将失败。 -
我将它与在线门户一起使用,每条记录都通过 GUI 插入。没有批量插入记录。
-
在 DBMS 之外做什么并不重要。 DBMS 能够一次插入多条记录。因此触发器坏了。也许有一天你会在你的外部程序中进行更改或将另一个程序附加到数据库中,这允许一次生成多个记录并且你突然遇到了错误。永远不要说“客户端过滤它,所以可以忽略服务器端的问题。”。
-
好的,感谢您指出这个问题。您能否建议一种方法来解决这种情况,而不是使用插入的?
-
这不是问题,你使用
inserted,是你如何使用它的问题。这是一套,所以你必须像对待一套一样对待它。而不是有一个UPDATE和WHERE ID = (Select [id] FROM inserted),当inserted中有不止一行时会中断,您需要做一个连接inserted的UPDATE,以便它也适用于其中的多行。
标签: sql sql-server database triggers auto-generate