在单个准备好的语句中执行 > 1 个 SQL 语句

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


其中,我有一列数据类型 JSON,其内容对应于诸如{name1:info,name2:info}


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


name  | status

------+--------

name1 | statusX

------+--------

name2 | statusY

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


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


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


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


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


然后将其作为参数化准备语句执行;那是对的吗?我对 MySQL Server 中的存储过程完全没有经验,实际上还不需要它们,但如果您想将 > 1 个 sql 语句包装到单个准备好的语句中,它们似乎是唯一的解决方案。这个假设以及我必须创建一个存储过程才能达到我想要的结果的结论是否正确?


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


更新


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


慕哥9229398
浏览 105回答 2
2回答

慕尼黑5688855

您可以使用 MySQL 查询 JSON 数据类型(如果版本 > 5.7),因此您可以通过单个查询轻松完成所有操作尝试一下SELECT t1.name1, t1.name2, t2.statusFROM(  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') t1INNER JOIN table2 t2 ON t2.`name`=t1.name2调整名称your_json_column。另外,我假设您想要搜索name2特定的name1,因此我的WHERE子句,如果它是错误的假设,请将其删除。

缥缈止盈

好的,它可以工作了,非常感谢 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 的名称数据,并且因为我不知道在查询之前检索的名称,所以我无法使用 Thomas 提出的WHERE子句G。
打开App,查看更多内容
随时随地看视频慕课网APP