【问题标题】:Install Stored Procedure on Multiple Databases在多个数据库上安装存储过程
【发布时间】:2011-01-21 00:54:25
【问题描述】:

有什么方法可以轻松地同时在多个 MySQL 数据库上创建存储过程?所有数据库都在同一个 MySQL 安装上。

【问题讨论】:

  • 当您说“多个数据库”时,您的意思是“多个模式”吗?您可以在任何架构中安装单个存储过程并从其他架构中利用它,假设该用户在该架构上的权限尚未被撤销。
  • 我将常用过程保存在 mysql 模式中并使用 ## call mysql.some_sp();
  • 如果可能的话,仅使用存储过程的复制可能值得研究。

标签: mysql stored-procedures


【解决方案1】:

在所有架构中安装

要获取架构列表,请使用show databases;。将此与-- use结合起来:

use schemaA;
-- use schemaB;
-- use schemaC;

create procedure ...

手动遍历模式,在继续操作时删除和取消注释use 子句,检查一切是否正常。在 MySQL Workbench 中,Ctrl+Shift+Enter 是您的朋友。

在架构子集中安装例程

通常您不想将存储的例程安装在服务器上的 all 模式中,而只能安装在 子集 中 --- 通常由模式集定义已经安装了一些特定的存储例程。然后,as discussed on SO,您可以使用这样的查询来获取相关架构的名称:

SELECT ROUTINE_SCHEMA FROM `information_schema`.`ROUTINES` where specific_name = 'MyRoutine'; 

验证

部署例程后,要验证它们是否存在,您可以使用如下查询:

SELECT distinct
    r1.ROUTINE_SCHEMA, 
    case when r2.specific_name is not null then '' else '####' end as RoutineName1,
    case when r3.specific_name is not null then '' else '####' end as RoutineName2,
    case when r4.specific_name is not null then '' else '####' end as RoutineName3
FROM 
    `information_schema`.`ROUTINES` as r1 
LEFT JOIN (select * from `information_schema`.`ROUTINES` where specific_name = 'RoutineName1') as r2 on r1.routine_schema = r2.routine_schema
LEFT JOIN (select * from `information_schema`.`ROUTINES` where specific_name = 'RoutineName2') as r3 on r1.routine_schema = r3.routine_schema
LEFT JOIN (select * from `information_schema`.`ROUTINES` where specific_name = 'RoutineName3') as r4 on r1.routine_schema = r4.routine_schema
where 
    r1.specific_name = 'FilteringRoutineName'; 

此查询将检查RoutineName1RoutineName2RoutineName3 是否存在于您的服务器上具有例程FilteringRoutineName 的数据库模式中。如果缺少例程,则会用#### 标记。

当然,这只是检查例程是否存在。要验证它们的实现,您可能需要一个数据库差异工具(例如 MySQL Compare 或类似工具)。

【讨论】:

  • 我尝试过自动执行此操作,但这似乎是不可能的,因为迭代循环不能在 MySQL 中的存储例程之外使用,并且CREATE PROCEDURE 语句不能在存储例程中使用。
  • 使用prepared statementsEXECUTE 执行也许可以解决这个问题。稍后我将对此进行探索并更新我的答案以反映任何新发现。
  • 不幸的是,如果您尝试在准备好的语句中使用CREATE PROCEDURE,则会收到错误代码:1295。准备好的语句协议尚不支持此命令。根据SO answer 的说法,Lua 脚本语言可能有用。
【解决方案2】:

假设您使用的是 Linux,带有一组模式名称的简单 BASH 循环将让您执行此操作。

将您的过程定义保存到一个文件(例如 myproc.sql),然后在循环中将该文件用作 mysql 的输入。如果您将登录详细信息放在 ~/.my.cnf 中,您还可以避免将用户名和密码放在 cmdline 中。

for i in dbname1 dbname2 dbname3; do mysql ${i} < myproc.sql; done;

【讨论】:

    【解决方案3】:

    我建议在每个数据库模式中复制粘贴并创建存储过程,如果它们只需要对该模式可用。否则,我会遵循“Kelly Vista”的建议,只参考位于其中一个架构中的存储过程。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-10-28
      • 1970-01-01
      • 2015-03-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多