使用带有information_schema的游标

时间:2014-06-11 11:11:29

标签: mysql

我有以下代码:

DELIMITER $$

DROP PROCEDURE IF EXISTS dropAll $$

CREATE PROCEDURE dropAll()
BEGIN
  DECLARE done INT DEFAULT FALSE;
  DECLARE constraint_name VARCHAR(64);
  DECLARE table_name CHAR(64);
  DECLARE cur1 CURSOR FOR select CONSTRAINT_NAME, TABLE_NAME from information_schema.TABLE_CONSTRAINTS where CONSTRAINT_TYPE='FOREIGN KEY';
  DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;

  OPEN cur1;

  read_loop: LOOP
    FETCH cur1 INTO constraint_name, table_name;
    IF done THEN
      LEAVE read_loop;
    END IF;
    select table_name, constraint_name;
  END LOOP;

  CLOSE cur1;
END$$
call dropAll()$$
DELIMITER ;

它应该打印表的名称和约束。但我得到的输出看起来像

table_name  constraint_name
NULL    NULL
table_name  constraint_name
NULL    NULL
table_name  constraint_name
NULL    NULL
table_name  constraint_name
NULL    NULL
table_name  constraint_name
NULL    NULL
table_name  constraint_name
NULL    NULL
table_name  constraint_name
NULL    NULL
table_name  constraint_name
NULL    NULL
table_name  constraint_name
NULL    NULL

如果我在information_schema以外的任何数据库上使用相同的代码,我会获得预期的输出。数据库information_schema有什么不同吗?

1 个答案:

答案 0 :(得分:2)

您应该在变量名前加上前缀,以区别于列名。

这应该有效:

DELIMITER $$

DROP PROCEDURE IF EXISTS dropAll $$

CREATE PROCEDURE dropAll()
BEGIN
  DECLARE v_done INT DEFAULT FALSE;
  DECLARE v_constraint_name VARCHAR(64);
  DECLARE v_table_name CHAR(64);
  DECLARE cur1 CURSOR FOR select CONSTRAINT_NAME, TABLE_NAME from information_schema.TABLE_CONSTRAINTS where CONSTRAINT_TYPE='FOREIGN KEY';
  DECLARE CONTINUE HANDLER FOR NOT FOUND SET v_done = TRUE;

  OPEN cur1;

  read_loop: LOOP
    FETCH cur1 INTO v_constraint_name, v_table_name;
    IF v_done THEN
      LEAVE read_loop;
    END IF;
    select v_table_name, v_constraint_name;
  END LOOP;

  CLOSE cur1;
END$$
call dropAll()$$
DELIMITER ;