如果我使用此数据透视表查询创建VIEW,则无法编辑。单元格是只读的,并给我SQL2005错误:“没有更新行。第2行中的数据未提交。更新或插入视图或函数'VIEWNAME'失败,因为它包含派生或常量字段。”< / p>
关于如何解决这个问题的任何想法或者像这样的支点永远不可编辑?
SELECT n_id,
MAX(CASE field WHEN 'fId' THEN c_metadata_value ELSE ' ' END) AS fId,
MAX(CASE field WHEN 'sID' THEN c_metadata_value ELSE ' ' END) AS sID,
MAX(CASE field WHEN 'NUMBER' THEN c_metadata_value ELSE ' ' END) AS NUMBER
FROM metadata
GROUP BY n_id
答案 0 :(得分:3)
假设您对n_id, field
有一个唯一约束,这意味着最多只能匹配一行,您可以(理论上至少)使用INSTEAD OF
触发器。
使用MERGE
(但在SQL Server 2008之前无法使用)会更容易,因为您需要覆盖UPDATES
现有数据INSERTS
(其中NULL
} value设置为NON NULL
one)和DELETES
,其中NON NULL
值设置为NULL
。
您需要考虑的一件事是如何应对UPDATES
将行中的所有列设置为NULL
我在测试下面的代码时这样做了,并且对于一两分钟,直到我意识到这已经删除了基表中n_id
的所有行(这意味着操作不能通过另一个UPDATE
语句反转)。将VIEW定义OUTER JOIN
放在表n_id
的PK上可以避免这个问题。
以下是事物类型的一个例子。您还需要考虑所指示的INSERT
/ DELETE
代码中的潜在竞争条件,以及是否需要一些额外的锁定提示。
CREATE TRIGGER trig
ON pivoted
INSTEAD OF UPDATE
AS
BEGIN
SET nocount ON;
DECLARE @unpivoted TABLE (
n_id INT,
field VARCHAR(10),
c_metadata_value VARCHAR(10))
INSERT INTO @unpivoted
SELECT *
FROM inserted UNPIVOT (data FOR col IN (fid, sid, NUMBER) ) AS unpvt
WHERE data IS NOT NULL
UPDATE m
SET m.c_metadata_value = u.c_metadata_value
FROM metadata m
JOIN @unpivoted u
ON u.n_id = m.n_id
AND u.c_metadata_value = m.field;
/*You need to consider race conditions below*/
DELETE FROM metadata
WHERE NOT EXISTS(SELECT *
FROM @unpivoted u
WHERE metadata.n_id = u.n_id
AND u.field = metadata.field)
INSERT INTO metadata
SELECT u.n_id,
u.field,
u.c_metadata_value
FROM @unpivoted u
WHERE NOT EXISTS (SELECT *
FROM metadata m
WHERE m.n_id = u.n_id
AND u.field = m.field)
END
答案 1 :(得分:2)
您必须在视图上创建触发器,因为无法直接更新:
CREATE TRIGGER TrMyViewUpdate on MyView
INSTEAD OF UPDATE
AS
BEGIN
SET NOCOUNT ON;
UPDATE MyTable
SET ...
FROM INSERTED...
END