使用MySQL,我想使用before-insert和before-update触发器来检查数据,类似于检查条件的工作方式。我可以很容易地编码,并且它可以工作,但由于我需要两个触发器(插入+更新)并且检查代码是相同的,我想将它放入一个过程中。但是,似乎我不能在过程中使用“new”限定符 - 仅在触发器中。它也不能作为参数传递。
任何想法如何做到这一点?我真的不想在两个触发器中复制检查代码。
(触发器语法不能像“在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!";
}
}