2

对于 MySQL,我想使用 before-insert 和 before-update 触发器来检查数据,类似于检查条件的工作方式。我可以很容易地对此进行编码,并且可以正常工作,但是由于我需要两个触发器(插入+更新)并且检查代码相同,因此我想将其放入一个过程中。但是,似乎我不能在过程中使用“新”限定符——只能在触发器中使用。也不能作为参数传递。

任何想法如何做到这一点?我真的很讨厌不得不在两个触发器中复制检查代码。

(太糟糕了,触发器语法不能像“CREATE TRIGGER t BEFORE INSERT-OR-UPDATE ON ...”。)

更新:这是我编写的一个 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 生成,这是一个仅使用一个过程的改进版本。长得离谱的参数列表是 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