2016-06-30 1 views
0

私が働いてMySQLのトリガーがあります。Mysqlトリガーの最適化。複数のテーブルの列のIF(OLD.data <> NEW.data)ここ

DROP TRIGGER IF EXISTS trg_after_update_tbl1; 
DELIMITER // 
CREATE TRIGGER trg_after_update_tbl1 
    AFTER UPDATE ON db1.tbl1 FOR EACH ROW 
    BEGIN 
    DECLARE strOld VARCHAR(255); 
    DECLARE strNew VARCHAR(255); 
    SET strOld = ''; 
    SET strNew = ''; 

    IF (NEW.colA <> OLD.colA) THEN 
     SET strOld = CONCAT(strOld, 'colA: ',OLD.colA,'; '); 
     SET strNew = CONCAT(strNew, 'colA: ',NEW.colA,'; '); 
    END IF; 
    IF (NEW.colB <> OLD.colB) THEN 
     SET strOld = CONCAT(strOld, 'colB: ',OLD.colB,'; '); 
     SET strNew = CONCAT(strNew, 'colB: ',NEW.colB,'; '); 
    END IF; 
    IF (NEW.colC <> OLD.colC) THEN 
     SET strOld = CONCAT(strOld, 'colC: ',OLD.colC,'; '); 
     SET strNew = CONCAT(strNew, 'colC: ',NEW.colC,'; '); 
    END IF; 
    -- AND SO MANY COLUMN CLAUSES ON.... 

    INSERT INTO db1.changes (user, tableName, oldData, newData, date) 
    VALUES (
      user(), 
      'tableA', 
      strOld, 
      strNew, 
      now() 
     ); 
    END// 
DELIMITER ; 

は、変数に、テーブルの列名を割り当てることが可能です(Xを言うことができます)、リストから、配列または何か似ている、それを反復し、ただ1つのIF句を使用する?関係なく使用されているDBMSの、何を示唆していることは、通常、あなたが実行している文が最初にコンパイルする必要があることを意味し、動的SQLとして知られている

BEGIN LOOP 
     IF (NEW.X <> OLD.X) THEN 
      SET strOld = CONCAT(strOld, X, ': ',OLD.X,'; '); 
      SET strNew = CONCAT(strNew, X, ': ',NEW.X,'; '); 
     END IF; 
END LOOP 
+0

「非常に多くの列...」 - 255で十分でしょうか? –

+0

はい、それは実際には:D –

答えて

1

、その後、この(擬似コード)のように実行される。

コード行数を減らすこともできますが、パフォーマンスに(悪影響を与える)影響があります。

私がいつも言うように、あなたはコードを一度書きますが、それを何度も読んでそれをさらに多く実行するとです。道徳:必要に応じて、コードを読みやすく効率的にするためにさらに努力します。

いずれにしても、MySQLはそのバージョンのDynamic SQLであるPrepared Statementsを提供しています。

私が上記で書いたものには1つの例外があります:あなたの2つのテーブルには、すべて同じ種類の既知数の列が含まれています。そのような場合、2つのレコードの内容を2つの配列に選択し、配列をループすることができます(ただし、これは最終的な考えです)。

関連する問題