从 table 获取 WHERE 子句的条件
Get condition of WHERE clause from table
我有 table1
,它只有 2 列:id
和 condition
。例如:
id condition
--------------------
100 caption LIKE "%xyz%"
200 tag=5
300 color>153
...
用户向服务器发送一个 ID,根据该 ID 的条件,特定的 select 查询必须在 table2
上 运行。例如,如果 id 100 被发送到服务器,那么这个查询必须是 运行:
SELECT * FROM table2 WHERE caption LIKE "%xyz%"
如何从表 1 中获取条件并 运行 具有该条件的查询?我已经试过了:
SELECT * FROM table2 INNER JOIN table1 AS t1 ON t1.id=... WHERE t1.condition
但是,我收到以下警告但没有结果。
Warning: #1292 Truncated incorrect DOUBLE value: 'caption LIKE "%xyz%"'
那是不可能的,如果可能的话,那将是一个巨大的存储 SQL 注入安全漏洞。为了能够做到这一点,您需要一些东西来解析存储的条件并即时评估条件。据我所知,MySQL 没有为此内置任何内容。
这在 MySQL 5+
中使用准备好的语句是可能的。您可以创建一个以条件 ID 作为参数的过程:
DELIMITER //
CREATE PROCEDURE get_from_table2_by_condition_id(IN conditionId bigint)
BEGIN
SET @condition = NULL;
SELECT cond
INTO @condition
FROM table1
WHERE id = conditionId;
SET @sql = CONCAT('SELECT * FROM table2 WHERE ', COALESCE(@condition, 'FALSE'));
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END//
DELIMITER ;
CALL get_from_table2_by_condition_id(100);
查看此 fiddle
中的工作示例
我不特别建议存储您描述的 SQL 代码。
但是你有一个客户端和一个服务器。解决方案只是查询 table1
的条件,然后从中构造您想要的查询。这需要两个查询。
您可以在数据库中设置一个存储过程,使用动态 SQL 达到同样的目的。
有几个原因不希望这样:
- 代码可能会引入很难调试的语法错误。
- 代码受到 SQL 注入,具体取决于
table1
周围的安全功能。
- 对基础表的更改可能会使条件无效。
有什么替代方案?一种可能性是为不同的条件创建单独的视图。或者,只创建一个查询并传入参数:
select t2.*
from table2 t2
where (caption like :caption or :caption is null) and
(tag = :tag or :tag is null) and
(color > :color or :color is null);
我有 table1
,它只有 2 列:id
和 condition
。例如:
id condition
--------------------
100 caption LIKE "%xyz%"
200 tag=5
300 color>153
...
用户向服务器发送一个 ID,根据该 ID 的条件,特定的 select 查询必须在 table2
上 运行。例如,如果 id 100 被发送到服务器,那么这个查询必须是 运行:
SELECT * FROM table2 WHERE caption LIKE "%xyz%"
如何从表 1 中获取条件并 运行 具有该条件的查询?我已经试过了:
SELECT * FROM table2 INNER JOIN table1 AS t1 ON t1.id=... WHERE t1.condition
但是,我收到以下警告但没有结果。
Warning: #1292 Truncated incorrect DOUBLE value: 'caption LIKE "%xyz%"'
那是不可能的,如果可能的话,那将是一个巨大的存储 SQL 注入安全漏洞。为了能够做到这一点,您需要一些东西来解析存储的条件并即时评估条件。据我所知,MySQL 没有为此内置任何内容。
这在 MySQL 5+
中使用准备好的语句是可能的。您可以创建一个以条件 ID 作为参数的过程:
DELIMITER //
CREATE PROCEDURE get_from_table2_by_condition_id(IN conditionId bigint)
BEGIN
SET @condition = NULL;
SELECT cond
INTO @condition
FROM table1
WHERE id = conditionId;
SET @sql = CONCAT('SELECT * FROM table2 WHERE ', COALESCE(@condition, 'FALSE'));
PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END//
DELIMITER ;
CALL get_from_table2_by_condition_id(100);
查看此 fiddle
中的工作示例我不特别建议存储您描述的 SQL 代码。
但是你有一个客户端和一个服务器。解决方案只是查询 table1
的条件,然后从中构造您想要的查询。这需要两个查询。
您可以在数据库中设置一个存储过程,使用动态 SQL 达到同样的目的。
有几个原因不希望这样:
- 代码可能会引入很难调试的语法错误。
- 代码受到 SQL 注入,具体取决于
table1
周围的安全功能。 - 对基础表的更改可能会使条件无效。
有什么替代方案?一种可能性是为不同的条件创建单独的视图。或者,只创建一个查询并传入参数:
select t2.*
from table2 t2
where (caption like :caption or :caption is null) and
(tag = :tag or :tag is null) and
(color > :color or :color is null);