2

I've been trying to create a trigger within PHP / PDO. I need to use session variables, and only know how to handle them on PHP, hence this was my start point.

My query is as follows:-

$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();

If I remove the variables and enter into PHPMYADMIN, everything works fine, so my conclusion is that I have not allocated the variables properly. Should I be binding parameters here?

I've looked in many places for this:

I still seem to be missing something though.

EDIT:- Thanks to Michael Berkowski, I have added the error code and get the following message:-

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

Line 58 is where the $sth = $dbLink->prepare($updateTrigger); sits.

22
  • 1
    Have you checked for errors? PDO errors silently by default. $dbLink->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); to make it throw a meaningful exception. Commented Mar 12, 2015 at 16:38
  • 2
    Enable display_errors in PHP. At the top of your script, error_reporting(E_ALL); ini_set('display_errors', 1); However, if there is a parse error in the code, that won't be printed on screen. You would have to look in the error log. Commented Mar 12, 2015 at 16:49
  • 1
    Perhaps the user you are using in this script doesn't have database permissions to create triggers? After you do the execute() you can ask the driver for any errors that may have occurred. This method returns a boolean success flag, too. Commented Mar 12, 2015 at 16:56
  • 1
    You cant run multiple statements with PDO prepare Commented Mar 12, 2015 at 17:03
  • 2
    D'oh - it's obvious now. PDO does not support multiple queries in the prepared statement. You are executing a DROP followed by a CREATE. Separate the actions. Call the DROP with $dbLink->exec("DROP...") first, then prepare the CREATE. Technically since you have no bound parameters, you could use exec() for the CREATE as well. Commented Mar 12, 2015 at 17:03

1 Answer 1

1

(Adding answer for the sake of completeness, from Michael's comment).

PDO does not support multiple queries in the prepared statement. You are executing a DROP followed by a CREATE. Separate the actions. Call the DROP with $dbLink->exec("DROP...") first, then prepare the CREATE. Technically since you have no bound parameters, you could use exec() for the CREATE as well.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.