在查询中创建过程

Posted

技术标签:

【中文标题】在查询中创建过程【英文标题】:Creating a procedure inside a query 【发布时间】:2021-10-30 11:41:40 【问题描述】:

我正在尝试在格拉纳达查询中实现 MySQL 过程(使用 if/else 语句)。唯一的问题是它不会让我创建我的过程并从同一个查询中调用它......

错误

db query error: Error 1064: You have an error in your SQL syntax; check the manual that corresponds to your mysql server version for the right syntax to use near 'CALL tester(true)' at line 44

我确信问题不在于我的语法,但查询的外观如下:

CREATE PROCEDURE tester(
  IN is_empty BOOLEAN
)
BEGIN
    IF(is_empty) THEN

        SELECT 
        ...
        from $dbName.table1
        where KernelName IN ($KernelNameFilter) AND `gpu-id` in ($gpuFilter) AND `Index` in ($DispatchIDFilter) 

        union SELECT
        ...
        from $dbName.table1
        where KernelName IN ($KernelNameFilter) AND `gpu-id` in ($gpuFilter) AND `Index` in ($DispatchIDFilter) 

    ELSE

        SELECT
        ...
        from $dbName.table1
        where KernelName IN ($KernelNameFilter) AND `gpu-id` in ($gpuFilter) AND `Index` in ($DispatchIDFilter);

    END IF;
END;

CALL tester(true);

它们似乎是独立工作的,但我不知道 Grafana 为什么不喜欢这种语法。有什么想法吗?

注意: 是的,我需要在 Grafana 查询 b/c 中创建过程我需要引用本地 Grafana 变量(即 $KernelNameFilter、$gpuFilter、...)

【问题讨论】:

我怀疑您看到的问题的原因是mysqliPDO 不会自动支持多个查询。在任何情况下,每次要运行该过程时都创建该过程是多余的。您应该创建一次过程(如果需要,使用 MySQL Workbench 等外部工具)然后调用它。如果您需要局部变量,请将它们作为参数传入 CALL 【参考方案1】:

您可能无法在对查询接口的一次调用中创建过程并调用该过程。大多数查询接口不支持多查询。

即使查询接口支持多查询,也不能用它来定义存储例程。多查询接口假定分号终止语句,因此过程主体内的第一个分号将终止整个 CREATE PROCEDURE 语句。这不是你想要的。

MySQL 客户端通过要求您将语句终止符更改为未出现在 CREATE PROCEDURE 语句主体中的内容来解决此问题。详情请见https://dev.mysql.com/doc/refman/8.0/en/stored-programs-defining.html

我需要引用本地 Grafana 变量(即 $KernelNameFilter、$gpuFilter、...)

您应该创建一个将 Grafana 变量作为参数的过程,并在过程主体内的查询中使用它们——不要在每次需要运行该过程时都创建一个全新的过程。

【讨论】:

以上是关于在查询中创建过程的主要内容,如果未能解决你的问题,请参考以下文章

将 POCO/实体添加到 DbContext 以进行自定义查询/过程,而无需先在实体框架代码中创建表

从 .net 代码在 Teradata 中创建存储过程

在oracle中创建存储过程的语法

在 ASP.NET 样板的种子中创建存储过程

在 Oracle -17110 中创建存储过程 - 警告:执行完成并出现警告

如何在存储过程中创建字符串列表变量以及如何在另一个查询中使用它?