0

たとえば、3 つの列を持つマスター テーブルがtblあります。と の組み合わせに関して一意である最初のレコードのみを表示するテーブルを作成するcol1としcol2ます。このようなテーブルの SQL は次のように定義されます。

CREATE TABLE pseudo_view AS SELECT col1, col2, col3 FROM tbl GROUP BY col1 col2

これで、この新しいテーブルにcol1とのすべての一意の組み合わせが表示されます。特定のレコードが変更されるcol2ように、このテーブルを更新します。すべての重複レコードに影響を与えるcol3ことで、これをマスター テーブルに適用したいと考えています。tbl

これは標準ビューでは不可能であることを承知しています。ただし、従属テーブルを作成する方法はありますか?それが更新されると、選択メカニズムによって定義されたとおりにマスター テーブルが更新されますか? 親テーブルにも影響を与えながら、この疑似ビュー テーブルのレコードを自由に更新および削除できるようなソリューションが必要です。

4

1 に答える 1

1

pseudo_view と tbl のいくつかのトリガーで動作します

tbl での挿入、更新、および削除の場合、「ビュー」はそれに応じて更新する必要があります。通常、それは簡単です。唯一の難しい部分は、col1 と col2 の最後のペアを削除するときです。

pseudo_table で更新および削除するには、マスターで何を変更する必要があるかを定義する必要があります。

私の例では、関数として min(3) を選択したので、行が更新されると、同じ行 (最小の col3 を持っていた行) が更新され、疑似テーブルの新しい (おそらく同じ) 値になります。計算されます。

行が削除されると、tbl のすべての行は、それ以外の場合は疑似でも行を指定するように移動する必要があります (そして、それは削除されました)。

CREATE TABLE tbl (col1 INT, col2 INT, col3 INT);
INSERT INTO tbl VALUES (1, 1, 1), (1, 1, 2), (2, 2, 3), (2, 2, 4);

CREATE TABLE pseudo_view
  AS
    SELECT
      col1,
      col2,
      MIN(col3) AS col3
    FROM tbl
    GROUP BY col1, col2;

DELIMITER //

-- update the row that originally was the min() and make sure that the new row in pseudo is the new min()
CREATE TRIGGER upd_pseudo
BEFORE UPDATE ON
  pseudo_view FOR EACH ROW
  BEGIN
    UPDATE tbl
    SET col3 = NEW.col3
    WHERE col1 = OLD.col1
          AND col2 = OLD.col2
          AND col3 = OLD.col3;

    SET NEW.col3 := (SELECT
                       MIN(col3)
                     FROM tbl
                     WHERE col1 = OLD.col1
                           AND col2 = OLD.col2);

  END //

-- delete all rows in tbl that has this col1 and col2
CREATE TRIGGER del_pseudo
AFTER DELETE ON
  pseudo_view FOR EACH ROW
  BEGIN
    DELETE FROM tbl
    WHERE col1 = OLD.col1 AND col2 = OLD.col2;
  END //

-- update pseudo to make sure it's still true
CREATE TRIGGER upd_tbl
AFTER UPDATE ON
  tbl FOR EACH ROW
  BEGIN
    UPDATE pseudo_view
    SET col3 = (SELECT
                  min(col3)
                FROM tbl
                WHERE col1 = NEW.col1 AND col2 = NEW.col2)
    WHERE col1 = NEW.col1 AND col2 = NEW.col2;
  END//

-- update pseudo to make sure it's still true
CREATE TRIGGER ins_tbl
AFTER INSERT ON
  tbl FOR EACH ROW
  BEGIN
    REPLACE pseudo_view
      VALUES (NEW.col1, NEW.col2, (SELECT
                                     min(col3)
                                   FROM tbl
                                   WHERE col1 = NEW.col1 AND col2 = NEW.col2));
  END//

-- update pseudo to make sure it's still true
CREATE TRIGGER del_tbl
AFTER DELETE ON
  tbl FOR EACH ROW
  BEGIN
    -- todo: add special case when the delete row was the last of that col1/col2-pair
    REPLACE pseudo_view
      VALUES (NEW.col1, NEW.col2, (SELECT
                                     min(col3)
                                   FROM tbl
                                   WHERE col1 = NEW.col1 AND col2 = NEW.col2));
  END//
于 2013-01-02T18:36:37.397 に答える