Сводная таблица SQL доступна только для чтения, и ячейки нельзя редактировать? - PullRequest
0 голосов
/ 16 февраля 2011

Если я создаю VIEW, используя этот запрос сводной таблицы, он не редактируется. Ячейки доступны только для чтения и выдают ошибку SQL2005: «Строка не была обновлена. Данные в строке 2 не были зафиксированы. Ошибка обновления или вставки представления или функции« VIEWNAME », поскольку она содержит производное или постоянное поле».

Любые идеи о том, как это можно решить, ИЛИ разворот, как этот, просто никогда не редактируется?

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

Ответы [ 2 ]

3 голосов
/ 16 февраля 2011

Если у вас есть уникальное ограничение на n_id, field, что означает, что может соответствовать не более одной строки, вы можете (по крайней мере в теории) использовать триггер INSTEAD OF.

Это было бы проще с MERGE (но это не доступно до SQL Server 2008), так как вам нужно охватить UPDATES существующих данных, INSERTS (где значение NULL установлено на NON NULL один) и 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  
2 голосов
/ 16 февраля 2011

Вам потребуется создать триггер при просмотре, поскольку прямое обновление невозможно:

CREATE TRIGGER TrMyViewUpdate on MyView
INSTEAD OF UPDATE
AS
BEGIN
   SET NOCOUNT ON;
   UPDATE MyTable
   SET ...
   FROM INSERTED...
END
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...