【问题标题】:In MySQL, how can I have a stored procedure query the tables from the calling database instead of the database where the stored procedure is defined在 MySQL 中,如何让存储过程从调用数据库而不是定义存储过程的数据库中查询表
【发布时间】:2021-07-10 18:07:02
【问题描述】:

为了简化起见,假设我有 2 个包含数据的数据库,db_data_1 和 db_data_2,它们具有相同的表集,并且我有第三个数据库,其中定义了我的存储过程,比如 db_sp。假设我的存储过程称为 my_sp

当我尝试从 db_data_1 或 db_data_2 调用 db_sp.my_sp 时,我收到一条错误消息,指出 db_sp.my_sp 中引用的表不存在。

如何让 db_sp.my_sp 查询调用数据库中的表与定义 my_sp 的数据库(即 db_sp)

谢谢。

【问题讨论】:

    标签: mysql stored-procedures database-permissions


    【解决方案1】:

    您必须使用存储过程中的数据库名称来限定查询中的表名。例如SELECT col FROM db_data_1.tbl 而不是SELECT col FROM tbl

    documentation 这么说:

    不允许在存储例程中使用 USE 语句。调用例程时,将执行隐式 USE db_name(并在例程终止时撤消)。导致例程在执行时具有给定的默认数据库。对常规默认数据库以外的数据库中对象的引用应使用适当的数据库名称进行限定。

    为什么会这样?好像xxx脖子疼的厉害。

    存储代码的一大用途是向非特权用户隐藏数据。您可以授予 MySQL 用户对存储过程的访问权限,而无需授予对基础表的访问权限。此限制将表与过程联系在一起。

    仅在test 数据库中拥有权限的用户不应该做这种事情。

    USE production;
    CALL test.get_all_user_private_data();
    

    而且,如果您使用一个数据库并运行存储在第二个数据库中的代码,它会从第二个数据库中获取数据。

    您的解决方案是将您的存储代码(过程、函数)视为每个数据库的架构定义的一部分。它们与您的其他数据定义操作(如 CREATE TABLE)一起使用。不要试图将它们放在自己的“代码库”数据库中,而是将它们放在需要它们的每个数据库中。

    【讨论】:

    • 谢谢,O.琼斯。不是我想听到的答案,但我理解其中的原理。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-04-07
    • 2018-11-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多