1
+------------------+        +------------------+    
| object           |        | example          |
+------------------+        +------------------+    
| id               |        | id               |    
| table_name       |        | ...              |    
| ref_id           |        |                  |    
+------------------+        +------------------+    

object  [ id = 5, table_name = example, ref_id = 2]
example [ id = 2 ]

我有一个表,它可以代表一组来自多个不同表的对象。这些对象都有一个id, 引用object.ref_id

我正在尝试通过 选择原始对象(从 引用的表中object.table_nameobject.id。为此,我尝试使用以下 SQL 查询。虽然这会导致#1054 - Unknown column 'entity.id' in 'where clause'.

SELECT  * 
FROM    (
        SELECT  table_name
        FROM    object 
        WHERE   id = 5) AS entity
WHERE   entity.id = (
        SELECT  ref_id
        FROM    object 
        WHERE   id = 5)

我究竟做错了什么?

案例示例

SELECT * 
FROM example 
WHERE id = (
    SELECT  ref_id
    FROM    object 
    WHERE   id = 5 )

虽然,对于我来说,FROM 子句不像示例中那样简单,因为这个值通常是从object.table_name.

使用 TOMBOM 的方法进行更新

使用 Tombom 的解决方案会导致错误,为了测试,我已经替换了 CONCAT 函数中的变量。

SET @sql = CONCAT('SELECT * FROM ', 'example', ' WHERE id = ', '1');

PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

#1243 - 给 EXECUTE 的未知准备好的语句处理程序 (stmt)

4

2 回答 2

2

你不能以这种方式告诉 MySQL 一个(子)查询的结果是一个表名。您必须使用结果构建动态语句。

SELECT @tableName:=table_name, @refId:=ref_id FROM object WHERE id = 5 LIMIT 1;

SET @sql = CONCAT('SELECT * FROM ', @tableName, ' WHERE id = ', @refId);

PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;

更新:请尝试使用存储过程:

DELIMITER $$
CREATE PROCEDURE procName(IN my_id INT)
BEGIN
SELECT @tableName:=table_name, @refId:=ref_id FROM object WHERE id = my_id LIMIT 1;

SET @sql = CONCAT('SELECT * FROM ', @tableName, ' WHERE id = ', @refId);

PREPARE stmt FROM @sql;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
END $$
DELIMITER ;

然后执行存储过程

CALL procName(5);
于 2013-03-11T11:19:39.857 回答
1

我最近遇到了完全相同的问题。当我删除最后一行时,DEALLOCATE PREPARE stmt;一切都开始工作了。

于 2016-01-28T12:39:47.693 回答