Phinx: How to add triggers (MySQL) using Phinx?

Created on 1 Aug 2018  路  2Comments  路  Source: cakephp/phinx

For some reason the SQL queries in this migration run just fine if I execute them in HeidiSQL. The triggers are created.

It just doesn't work for some reason when I try to put them into a migration. I've already figured out that there seems to be a problem with PDO as mentioned here PDO support for multiple queries (PDO_MYSQL, PDO_MYSQLND). I've tried to replicate the example from this question but without success.

So what is still wrong with this? Or is there any "native" way that Phinx provides to create triggers?

<?php
use Cake\Datasource\ConnectionManager;
use Migrations\AbstractMigration;

/**
 * AddingConstraintsToTransactions
 */
class AddingConstraintsToTransactions extends AbstractMigration {

    /**
     * Add constraints to the transactions so that either credit or debit has
     * to be filled but at least one of must be filled at the same time.
     *
     * @link https://stackoverflow.com/questions/6346674/pdo-support-for-multiple-queries-pdo-mysql-pdo-mysqlnd
     */
    public function up() {
        $config = ConnectionManager::getConfig('default');
        $connection = 'mysql:host=' . $config['host'] . ';dbname=' . $config['database'];
        $db = new PDO($connection, $config['username'], $config['password']);
        $db->setAttribute(PDO::ATTR_EMULATE_PREPARES, 0);

$sql = " 
DELIMITER //

CREATE TRIGGER `wa3`.`InsertCreditOrDebitNotNull` BEFORE INSERT ON `transactions`
FOR EACH ROW BEGIN
  IF (NEW.credit IS NULL AND NEW.debit IS NULL) 
    THEN 
       SIGNAL SQLSTATE '45000'
          SET MESSAGE_TEXT = '\'credit\' and \'debit\' cannot both be null';
  END IF;
  IF (NEW.credit IS NOT NULL AND NEW.debit IS NOT NULL) 
    THEN
      SIGNAL SQLSTATE '45000'
         SET MESSAGE_TEXT = '\'credit\' and \'debit\' cannot both have a value';
  END IF;
END// -- first trigger

DELIMITER ;";

        $db->exec($sql);

$sql = "
DELIMITER //
CREATE TRIGGER `wa3`.`UpdateCreditOrDebitNotNull` BEFORE UPDATE ON `transactions`
FOR EACH ROW BEGIN
  IF (NEW.credit IS NULL AND NEW.debit IS NULL) 
    THEN
      SIGNAL SQLSTATE '45000'
         SET MESSAGE_TEXT = '\'credit\' and \'debit\' cannot both be null';
  END IF;
  IF (NEW.credit IS NOT NULL AND NEW.debit IS NOT NULL) 
    THEN
       SIGNAL SQLSTATE '45000'
          SET MESSAGE_TEXT = '\'credit\' and \'debit\' cannot both have a value';
  END IF;
END// -- second trigger

DELIMITER ;";

        $db->exec($sql);
    }

    /**
     * @inheritDoc
     */
    public function down() {
        $this->query('DROP TRIGGER IF EXISTS `InsertCreditOrDebitNotNull`');
        $this->query('DROP TRIGGER IF EXISTS `UpdateCreditOrDebitNotNull`');
    }

}
enhancement

Most helpful comment

PDO statements (exec) don't support delimiters. The DELIMITER is a client-side implementation only and is not needed for PDO statements. Try it without, and it should work.

All 2 comments

What shall we do with this one?

PDO statements (exec) don't support delimiters. The DELIMITER is a client-side implementation only and is not needed for PDO statements. Try it without, and it should work.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

alex-barylski picture alex-barylski  路  14Comments

ylynfatt picture ylynfatt  路  82Comments

igorsantos07 picture igorsantos07  路  30Comments

saada picture saada  路  14Comments

orderbynull picture orderbynull  路  19Comments