0

I have a Laravel project that already has a database with an SQL script and I'm trying to put the MySQL script in a migration to use Eloquent instead. My database has triggers that uses DELIMITER $$ and according to this question, it looks like I can't use DELIMITER $$ in my script because it's a MySQL client command and MySQL PDO doesn't have access to it with PHP.

Is there a way to avoid DELIMITER $$ but still have conditions in a MySQL trigger to make it usable by Laravel database migration?

migration.php:

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\File;
use Illuminate\Support\Facades\Log;

class RunInitScriptSql extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
     public function up()
     {
        $sql_dump = File::get(base_path("database/billing_system_stable.sql"));
        $sql_dump_insert = File::get(base_path("database/billing_system_insertions.sql"));
        $sql_dump_trigger = File::get(base_path("/database/billing_system_triggers.sql"));

        DB::connection('mysql')->getPdo()->exec("CREATE DATABASE IF NOT EXISTS billing_system;");
        DB::connection('mysql')->getPdo()->exec(
            $sql_dump .
            $sql_dump_insert .
            $sql_dump_trigger
        );
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {

    }
}

sample trigger:

DROP TRIGGER IF EXISTS before_update_typesoumission;
DELIMITER $$
CREATE TRIGGER before_update_typesoumission
  BEFORE UPDATE
  ON typesoumission
  FOR EACH ROW
    IF NEW.typeSoumission = 'Résidentiel'
    THEN
      SET NEW.ratio = 1;
    ELSE
      SET NEW.ratio =
      NEW.tauxHoraire / (SELECT tauxHoraire
                         FROM typesoumission
                         WHERE typeSoumission = 'Résidentiel');
    END IF;
$$
DELIMITER ;
MathieuAuclair
  • 1,229
  • 11
  • 41

1 Answers1

1

Note Although this solution works fine with MySQL, OP is using MariaDB which doesn't seem to like it.

You should be able to just put the CREATE TRIGGER into a query. In my case I use $link (the result from $link = new PDO("mysql:host=$server;dbname=$db;charset=utf8", $user, $pass, $options);) as my connection. I am running PHP7 and MySQL5.6:

$link->exec("DROP TRIGGER IF EXISTS before_update_typesoumission");
$link->exec("CREATE TRIGGER before_update_typesoumission
  BEFORE UPDATE
  ON typesoumission
  FOR EACH ROW
    IF NEW.typeSoumission = 'Résidentiel'
    THEN
      SET NEW.ratio = 1;
    ELSE
      SET NEW.ratio =
      NEW.tauxHoraire / (SELECT tauxHoraire
                         FROM typesoumission
                         WHERE typeSoumission = 'Résidentiel');
    END IF;");
$result = $link->query("SELECT * FROM INFORMATION_SCHEMA.TRIGGERS WHERE TRIGGER_NAME='before_update_typesoumission'");
print_r($result->fetch());

Output:

Array
(
    [TRIGGER_CATALOG] => def
    [TRIGGER_SCHEMA] => test
    [TRIGGER_NAME] => before_update_typesoumission
    [EVENT_MANIPULATION] => UPDATE
    [EVENT_OBJECT_CATALOG] => def
    [EVENT_OBJECT_SCHEMA] => test
    [EVENT_OBJECT_TABLE] => typesoumission
    [ACTION_ORDER] => 0
    [ACTION_CONDITION] => 
    [ACTION_STATEMENT] => IF NEW.typeSoumission = 'Résidentiel'
    THEN
      SET NEW.ratio = 1;
    ELSE
      SET NEW.ratio =
      NEW.tauxHoraire / (SELECT tauxHoraire
                         FROM typesoumission
                         WHERE typeSoumission = 'Résidentiel');
    END IF
    [ACTION_ORIENTATION] => ROW
    [ACTION_TIMING] => BEFORE
    [ACTION_REFERENCE_OLD_TABLE] => 
    [ACTION_REFERENCE_NEW_TABLE] => 
    [ACTION_REFERENCE_OLD_ROW] => OLD
    [ACTION_REFERENCE_NEW_ROW] => NEW
    [CREATED] => 
    [SQL_MODE] => STRICT_TRANS_TABLES,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION
    [DEFINER] => test@10.1.10.0/255.255.255.0
    [CHARACTER_SET_CLIENT] => utf8
    [COLLATION_CONNECTION] => utf8_general_ci
    [DATABASE_COLLATION] => utf8_general_ci
)
Nick
  • 138,499
  • 22
  • 57
  • 95
  • What's the value of link?? Did you import a library or is it a simple MySQL connection? – MathieuAuclair Aug 13 '18 at 02:34
  • `$link` in my code is the result from `$link = new PDO("mysql:host=$server;dbname=$db;charset=utf8", $user, $pass, $options);`. Probably the same as your `DB::connection('mysql')->getPdo()`? – Nick Aug 13 '18 at 02:36
  • Hmmm.. I can't get it to work... can you update the answer with the full query for the trigger creation? Thank for your help by the way! – MathieuAuclair Aug 13 '18 at 02:54
  • I'm using MariaDB also, could this be a reason? ```mysql Ver 15.1 Distrib 10.1.34-MariaDB, for Linux (x86_64) using readline 5.1``` – MathieuAuclair Aug 13 '18 at 02:57
  • MariaDB may be the problem but I thought it was MySQL compatible. What error are you getting? Anyway I've posted my entire PHP code. – Nick Aug 13 '18 at 02:59
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/177917/discussion-between-mathieuauclair-and-nick). – MathieuAuclair Aug 13 '18 at 03:07
  • this is weird but this trigger only works with PDO and not SQLClient... Anyway, this is working so thank you! – MathieuAuclair Aug 13 '18 at 17:01