MySQL可能创建全局例程(存储过程和/或函数)


8

是否可以以某种方式定义全局可用的例程?似乎每个例程都必须在数据库范围内创建。

当我尝试从控制台创建例程(没有发出之前use dbname)时,出现错误:

ERROR 1046 (3D000): No database selected

我们有大量相同的数据库(数据不同),目标是为某些表名创建一些触发器。但是我们只想运行一个例程,所以我们不必为每个数据库都创建这些例程(由于它们是相同的,因此例程对于每个数据库都将起作用)。


您确定要在mysql中创建触发器吗?读这篇文章是我的文章dba.stackexchange.com/questions/48797/…–
Raymond Nijland

Answers:


14

无法定义全局的存储过程或存储函数(或事件)。

一种方法是创建一个共享的通用模式,然后使用该模式的名称(CALL shared.the_procedure();)限定对函数和过程的调用。

这是我使用自定义日期/时间计算函数(例如SELECT date_time.next_quarter_start_after(NOW()))以及非常方便的common_schema框架(当然,该框架位于“ common_schema”中)所做的事情。

如果采用这种方法,则必须记住当例程运行时,“当前”数据库会自动更改,并且该DATABASE()函数的返回值将返回定义该例程的模式名称,而不是会话的当前数据库。它在例程退出时变回原来的状态,因此,如果在触发器中使用它,它不会破坏周围的任何内容,但是如果您需要知道的话,您将无法从例程内部了解当前数据库的内容。


1个实际上存储过程或存储函数(或事件)总是一个数据库中定义的
雷蒙德Nijland

3

只是为了扩展@Michael的答案,但是要引用通用模式是可以的,但是您可以在本地数据库中创建“别名”,以使其更易于管理。

例如,我正在使用尚未具有MySQL 8 UUID_TO_BIN功能的MySQL派生类,因此我创建了自己的派生类,并将其存储在专门用于我称之为的全局对象的数据库中common。因此,要引用此功能,我现在必须common.UUID_TO_BIN在所有查询和存储过程中使用。这不是一个大问题,但没有简单调用那么容易UUID_TO_BIN(就像我可以使用本地函数一样)。

因此,我还为每个数据库都添加了“别名”,如下所示:

CREATE FUNCTION `UUID_TO_BIN`(a_uuid CHAR(36), a_reorder BOOL) RETURNS binary(16)
    DETERMINISTIC
RETURN `common`.UUID_TO_BIN(a_uuid, a_reorder);

这样,在每个数据库中我都添加了这个“别名”,我现在可以简单地调用UUID_TO_BIN(some_uuid, TRUE)而无需添加任何数据库名称,而无需重复整个函数的麻烦,即-如果出于某种原因需要更改或优化该函数,我只需必须在一个地方(common.UUID_TO_BIN)这样做,而不是更新每个数据库。

如果以后使用本机升级到数据库,UUID_TO_BIN我也可以简单地删除所有“别名”功能,并且所有现有查询和过程现在都可以使用它,而无需进行任何进一步的修改。或者,如果要将全局函数移至其他数据库,则只需要更新别名,而不必更新使用该别名的每个查询。

我不确定优化一个仅调用另一个函数的函数时MySQL的智能程度如何,因此以这种方式重定向它可能会花费一些成本,但我认为简化管理是值得的仅保留一个“全局”定义。


1

一个非常简单的方法是:

  1. 确保您具有将传递给某个函数的公共变量和参数。
  2. 并只需调用您从其他数据库创建的函数即可。例如 select [databasename].empstatus(empid) as status;

PHP脚本:

$empid=trim($_REQUEST['empid']);
$conn=mysqli_connect($db_host, $db_user, $db_pass, $db_name);
$sqld="SELECT [otherdatabasename].empstatus('$empid') as employee_status";
$rs=mysqli_query($conn,$sqld);
$rw= mysqli_fetch_array($rs);
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.