只有在插入触发后才能实现半计算列?

时间:2012-10-10 22:47:59

标签: sql-server

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

如果有一种方法可以使用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')

1 个答案:

答案 0 :(得分:0)

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

执行所需操作的另一种方法是创建另一个值为

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

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

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

最后但并非最不重要的是,我会使用HASHBYTES代替fn_varbintohexstr