我一直在研究我们的内部开发服务器并在我们的MySQL 5.6.13服务器上创建MySQL触发器。我现在遇到的问题是在内部服务器上使用DEFINER = root
@ %
创建了触发器(总共大约200个)。
现在我想转移到实时制作服务器。但是在我们的实时服务器上,我们不允许用户root访问。因此,我如何批量更改所有触发器,以便它读取DEFINER = root
@ localhost
答案 0 :(得分:52)
一种方法:
1)将触发器定义转储到文件
# mysqldump -uroot -p --triggers --add-drop-trigger --no-create-info \
--no-data --no-create-db --skip-opt test > /tmp/triggers.sql
2)在您喜欢的编辑器中打开triggers.sql
文件,然后使用Find and Replace
功能更改DEFINER
。保存更新的文件。
3)从文件
重新创建触发器# mysql < triggers.sql
答案 1 :(得分:4)
不使用--add-drop-trigger选项:
currentUserDefiner='root'
currentHostDefiner='localhost'
newUserDefiner='user'
newHostDefiner='localhost'
db='myDb'
mysqldump -u root --triggers --no-create-info --no-data --no-create-db --skip-opt $db \
| perl -0777 -pe 's/(\n\/\*.+?50003 TRIGGER `([^`]+)`)/\nDROP TRIGGER \2;\1/g' \
| perl -0777 -pe 's/(DEFINER[^`]+)'$currentUserDefiner'(`@`)'$currentHostDefiner'/\1'$newUserDefiner'\2'$newHostDefiner'/gi' \
> out.sql
mysql -u root < out.sql
答案 2 :(得分:1)
接受的答案对我不起作用,因为我的大多数客户都托管在5.5的服务器上,而我可以做的不多, --add-drop-trigger function was added in 5.6
在敲了敲我的头后,我刚进入phpMyAdmin,在触发器编辑页面上暴露了定义器,我只是编辑了20个左右触发器的定义器 - phpMyAdmin将丢弃并重新创建触发器新的定义者。
我找到的另一个选项是完成一个完整的mysqldump,编辑生成的文件,用它来创建一个新数据库,然后使用像Navicat这样的工具执行结构同步回原始数据库,只选择所需的触发器。结果比较清单。这对我来说是一个更长的过程,因为我只需要编辑20个触发器,但如果我必须更新数百个触发器,这将更快。
答案 3 :(得分:1)
另一种方法是使用此Java实用程序。请注意,这是一项正在进行的工作,因为当前版本1.0清除了一些服务器变量。 newdef
答案 4 :(得分:1)
我知道这是一篇过时的文章,但也许可以对某人有所帮助。
我使用此sql查询生成DROP和CREATE命令:
SELECT CONCAT("DROP TRIGGER ", trigger_name, ";", " CREATE TRIGGER ", TRIGGER_NAME, " AFTER ", EVENT_MANIPULATION, " ON ", EVENT_OBJECT_SCHEMA, ".", EVENT_OBJECT_TABLE, " FOR EACH ROW ", ACTION_STATEMENT, ";") AS sqlCommand FROM information_schema.triggers WHERE EVENT_OBJECT_SCHEMA = "yourdatabase";
当我将生产数据库带到开发机器并在所有命令上使用foreach进行操作并自动重新创建触发器时,我在应用程序中使用了此功能。这给了我自动化的选择。
PHP / Laravel中的示例:
$this->info('DROP and CREATE TRIGGERS');
$pdo = DB::connection()->getPdo();
$sql = 'SELECT CONCAT("DROP TRIGGER ", trigger_name, ";", " CREATE TRIGGER ", TRIGGER_NAME, " AFTER ", EVENT_MANIPULATION, " ON ", EVENT_OBJECT_SCHEMA, ".", EVENT_OBJECT_TABLE, " FOR EACH ROW ", ACTION_STATEMENT, ";") AS sqlCommand FROM information_schema.triggers WHERE EVENT_OBJECT_SCHEMA = "mydatabase";';
$stmt = $pdo->prepare($sql, [PDO::MYSQL_ATTR_USE_BUFFERED_QUERY => true]);
$stmt->execute();
$result = $stmt->fetchAll(PDO::FETCH_ASSOC);
$stmt->closeCursor();
foreach($result as $rs){
$pdo = DB::unprepared($rs['sqlCommand']);
break;
}
提示:由于mysql缓冲区查询问题,我必须使用pdo进行操作,here
我的观点也一样(在这里您可以使用ALTER TABLE):
$pdo = DB::connection()->getPdo();
$sql = 'SELECT CONCAT("ALTER DEFINER=`homestead` VIEW ", table_name," AS ", view_definition,";") AS sqlCommand FROM information_schema.views WHERE table_schema="mydatabase";';
$stmt = $pdo->prepare($sql, [PDO::MYSQL_ATTR_USE_BUFFERED_QUERY => true]);
$stmt->execute();
$result = $stmt->fetchAll(PDO::FETCH_ASSOC);
$stmt->closeCursor();
$this->info('View definer changed');
foreach($result as $rs){
$pdo = DB::unprepared($rs['sqlCommand']);
}
希望有帮助。
答案 5 :(得分:1)
运行此sql语句(用所需的触发器替换表名和触发器名):
$ mysql -V
mysql Ver 15.1 Distrib 5.5.64-MariaDB, for Linux (x86_64) using readline 5.1
然后修改结果并执行。
答案 6 :(得分:0)
使用MySQL Workbench中的选项主题的另一个变体是使用“mysqldump”转储整个数据库,在功能强大的编辑器中打开转储,找到替换为所需的“DEFINER”,然后使用MyQSL Workbench导入“转储”在导入屏幕上选择了结构选项“(v6.2)。
答案 7 :(得分:0)
我能够通过关闭MySQL服务器来更新触发器定义程序,然后更新表.TRG文件(这些文件是文本文件,在其中查找定义程序和CREATE DEFINER),然后重新启动MySQL。我只需要为一张桌子做,但是如果有很多桌子,我会按照这些原则编写一个sed脚本或其他东西。如果服务器无法关闭,则以下各项应能非常顺利地进行,而对活动的干扰很小(免责声明-我尚未对其进行测试):
每个表: