3

我的数据库中的每个表都有一个列,需要为新行计算,但有需要保留的旧值。我有一个使用更新后触发器的工作解决方案,但它的某些内容并不适合我。尤其是对每个表都有这样的触发器的想法。我希望还有其他我忽略的想法。

如果有一种方法可以使用 DEFAULT 列值,我会非常高兴,但这似乎是不可能的。据我所知,DEFAULT 标量函数无法查看插入到行中的其他值。

这是一个示例数据库,用于演示我当前的解决方案。为了方便起见,我把它放在 SQL Fiddle 上:

但这里是重新创建它的代码(以防将来由于任何原因无法访问 SQL Fiddle):

CREATE TABLE tmpTest (
    id INT IDENTITY PRIMARY KEY,
    origin INT DEFAULT 15,
    code VARCHAR(9),
    name VARCHAR(100),
    UNIQUE (code)
)

GO

CREATE TRIGGER tmpTest_code ON tmpTest
AFTER INSERT AS
    UPDATE t SET
      t.code = RIGHT(UPPER(master.dbo.fn_varbintohexstr(t.origin)), 2)
             + RIGHT(UPPER(master.dbo.fn_varbintohexstr(t.id)), 7)
    FROM tmpTest t 
    INNER JOIN inserted i ON i.id = t.id
    WHERE t.code IS NULL

GO

INSERT INTO tmpTest (name) VALUES ('one')
INSERT INTO tmpTest (name) VALUES ('two')
INSERT INTO tmpTest (name) VALUES ('three')
INSERT INTO tmpTest (name) VALUES ('four')
INSERT INTO tmpTest (name) VALUES ('five')
INSERT INTO tmpTest (name) VALUES ('six')
INSERT INTO tmpTest (name) VALUES ('seven')
INSERT INTO tmpTest (name) VALUES ('eight')
INSERT INTO tmpTest (name) VALUES ('nine')
INSERT INTO tmpTest (name) VALUES ('ten')

INSERT INTO tmpTest (origin, code, name) VALUES (3, '030000001', 'legacy one')
INSERT INTO tmpTest (origin, code, name) VALUES (3, '030000002', 'legacy two')
INSERT INTO tmpTest (origin, code, name) VALUES (3, '030000003', 'legacy three')
INSERT INTO tmpTest (origin, code, name) VALUES (3, '030000004', 'legacy four')
INSERT INTO tmpTest (origin, code, name) VALUES (3, '030000005', 'legacy five')
INSERT INTO tmpTest (origin, code, name) VALUES (3, '030000006', 'legacy six')
INSERT INTO tmpTest (origin, code, name) VALUES (3, '030000007', 'legacy seven')
INSERT INTO tmpTest (origin, code, name) VALUES (3, '030000008', 'legacy eight')
INSERT INTO tmpTest (origin, code, name) VALUES (3, '030000009', 'legacy nine')
INSERT INTO tmpTest (origin, code, name) VALUES (3, '03000000A', 'legacy ten')
4

1 回答 1

0

如果对 code 列的要求是UNIQUE,为什么不将其更改为具有默认值,例如,NEWID()同时保留所有当前值?

做你需要的另一种方法是创建另一个列,其值为

ISNULL(code, <formula based on id and origin)

这样,对于现有记录,其值将与代码匹配,而对于代码可能为空的新值,它将与您的新公式匹配。

无论哪种方式,它都应该避免令人不快的触发解决方案,我同意。

最后但同样重要的是,我会使用HASHBYTES而不是fn_varbintohexstr

于 2012-11-20T09:20:06.307 回答