我已经定义了以下程序。
create procedure deleteData()
begin
DECLARE no_tbls INT;
DECLARE tbl VARCHAR(64);
DECLARE tbls_cr CURSOR for SELECT DISTINCT table_name FROM INFORMATION_SCHEMA.COLUMNS WHERE table_schema='db';
DECLARE CONTINUE HANDLER FOR NOT FOUND SET no_tbls=1;
OPEN tbls_cr;
SET no_tbls=0;
while no_tbls=0 do
fetch tbls_cr into tbl;
select tbl.updated_at from tbl limit 1;
end while;
close tbls_cr;
end
运行此程序后,我收到错误db.tbl doesn't exist
。
所以我在搜索是否有办法在另一个查询中使用游标获取对象。我正在做的所有这些繁琐的事情的问题是我想从具有特定where子句的db的所有表中删除数据。
注意:所有表都有一个带有日期格式的列updated_at
。
(我是MySQL存储过程的新手)。
答案 0 :(得分:1)
在普通的select语句中,你不能在from子句中使用变量来代替表名,mysql将在数据库中查找名为tbl
的表。
您需要使用字符串连接和prepared statements来动态创建和执行sql语句:
的MySQL>
USE test;
的MySQL>
CREATE TABLE t1 (a INT NOT NULL);
的MySQL>
INSERT INTO t1 VALUES (4), (8), (11), (32), (80);
的MySQL>
SET @table = 't1';
的MySQL>
SET @s = CONCAT('SELECT * FROM ',@table);
的MySQL>
PREPARE stmt3 FROM @s;
的MySQL>
EXECUTE stmt3;
的MySQL>
DEALLOCATE PREPARE stmt3;
预准备语句也适用于存储过程,上面的示例演示了如何通过将字符串文字与变量连接起来来创建sql语句,准备语句,执行它,然后从内存中释放预准备语句。
答案 1 :(得分:0)
使用Prepare Statement可以动态获取数据
create procedure deleteData()
begin
DECLARE no_tbls INT;
DECLARE tbl VARCHAR(64);
DECLARE tbls_cr CURSOR for
SELECT DISTINCT table_name
FROM INFORMATION_SCHEMA.COLUMNS
WHERE table_schema='db';
DECLARE CONTINUE HANDLER FOR NOT FOUND SET no_tbls=1;
OPEN tbls_cr;
start_loop : LOOP
fetch tbls_cr into tbl;
set @b = concat('select ', tbl, '.updated_at from ' , tbl, ' limit 1');
prepare stmt3 from @b;
execute stmt3;
DEALLOCATE PREPARE stmt3;
END LOOP start_loop;
close tbls_cr;
end