从 table 获取 WHERE 子句的条件

Get condition of WHERE clause from table

我有 table1,它只有 2 列:idcondition。例如:

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);