更新视图时在基础 table 中插入不同的值
Insert a different value in underlying table when a view is updated
考虑以下示例,其中我有一个 table 和相应的视图:
Table | View
T_EmailAddress | V_EmailAddress
----------------+----------------
ID INT | ID
Status VARCHAR | Status
Valid INT |
Column1 VARCHAR | Column1
ColumnN VARCHAR | ColumnN
我有一个程序发出以下查询:
UPDATE V_EmailAddress SET Status = 'valid' WHERE ID = 1;
UPDATE V_EmailAddress SET Status = 'invalid' WHERE ID = 2;
是否可以更新基础 table 以便 Status valid
和 invalid
存储为 1
和 0
在 Valid 列 table.
请注意,我无法更改 table 或查询。但是我可以将 "normal" 列添加到 table.
您可以添加一个UPDATE TRIGGER
:
CREATE TRIGGER T_Valid ON T_EmailAddress
INSTEAD OF UPDATE
AS
BEGIN
UPDATE t
SET ID = i.ID
,Valid = CASE WHEN i.Status = 'Valid' THEN 1 ELSE 0 END
,Status = i.Status
,Column1 = i.Column1
,ColumnN = i.ColumnN
FROM T_EmailAddress t
INNER JOIN ON INSERTED i
ON t.ID = i.ID
END
GO
或者,您可能希望将 Valid
列替换为计算列:
ALTER TABLE T_EmailAddress
DROP COLUMN Valid
ALTER TABLE T_EmailAddress
ADD Valid AS (CASE WHEN Status = 'Valid' THEN 1 ELSE 0 END) PERSISTED
您可以在视图上使用 instead of update 触发器。
每当视图上的更新语句完成时,触发器就会触发。注意,instead of trigger 意味着更新会被阻塞,更新语句必须自己写到底层table。
按照这些思路应该可以解决问题:
CREATE TRIGGER V_EmailAddress_IO_Update ON V_EmailAddress
INSTEAD OF UPDATE
AS
BEGIN
UPDATE t
SET Column1 = i.Column1,
ColumnN = i.ColumnN,
Valid = CASE WHEN i.[Status] = 'valid' THEN 1 ELSE 0 END
FROM inserted i
INNER JOIN T_EmailAddress t ON i.ID = t.ID
END
注意你的更新语句中必须包含视图中所有可以更新的列,否则不会更新。
考虑以下示例,其中我有一个 table 和相应的视图:
Table | View
T_EmailAddress | V_EmailAddress
----------------+----------------
ID INT | ID
Status VARCHAR | Status
Valid INT |
Column1 VARCHAR | Column1
ColumnN VARCHAR | ColumnN
我有一个程序发出以下查询:
UPDATE V_EmailAddress SET Status = 'valid' WHERE ID = 1;
UPDATE V_EmailAddress SET Status = 'invalid' WHERE ID = 2;
是否可以更新基础 table 以便 Status valid
和 invalid
存储为 1
和 0
在 Valid 列 table.
请注意,我无法更改 table 或查询。但是我可以将 "normal" 列添加到 table.
您可以添加一个UPDATE TRIGGER
:
CREATE TRIGGER T_Valid ON T_EmailAddress
INSTEAD OF UPDATE
AS
BEGIN
UPDATE t
SET ID = i.ID
,Valid = CASE WHEN i.Status = 'Valid' THEN 1 ELSE 0 END
,Status = i.Status
,Column1 = i.Column1
,ColumnN = i.ColumnN
FROM T_EmailAddress t
INNER JOIN ON INSERTED i
ON t.ID = i.ID
END
GO
或者,您可能希望将 Valid
列替换为计算列:
ALTER TABLE T_EmailAddress
DROP COLUMN Valid
ALTER TABLE T_EmailAddress
ADD Valid AS (CASE WHEN Status = 'Valid' THEN 1 ELSE 0 END) PERSISTED
您可以在视图上使用 instead of update 触发器。 每当视图上的更新语句完成时,触发器就会触发。注意,instead of trigger 意味着更新会被阻塞,更新语句必须自己写到底层table。
按照这些思路应该可以解决问题:
CREATE TRIGGER V_EmailAddress_IO_Update ON V_EmailAddress
INSTEAD OF UPDATE
AS
BEGIN
UPDATE t
SET Column1 = i.Column1,
ColumnN = i.ColumnN,
Valid = CASE WHEN i.[Status] = 'valid' THEN 1 ELSE 0 END
FROM inserted i
INNER JOIN T_EmailAddress t ON i.ID = t.ID
END
注意你的更新语句中必须包含视图中所有可以更新的列,否则不会更新。