如何为 Laravel 迁移创建带条件且不带定界符的 MySQL 触发器?

How to create a MySQL trigger with condition and without delimiter for Laravel migration?

我有一个 Laravel 项目,该项目已经有一个带有 SQL 脚本的数据库,我正在尝试将 MySQL 脚本放入迁移中以使用 Eloquent 反而。我的数据库有使用 DELIMITER $$ 的触发器,根据这个 question,看起来我不能在我的脚本中使用 DELIMITER $$ 因为它是一个 MySQL 客户端命令和 MySQL PDO 无法通过 PHP.

访问它

有没有办法避免 DELIMITER $$ 但在 MySQL 触发器 中仍然有条件使其可用于 Laravel 数据库迁移?

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()
    {

    }
}

示例触发器:

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 ;

注意虽然此解决方案适用于 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] => test@10.1.10.0/255.255.255.0
    [CHARACTER_SET_CLIENT] => utf8
    [COLLATION_CONNECTION] => utf8_general_ci
    [DATABASE_COLLATION] => utf8_general_ci
)