在 mysql sproc 中使用表名的变量
Posted
技术标签:
【中文标题】在 mysql sproc 中使用表名的变量【英文标题】:use a variable for table name in mysql sproc 【发布时间】:2010-05-02 18:09:37 【问题描述】:我正在尝试将表名传递到我的 mysql 存储过程中,以使用此存储过程从不同的表中进行选择,但它不起作用...
这就是我正在尝试的:
CREATE PROCEDURE `usp_SelectFromTables`(
IN TableName varchar(100)
)
BEGIN
SELECT * FROM @TableName;
END
我也试过不带 @ 符号,它只是告诉我 TableName 不存在......我知道 :)
【问题讨论】:
【参考方案1】:SET @cname:='jello';
SET @vname:='dwb';
SET @sql_text = concat('select concept_id,concept_name,',@vname,' from enc2.concept a JOIN enc2.ratings b USING(concept_id) where concept_name like (''%',@cname,'%'') and 3 is not null order by 3 asc');
PREPARE stmt FROM @sql_text;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
【讨论】:
哇,好棒的方法! 这是如何回答问题的? OP询问如何将表名作为变量传递到存储过程中!!! @ifedi:没错。所以我想 CONCAT 函数应该包含一个使用 (IN tableName) 语句传递的变量名... 另外,请记住,在存储过程中,您不必使用@varname:='XXX'
和@varname
来阅读它们,而只需使用DECLARE
它们,然后是SET varname=value
和@987654326 @...【参考方案2】:
额外的一点给我带来了麻烦。
我想按照@kyle 的要求在查询中动态设置表名和字段,但我也想将该查询的结果存储到查询中的变量@a
中。
您需要将变量@a
直接放入concat
,而不是将其作为字符串文本的一部分。
delimiter //
CREATE PROCEDURE removeProcessed(table_name VARCHAR(255), keyField VARCHAR(255), maxId INT, num_rows INT)
BEGIN
SET @table_name = table_name;
SET @keyField = keyField;
SET @maxId = maxId;
SET @num_rows = num_rows;
SET @sql_text1 = concat('SELECT MIN(',@keyField,') INTO @a FROM ',@table_name);
PREPARE stmt1 FROM @sql_text1;
EXECUTE stmt1;
DEALLOCATE PREPARE stmt1;
loop_label: LOOP
SET @sql_text2 = concat('SELECT ',@keyField,' INTO @z FROM ',@table_name,' WHERE ',@keyField,' >= ',@a,' ORDER BY ',@keyField,' LIMIT ',@num_rows,',1');
PREPARE stmt2 FROM @sql_text2;
EXECUTE stmt2;
DEALLOCATE PREPARE stmt2;
...Additional looping code...
END LOOP;
END
//
delimiter ;
所以在@sql_text1
中,将查询结果分配给字符串中的@a
,使用:
') INTO @a FROM '
然后在@sql_text2
中使用@a
作为实际变量:
,' WHERE ',@keyField,' >= ',
@a,' ORDER BY '
【讨论】:
【参考方案3】:它依赖于 DBMS,但符号通常需要动态 SQL,并且在执行时遇到函数的返回值取决于输入的问题。这给了系统conniptions。作为一般规则(因此可能有例外),DBMS 不允许您对查询的结构元素(例如表名或列名)使用占位符(参数);它们只允许您指定值,例如列值。
某些 DBMS 确实具有存储过程支持,允许您构建 SQL 字符串,然后使用“准备”或“立即执行”或类似操作来处理它。但是请注意,您突然容易受到 SQL 注入攻击 - 可以执行您的过程的人随后能够部分地控制执行的 SQL。
【讨论】:
( IN YOURVARNAME DATATYPE ) 我更喜欢使用 IN/OUT 以便可以提供动态变量,而不仅仅是将静态变量硬编码到存储过程中。但是在有人建议验证之前,因为您应该始终验证,表单端和服务器端只是为了确保,但无论如何。以上是关于在 mysql sproc 中使用表名的变量的主要内容,如果未能解决你的问题,请参考以下文章
没有表名的 Cakephp db 查询结果,只是像 MySQL 中的普通结果?