【问题标题】:Execute > 1 SQL statement in single prepared statement在单个准备好的语句中执行 > 1 个 SQL 语句
【发布时间】:2020-11-13 14:29:48
【问题描述】:

好的,所以我会尽量简单地解释它;考虑到我有两个数据库表(MySQL Server / MariaDB,使用准备好的语句在 PHP 中以过程风格编码的数据库相关任务):

  1. 在其中,我有一列数据类型为 JSON,其内容对应于某事,例如{name1:info,name2:info}

  2. 在另一个中,我有简单的非 json 记录,其结构如下:

name  | status
------+--------
name1 | statusX
------+--------
name2 | statusY

我的目标:我需要从表 1 中检索 name2),但我还需要检索具有相同名称的人的状态(在本例中为 statusY)。请注意,对于name2的检索,我不能依赖json对象的索引(name2可能是json对象的第一个键)。

到目前为止我会怎么做: A) 在第一个查询中从表 1) 中获取 name2,对其进行清理,然后 B)在第二个查询中使用它,然后正确检索状态Y

语句 A) 和 B) 都是参数化的准备好的 sql 语句,由定期的 AJAX 调用(AJAX 轮询)触发。

鉴于这些数据库查询因此被频繁执行,我希望它们尽可能快地执行,从而理想地将上面的两个查询减少到一个。我的问题:我需要语句A)的结果来执行语句B),所以我不能将两个查询汇总为一个准备好的语句,因为准备好的语句不能包含多个sql语句。达到我想要的最佳解决方案是创建一个存储过程,例如:

SET @name = SELECT ..... FROM table_1; SELECT .... FROM table_2;

然后将其作为参数化的prepared statement执行;那是对的吗? 我对 MySQL Server 中的存储过程完全没有经验,还没有真正需要它们,但如果你想将 > 1 条 sql 语句包装到单个准备好的语句中,它们似乎是唯一的解决方案。这个假设,因此得出的结论是我必须创建一个存储过程来达到我想要的,正确吗?

重要提示:我不知道需要查询的名称。从表1)的json列的两个名字,我只知道另一个名字。换句话说,我有一个人 X 的名字,我想在表 1) 中获取与该人 X 关联的所有人的状态,而每个人的状态在表 2) 中列出,以避免在数据库中有重复的状态存储。 ATM,我从 DB 1) 中检索每个关系记录的其他名称,方法是使用条件语句说 sth like

更新

请参阅下面添加的答案,让它工作。

【问题讨论】:

  • MySQL 或 SQL Server,它们是不同的数据库引擎?
  • 抱歉错字;基本上我只想说我在 MySQL 服务器上使用 MariaDB;让读者知道我说的是哪种预处理语句和存储过程
  • 通常可以通过连接这两个表来解决这个问题,但是由于 table1 中的数据不是以关系格式(它是 json)存储的,所以这会有点困难。我认为this question 有你要找的东西。连接是在 json 列的 json_search 的结果上执行的。最后,您将获得一个包含 name2 的查询,结果集为 status
  • 问题是我需要先检索json doc中的名称,然后根据检索到的名称进行第二次查询。鉴于要检索的名称可能位于表 1) 的 json 列的第一个或第二个位置,我无法将其“设置”为我的 sql 语句中的选定值,但我需要先将其定义为用户定义的变量以后用它,不是吗?稍后我可以使用 JOIN 语句来做到这一点,是的,但我的主要问题是我需要使用检索到的名称的第二条语句,因此需要切换到存储过程..?
  • 您可以做的(使用下面答案的查询)是使用 Name1 和 Name2 两次加入您的第二个表。您可以将两种状态都粘贴在输出中,然后当数据返回到您的 php 时,您可以找出您真正想要的名称并获取其各自的状态。 1行到数据库和单组参数。不过,这可能会或可能不会比您当前使用两个不同查询的方法更快/更好。

标签: php mysql stored-procedures prepared-statement


【解决方案1】:

您可以使用 MySQL(如果版本 > 5.7)查询 JSON 数据类型,因此您可以通过单个查询轻松完成所有操作

试试这个

SELECT t1.name1, t1.name2, t2.status
FROM
(
  SELECT  JSON_EXTRACT(your_json_column, "$.name1") AS name1,
        JSON_EXTRACT(your_json_column, "$.name2") AS name2
  FROM table1
  WHERE JSON_EXTRACT(your_json_column, "$.name1") = 'info'
) t1
INNER JOIN table2 t2 ON t2.`name`=t1.name2

修改your_json_column的名称。我还假设您想搜索特定name1name2,因此我的WHERE 子句,如果这是一个错误的假设,请将其删除。

【讨论】:

  • 谢谢老兄,但有一点我没有提到:我不知道我需要查询的两个人的名字;我只知道我不需要的名称(例如,如果我需要将 name2 用于查询 B),我在触发查询时只知道 name1)。我通过使用条件语句来检索 name2,例如 CASE WHEN JSON_VALUE(JSON_KEY(names),'$[0]') = name1 THEN JSON_VALUE(JSON_KEY(names),'$[1]') ELSE JSON_VALUE(JSON_KEY(names),'$[0]') END
【解决方案2】:

好的,非常感谢 Thomas G 提出的解决方案和 JNevill 的一些提示(干杯!):

SELECT t1.info1, t1.info2, t1.info3, t1.other_name, t2.status FROM (
    SELECT
    field1 AS info1,
    field2 AS info2,
    field3 AS info3,
    CASE
    WHEN JSON_VALUE(JSON_KEYS(json_names_column),"$[0]") = 'name1'
    THEN JSON_VALUE(JSON_KEYS(json_names_column),"$[1]")
    ELSE JSON_VALUE(JSON_KEYS(json_names_column),"$[0]")
    END
    AS other_name
    FROM table1
    WHERE id = 345
) t1 INNER JOIN table2 t2 ON t1.other_name = t2.name;

请注意,我使用 JSON_VALUE(JSON_KEYS()) 而不是 JSON_EXTRACT,只返回所需的名称作为 t1 的名称数据,并且因为我不知道在查询之前要检索的名称,所以我不能使用 @ 987654322@clause 由 Thomas G. 提出。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-12-25
    • 2010-11-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多