我正在尝试将表名传递给我的mysql存储过程以使用此sproc来选择不同的表,但它不起作用...
这就是我想要的:
CREATE PROCEDURE `usp_SelectFromTables`(
IN TableName varchar(100)
)
BEGIN
SELECT * FROM @TableName;
END
我也尝试了没有@符号,只是告诉我TableName不存在......我知道:)。
答案 0 :(得分:54)
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;
答案 1 :(得分:14)
额外的一点让我有问题。
我想在@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,' >= ',
@一个,' ORDER BY '
答案 2 :(得分:13)
它取决于DBMS,但是表示法通常需要动态SQL,并且遇到的问题是函数的返回值取决于执行时的输入。这给系统带来了条件。作为一般规则(因此可能受到例外限制),DBMS不允许您对查询的结构元素(如表名或列名)使用占位符(参数);它们只允许您指定列值等值。
某些DBMS确实具有存储过程支持,允许您构建SQL字符串,然后使用“prepare”或“execute immediate”或类似操作来处理它。但请注意,您突然容易受到SQL注入攻击 - 可以执行您的过程的人可以部分控制SQL执行的内容。