如何为 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
)
我有一个 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
)