+------------------+ +------------------+
| 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_name
选择原始对象(来自object.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)
答案 0 :(得分: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);
答案 1 :(得分:1)
我最近遇到了完全相同的问题。当我删除最后一行DEALLOCATE PREPARE stmt;
时,一切都开始有效了。