2011-02-16 4 views
0

이 피벗 테이블 쿼리를 사용하여 VIEW를 만들면 편집 할 수 없습니다. 셀이 읽기 전용이고 SQL2005 오류가 발생했습니다 : "행이 업데이트되지 않았습니다. 행 2의 데이터가 커밋되지 않았습니다. 뷰 또는 함수 'VIEWNAME'이 파생되거나 상수 필드를 포함하고있어 업데이트 또는 삽입에 실패했습니다."SQL 피벗 테이블은 읽기 전용이며 셀을 편집 할 수 없습니까?

어떻게 해결할 수 있는지 또는 편집 할 수없는 피벗이라고 생각하십니까?

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

'n_id, field'에 고유 한 제약이 있습니까? –

답변

2

직접 업데이트가되지 수 있기 때문에 당신은보기에 트리거를 작성해야합니다 :

CREATE TRIGGER TrMyViewUpdate on MyView 
INSTEAD OF UPDATE 
AS 
BEGIN 
    SET NOCOUNT ON; 
    UPDATE MyTable 
    SET ... 
    FROM INSERTED... 
END 
3

이 최대 하나 개의 행이 당신에게 수와 일치 할 수 있음을 의미하는 당신이 n_id, field에 고유 제한 조건을 가정 (적어도 이론적으로) INSTEAD OF 방아쇠를 사용하십시오.

MERGE와 쉬울 것이다 (하지만이 SQL 서버 2008까지 사용할 수 없습니다) 당신과 DELETESNON NULL 값 (A NULL 값이 NON NULL 하나로 설정됩니다) 기존 데이터의 UPDATES, INSERTS을 충당하기 위해 필요로하는 NULL으로 설정됩니다.

여기서 고려해야 할 한 가지는 행의 모든 ​​열을 NULL으로 설정하는 UPDATES에 대처하는 방법입니다. 아래 코드를 테스트하는 동안이 작업을 수행했는데 실제로 실현 될 때까지 1-2 분 동안 매우 혼란스러워했습니다. 이로 인해 기본 테이블의 모든 행이 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 
+0

업데이트 및 삽입이있는 경우 삭제가 있어야합니다. 맞습니까? – RichardTheKiwi

+0

@cyberkiwi - 네. 페니 방금 그 중 하나에 떨어졌다 ... –

+0

이 답변은 끝내 주지만 구현할 수있는 능력을 넘어 수도 ... – djangofan

관련 문제