2

MySQL では、チェック条件が機能する方法と同様に、before-insert トリガーと before-update トリガーを使用してデータをチェックしたいと考えています。これは簡単にコーディングでき、機能しますが、2 つのトリガー (挿入 + 更新) が必要で、チェック コードが同じであるため、プロシージャに入れたいと思います。ただし、プロシージャでは「new」修飾子を使用できないようです。トリガーでのみ使用できます。パラメータとして渡すこともできません。

これを行う方法はありますか?2 つのトリガーでチェック コードを複製しなければならないのは本当に嫌です。

(トリガー構文が「CREATE TRIGGER t BEFORE INSERT-OR-UPDATE ON ...」のようなものにならないのは残念です。)

更新: これは、チェック コードのコピーを 2 つ持つことなく 2 つのトリガーを作成するために作成した PHP 関数です。チェックコードを複製せずにこれを行う純粋なMySQLの方法があるかどうかを知りたいです。

function add_trigger($table, $sql) {
    dbquery2("drop trigger if exists table_{$table}_trigger1");
    dbquery2("drop trigger if exists table_{$table}_trigger2");
    dbquery2("create trigger table_{$table}_trigger1 before insert on $table for each row begin $sql end");
    dbquery2("create trigger table_{$table}_trigger2 before update on $table for each row begin $sql end");
}

dbquery2 は、mysqli::query を呼び出す私自身の関数です。

更新 2: SQL が PHP によって生成されることを考えると、1 つのプロシージャのみを使用する改良版を次に示します。とてつもなく長いパラメーター リストは PHP によって information_schema から生成されるため、その長さと冗長性は問題になりません。

function add_trigger($table, $sql) {
    if ($result = dbquery2("select column_name, column_type from information_schema.columns where table_schema = 'cwadb_local' and table_name = '$table'")) {
        while ($row = $result->fetch_assoc()) {
            $cols .= ", new.{$row['column_name']}";
            $params .= ", {$row['column_name']} {$row['column_type']}";
        }
        $cols = substr($cols, 2); // remove extra ", " at front
        $params = substr($params, 2);
        $t1 = "create trigger table_{$table}_trigger1 before insert on $table for each row begin call check_table_{$table}($cols); end";
        $t2 = "create trigger table_{$table}_trigger2 before update on $table for each row begin call check_table_{$table}($cols); end";
        $proc = "create procedure check_table_{$table}($params) begin $sql end";
        dbquery2("drop procedure if exists check_table_{$table}"); // like mysqli::query, but throws exception on error
        dbquery2("drop trigger if exists table_{$table}_trigger1");
        dbquery2("drop trigger if exists table_{$table}_trigger2");
        dbquery2($t1);
        dbquery2($t2);
        dbquery2($proc);
        echo "<p>Success!";
    }
}
4

0 に答える 0