SELECT 带有 WHERE 子句,该子句在另一个 table 中存储为字符串

SELECT with a WHERE clause which is stored as string in another table

在 MySQL 中,我尝试使用 WHERE 子句从 table 中获取 select 行,该子句不固定(事先已知),而是存储在另一个 table 中,并将在 运行 时从另一个 table 中提取。

尽管 Whosebug 上已经发布了看似相似的问题,但 none 完全涵盖了该问题。

我要实现的目标如下:

SELECT * FROM users WHERE (SELECT user_condition FROM user_condition_table WHERE id = '1')

子查询

SELECT user_condition FROM user_condition_table WHERE id = '1'

会产生字符串

first_name like 'Br' and last_name like 'A%'

所以整个查询看起来像:

SELECT * FROM users WHERE first_name like 'Br' and last_name like 'A%'

我想这里的问题是从 select 返回的字符串是作为字符串而不是作为 SQL 语句返回的。 有什么办法可以做到这一点吗?

您必须使用动态 SQL --> Prepare / Execute / Deallocate 命令。

Dynamic SQL

Dynamic SQL is a programming technique that enables you to build SQL statements dynamically at runtime. You can create more general purpose, flexible applications by using dynamic SQL because the full text of a SQL statement may be unknown at compilation.


简单live example

DROP TABLE  IF exists Users;
CREATE TABLE USERS(
  first_name varchar(20),
  last_name varchar(20)
);

INSERT INTO Users VALUES('Tom','Smile'),('Bob','Hamilton'),('Jane','Moon');

DROP TABLE  IF exists user_condition_table;
CREATE TABLE user_condition_table(
  id int,
  user_condition Varchar(100)
);


INSERT INTO User_condition_table 
VALUES(1, 'first_name like ''B%'' and last_name like ''H%''');

和查询:

SET @x = ( SELECT user_condition FROM user_condition_table WHERE id = '1');
SET @x = concat('SELECT * FROM USERS WHERE ', @x );
SELECT @x;

PREPARE stmt2 FROM @x;
EXECUTE stmt2;
DEALLOCATE PREPARE stmt2;

这是一个有趣的问题。我从来没有尝试过,因为直到现在我都在应用程序代码中做过这样的事情。尽管如此,我对这个主题产生了兴趣,并提出了以下解决方案:

SELECT @cond := user_condition FROM user_condition_table WHERE (id = 1);
SELECT @sqlstring := CONCAT('SELECT * FROM users WHERE ', @cond);
PREPARE sqlquery FROM @sqlstring;
EXECUTE sqlquery;
DEALLOCATE PREPARE sqlquery;

一些备注:

  • 看来您需要使用会话变量(由前导 @ 表示)。
  • 这不是存储过程;例如,它只是一些普通的 SQL 语句,您可以直接从 MySQL 客户端中输入这些语句。