【发布时间】:2015-03-12 16:32:37
【问题描述】:
我一直在尝试在 PHP/PDO 中创建触发器。我需要使用会话变量,并且只知道如何在 PHP 上处理它们,因此这是我的起点。
我的查询如下:-
$updateTrigger = "DROP TRIGGER IF EXISTS `trigger_repair_update` ;
CREATE TRIGGER `trigger_repair_update` BEFORE UPDATE ON $tbl_name
FOR EACH ROW
BEGIN
IF (NEW.repaired_by != OLD.repaired_by) THEN
INSERT INTO data_tracking
(`table_name` , `data_id`, `field`, `old_value` , `new_value` , `date_modified`, `username`)
VALUES
('$tbl_name' , NEW.id , 'repaired_by' , OLD.repaired_by , NEW.repaired_by , NOW() , '$user' );
END IF;
IF (NEW.must_have != OLD.must_have) THEN
INSERT INTO data_tracking
(`table_name` , `data_id`, `field`, `old_value` , `new_value` , `date_modified`, `username`)
VALUES
('$tbl_name' , NEW.id , 'must_have' , OLD.must_have , NEW.must_have , NOW() , '$user' );
END IF;
IF (NEW.location != OLD.location) THEN
INSERT INTO data_tracking
(`table_name` , `data_id`, `field`, `old_value` , `new_value` , `date_modified`, `username`)
VALUES
('$tbl_name' , NEW.id , 'location' , OLD.location , NEW.location , NOW() , '$user' );
END IF;
IF (NEW.status != OLD.status) THEN
INSERT INTO data_tracking
(`table_name` , `data_id`, `field`, `old_value` , `new_value` , `date_modified`, `username`)
VALUES
('$tbl_name' , NEW.id , 'status' , OLD.status , NEW.status , NOW() , '$user' );
END IF;
IF (NEW.price != OLD.price) THEN
INSERT INTO data_tracking
(`table_name` , `data_id`, `field`, `old_value` , `new_value` , `date_modified`, `username`)
VALUES
('$tbl_name' , NEW.id , 'price' , OLD.price , NEW.price , NOW() , '$user' );
END IF;
END;";
$sth = $dbLink->prepare($updateTrigger);
$sth->execute();
如果我删除变量并进入 PHPMYADMIN,一切正常,所以我的结论是我没有正确分配变量。我应该在这里绑定参数吗?
我在很多地方都找过这个:
- http://code.tutsplus.com/articles/introduction-to-mysql-triggers--net-12226
- Is is possible to see what data was changed by a query?
- Using MySQL triggers to log all table changes to a secondary table
- Is there a MySQL option/feature to track history of changes to records?
- http://codespatter.com/2008/05/06/how-to-use-triggers-to-track-changes-in-mysql/
但我似乎仍然缺少一些东西。
编辑:- 感谢 Michael Berkowski,我添加了错误代码并收到以下消息:-
致命错误:未捕获的异常 'PDOException' 带有消息 'SQLSTATE[42000]:语法错误或访问冲突:1064 您的 SQL 语法有错误;检查与您的 MySQL 服务器版本相对应的手册,以在 /Applications/MAMP/htdocs/repair_list.php:58 中的第 2 行的“CREATE TRIGGER
trigger_repair_updateBEFORE UPDATE ON repair FOR EACH ROW BEGI”附近使用正确的语法跟踪:#0 /Applications/MAMP/htdocs/repair_list.php(58): PDO->prepare('DROP TRIGGER IF...') #1 {main} 在 /Applications/MAMP/htdocs/repair_list.php 中抛出第 58 行
第 58 行是 $sth = $dbLink->prepare($updateTrigger);坐。
【问题讨论】:
-
您检查过错误吗? PDO 错误默认静默。
$dbLink->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);让它抛出一个有意义的异常。 -
在 PHP 中启用 display_errors。在脚本的顶部,
error_reporting(E_ALL); ini_set('display_errors', 1);但是,如果代码中存在解析错误,则不会在屏幕上打印。您必须查看错误日志。 -
也许您在此脚本中使用的用户没有创建触发器的数据库权限?完成
execute()后,您可以向驱动程序询问可能发生的任何错误。此方法也返回一个布尔成功标志。 -
你不能用 PDO prepare 运行多个语句
-
D'oh - 现在很明显了。 PDO 不支持在准备好的语句中进行多个查询。您正在执行
DROP,后跟CREATE。将动作分开。首先用$dbLink->exec("DROP...")调用DROP,然后准备CREATE。从技术上讲,由于您没有绑定参数,因此您也可以将exec()用于CREATE。