在单个准备好的语句中执行 > 1 SQL 语句
Execute > 1 SQL statement in single prepared statement
好的,我会尽量解释的简单些;考虑到我有两个数据库 tables(MySQL Server / MariaDB,使用准备好的语句在 PHP 中以过程样式编码的数据库相关任务:
其中,我有一个数据类型为 JSON 的列,其内容对应于 {name1:info,name2:info}
之类的内容
在另一个例子中,我有简单的非json记录,其结构如下:
name | status
------+--------
name1 | statusX
------+--------
name2 | statusY
我的目标:我需要从 table 1) 中检索 name2,但我还需要检索具有相同名称的人的状态(在本例中为 statusY)。请注意,对于 name2 的检索,我不能依赖 json 对象的索引(name2 可能是 json 对象的第一个键)。
到目前为止我会怎么做:
A) 从 table 中获取 name2 1) 在第一个查询中对其进行清理,然后
B) 在第二个查询中使用它,然后正确检索 statusY
语句 A) 和 B) 都是参数化准备好的 sql 语句,由 AJAX 定期调用(AJAX 轮询)触发。
鉴于这些数据库查询被频繁执行,我希望它们尽快执行,因此理想情况下将我上面的两个查询减少为一个。我的问题:我需要语句 A) 的结果来执行语句 B),所以我不能将两个查询汇总到一个准备好的语句中,因为准备好的语句不能包含多个 sql 语句。达到我想要的效果的最佳解决方案是创建一个存储过程,例如:
SET @name = SELECT ..... FROM table_1; SELECT .... FROM table_2;
然后作为参数化准备语句执行;那是对的吗?
我对 MySQL 服务器中的存储过程完全没有经验,还不是真的需要它们,但如果你想将 > 1 sql 语句包装成一个单一的,它们似乎是唯一的解决方案准备好的声明。这个假设以及我必须创建一个存储过程来达到我想要的结果的结论是否正确?
重要提示:我不知道我需要查询的名称。从table 1)的json栏的两个名字,我只知道另一个名字。换句话说,我有一个人X的名字,我想在table 1)中获取与该人X关联的所有人的状态,而每个人的状态都列在table 2)、避免在数据库中有重复的状态存储。 ATM,我通过使用条件语句从 DB 1) 检索每个关系记录的其他名称
更新
查看下面添加的答案,让它正常工作。
您可以使用 MySQL 查询 JSON 数据类型(如果版本 > 5.7),因此您可以通过一个查询简单地完成所有操作
试试这个
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
的名字。此外,我假设您想搜索特定 name1
的 name2
,因此我的 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,只 return 需要的名称作为 t1 的名称数据,因为我在查询之前不知道要检索的名称,所以我不能使用 Thomas G.
提出的 WHERE
子句
好的,我会尽量解释的简单些;考虑到我有两个数据库 tables(MySQL Server / MariaDB,使用准备好的语句在 PHP 中以过程样式编码的数据库相关任务:
其中,我有一个数据类型为 JSON 的列,其内容对应于
之类的内容{name1:info,name2:info}
在另一个例子中,我有简单的非json记录,其结构如下:
name | status
------+--------
name1 | statusX
------+--------
name2 | statusY
我的目标:我需要从 table 1) 中检索 name2,但我还需要检索具有相同名称的人的状态(在本例中为 statusY)。请注意,对于 name2 的检索,我不能依赖 json 对象的索引(name2 可能是 json 对象的第一个键)。
到目前为止我会怎么做: A) 从 table 中获取 name2 1) 在第一个查询中对其进行清理,然后 B) 在第二个查询中使用它,然后正确检索 statusY
语句 A) 和 B) 都是参数化准备好的 sql 语句,由 AJAX 定期调用(AJAX 轮询)触发。
鉴于这些数据库查询被频繁执行,我希望它们尽快执行,因此理想情况下将我上面的两个查询减少为一个。我的问题:我需要语句 A) 的结果来执行语句 B),所以我不能将两个查询汇总到一个准备好的语句中,因为准备好的语句不能包含多个 sql 语句。达到我想要的效果的最佳解决方案是创建一个存储过程,例如:
SET @name = SELECT ..... FROM table_1; SELECT .... FROM table_2;
然后作为参数化准备语句执行;那是对的吗? 我对 MySQL 服务器中的存储过程完全没有经验,还不是真的需要它们,但如果你想将 > 1 sql 语句包装成一个单一的,它们似乎是唯一的解决方案准备好的声明。这个假设以及我必须创建一个存储过程来达到我想要的结果的结论是否正确?
重要提示:我不知道我需要查询的名称。从table 1)的json栏的两个名字,我只知道另一个名字。换句话说,我有一个人X的名字,我想在table 1)中获取与该人X关联的所有人的状态,而每个人的状态都列在table 2)、避免在数据库中有重复的状态存储。 ATM,我通过使用条件语句从 DB 1) 检索每个关系记录的其他名称
更新
查看下面添加的答案,让它正常工作。
您可以使用 MySQL 查询 JSON 数据类型(如果版本 > 5.7),因此您可以通过一个查询简单地完成所有操作
试试这个
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
的名字。此外,我假设您想搜索特定 name1
的 name2
,因此我的 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,只 return 需要的名称作为 t1 的名称数据,因为我在查询之前不知道要检索的名称,所以我不能使用 Thomas G.
提出的WHERE
子句