使用 PDO / PHP 创建 MYSQL 触发器
Creating a MYSQL Trigger using PDO / PHP
我一直在尝试在 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,我添加了错误代码并收到以下消息:-
Fatal error: Uncaught exception 'PDOException' with message 'SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'CREATE TRIGGER trigger_repair_update
BEFORE UPDATE ON repair FOR EACH ROW BEGI' at line 2' in /Applications/MAMP/htdocs/repair_list.php:58 Stack trace: #0 /Applications/MAMP/htdocs/repair_list.php(58): PDO->prepare('DROP TRIGGER IF...') #1 {main} thrown in /Applications/MAMP/htdocs/repair_list.php on line 58
第 58 行是 $sth = $dbLink->prepare($updateTrigger);坐着。
(为完整起见添加答案,来自 Michael 的评论)。
PDO 不支持准备语句中的多个查询。您正在执行 DROP
,然后是 CREATE
。将动作分开。先用 $dbLink->exec("DROP...")
调用 DROP
,然后准备 CREATE
。从技术上讲,由于您没有绑定参数,因此您也可以将 exec()
用于 CREATE
。
我一直在尝试在 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,我添加了错误代码并收到以下消息:-
Fatal error: Uncaught exception 'PDOException' with message 'SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'CREATE TRIGGER
trigger_repair_update
BEFORE UPDATE ON repair FOR EACH ROW BEGI' at line 2' in /Applications/MAMP/htdocs/repair_list.php:58 Stack trace: #0 /Applications/MAMP/htdocs/repair_list.php(58): PDO->prepare('DROP TRIGGER IF...') #1 {main} thrown in /Applications/MAMP/htdocs/repair_list.php on line 58
第 58 行是 $sth = $dbLink->prepare($updateTrigger);坐着。
(为完整起见添加答案,来自 Michael 的评论)。
PDO 不支持准备语句中的多个查询。您正在执行 DROP
,然后是 CREATE
。将动作分开。先用 $dbLink->exec("DROP...")
调用 DROP
,然后准备 CREATE
。从技术上讲,由于您没有绑定参数,因此您也可以将 exec()
用于 CREATE
。