Mysql存储过程在sql查询中使用游标fetched变量

时间:2016-03-22 09:09:18

标签: mysql stored-procedures

我已经定义了以下程序。


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存储过程的新手)。

2 个答案:

答案 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