Как создать триггер MySQL с условием и без разделителя для миграции Laravel?

У меня есть проект Laravel, в котором уже есть база данных со скриптом SQL, и я пытаюсь поместить скрипт MySQL в миграцию, чтобы вместо этого использовать Eloquent. В моей базе данных есть триггеры, которые используют DELIMITER $$, и, согласно этому вопросу, это похоже, я не могу использовать DELIMITER $$ в своем скрипте, потому что это клиентская команда MySQL, а MySQL PDO не имеет к ней доступа с PHP.

Есть ли способ избежать DELIMITER $$, но при этом сохранить условия в триггере MySQL, чтобы его можно было использовать при миграции базы данных Laravel?

миграция.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()
    {

    }
}

образец триггера:

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 ;

person MathieuAuclair    schedule 13.08.2018    source источник


Ответы (1)


Примечание. Хотя это решение отлично работает с MySQL, OP использует MariaDB, которому это, похоже, не нравится.

Вы должны иметь возможность просто поместить CREATE TRIGGER в запрос. В моем случае я использую $link (результат $link = new PDO("mysql:host=$server;dbname=$db;charset=utf8", $user, $pass, $options);) в качестве соединения. Я использую PHP7 и 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());

Выход:

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] => [email protected]/255.255.255.0
    [CHARACTER_SET_CLIENT] => utf8
    [COLLATION_CONNECTION] => utf8_general_ci
    [DATABASE_COLLATION] => utf8_general_ci
)
person Nick    schedule 13.08.2018
comment
Сколько стоит ссылка?? Вы импортировали библиотеку или это простое соединение с MySQL? - person MathieuAuclair; 13.08.2018
comment
$link в моем коде является результатом $link = new PDO("mysql:host=$server;dbname=$db;charset=utf8", $user, $pass, $options);. Наверное, такой же, как ваш DB::connection('mysql')->getPdo()? - person Nick; 13.08.2018
comment
Хммм... Я не могу заставить его работать... можете ли вы обновить ответ полным запросом на создание триггера? Кстати спасибо за помощь! - person MathieuAuclair; 13.08.2018
comment
Я также использую MariaDB, может ли это быть причиной? mysql Ver 15.1 Distrib 10.1.34-MariaDB, for Linux (x86_64) using readline 5.1 - person MathieuAuclair; 13.08.2018
comment
Проблема может быть в MariaDB, но я думал, что она совместима с MySQL. Какую ошибку вы получаете? Во всяком случае, я разместил весь свой PHP-код. - person Nick; 13.08.2018
comment
Давайте продолжим обсуждение в чате. - person MathieuAuclair; 13.08.2018
comment
это странно, но этот триггер работает только с PDO, а не с SQLClient... В любом случае, это работает, так что спасибо! - person MathieuAuclair; 13.08.2018