循环 table 并调用存储过程
Loop over table and call stored procedure
现在,我正在尝试遍历导入过程创建的临时 table。我试过使用游标,但 tablename 必须传递给存储过程。
CREATE PROCEDURE `do_update`(tablename VARCHAR(100))
BEGIN
DECLARE done BOOLEAN DEFAULT FALSE;
DECLARE c_ean VARCHAR(20);
DECLARE c_sku VARCHAR(20);
DECLARE c_mpn VARCHAR(20);
DECLARE c_manufacturerName VARCHAR(100);
DECLARE c_manufacturerUniqueId VARCHAR(100);
DECLARE c_images TEXT;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done := TRUE;
-- move declare cursor into sql to be executed
SET @sqlstatement = CONCAT('DECLARE import_cursor CURSOR FOR SELECT ean, sku, mpn, manufacturerName, manufacturerUniqueId, images FROM ', tablename);
PREPARE stmt FROM @sqlstatement;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
OPEN import_cursor;
importloop: LOOP
FETCH import_cursor INTO c_ean, c_sku, c_mpn, c_manufacturerName, c_manufacturerUniqueId, c_images;
IF done THEN
LEAVE importloop;
END IF;
CALL upsert_article(c_ean, c_sku, c_mpn, c_manufacturerName, c_manufacturerUniqueId, c_images);
END LOOP testloop;
CLOSE import_cursor;
END
注意:此导入脚本将在一天内多次调用,并且可能 运行 同时调用。所以定义的 tablename 不是一个选项。
到目前为止我尝试了什么:
- 正在用给定的table名称创建游标。 --> 有效,但名称必须是动态的。
- 正在使用动态创建游标 sql。 --> 失败
- 跳过使用光标并以不同的方式循环 table。 --> 未找到使用动态 sql
的方法
那么,有没有办法通过游标或解决方法来实现这一点?
创建一个临时 table 并插入我的动态查询的结果最终成功了。
这样我就可以将 mysql 游标与名为临时 table 的静态一起使用。由于它是临时的 table,多个导入作业不会相互干扰,因为它们对其他会话是隐藏的。
最后这是对我有用的代码:
CREATE PROCEDURE `do_update`(IN
tablename VARCHAR(100))
BEGIN
DECLARE done INT;
DECLARE c_ean VARCHAR(20);
DECLARE c_sku VARCHAR(20);
DECLARE c_mpn VARCHAR(20);
DECLARE c_manufacturerName VARCHAR(100);
DECLARE c_manufacturerUniqueId VARCHAR(100);
DECLARE c_images NVARCHAR(3000);
DECLARE import_cursor CURSOR FOR SELECT ean, sku, mpn, manufacturerName, manufacturerUniqueId, images FROM importjob;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done := TRUE;
DROP TEMPORARY TABLE IF EXISTS importjob;
SET @sqlstatement = CONCAT('CREATE TEMPORARY TABLE importjob SELECT ean, sku, mpn, manufacturerName, manufacturerUniqueId, images FROM ', tablename);
PREPARE stmt FROM @sqlstatement;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
SET @DEBUG = true;
OPEN import_cursor;
importloop: LOOP
FETCH import_cursor INTO c_ean, c_sku, c_mpn, c_manufacturerName, c_manufacturerUniqueId, c_images;
IF done THEN
LEAVE importloop;
END IF;
CALL upsert_article(c_ean, c_sku, c_mpn, c_manufacturerName, c_manufacturerUniqueId, c_images);
END LOOP importloop;
CLOSE import_cursor;
DROP TEMPORARY TABLE IF EXISTS importjob;
END
现在,我正在尝试遍历导入过程创建的临时 table。我试过使用游标,但 tablename 必须传递给存储过程。
CREATE PROCEDURE `do_update`(tablename VARCHAR(100))
BEGIN
DECLARE done BOOLEAN DEFAULT FALSE;
DECLARE c_ean VARCHAR(20);
DECLARE c_sku VARCHAR(20);
DECLARE c_mpn VARCHAR(20);
DECLARE c_manufacturerName VARCHAR(100);
DECLARE c_manufacturerUniqueId VARCHAR(100);
DECLARE c_images TEXT;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done := TRUE;
-- move declare cursor into sql to be executed
SET @sqlstatement = CONCAT('DECLARE import_cursor CURSOR FOR SELECT ean, sku, mpn, manufacturerName, manufacturerUniqueId, images FROM ', tablename);
PREPARE stmt FROM @sqlstatement;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
OPEN import_cursor;
importloop: LOOP
FETCH import_cursor INTO c_ean, c_sku, c_mpn, c_manufacturerName, c_manufacturerUniqueId, c_images;
IF done THEN
LEAVE importloop;
END IF;
CALL upsert_article(c_ean, c_sku, c_mpn, c_manufacturerName, c_manufacturerUniqueId, c_images);
END LOOP testloop;
CLOSE import_cursor;
END
注意:此导入脚本将在一天内多次调用,并且可能 运行 同时调用。所以定义的 tablename 不是一个选项。
到目前为止我尝试了什么:
- 正在用给定的table名称创建游标。 --> 有效,但名称必须是动态的。
- 正在使用动态创建游标 sql。 --> 失败
- 跳过使用光标并以不同的方式循环 table。 --> 未找到使用动态 sql 的方法
那么,有没有办法通过游标或解决方法来实现这一点?
创建一个临时 table 并插入我的动态查询的结果最终成功了。 这样我就可以将 mysql 游标与名为临时 table 的静态一起使用。由于它是临时的 table,多个导入作业不会相互干扰,因为它们对其他会话是隐藏的。
最后这是对我有用的代码:
CREATE PROCEDURE `do_update`(IN
tablename VARCHAR(100))
BEGIN
DECLARE done INT;
DECLARE c_ean VARCHAR(20);
DECLARE c_sku VARCHAR(20);
DECLARE c_mpn VARCHAR(20);
DECLARE c_manufacturerName VARCHAR(100);
DECLARE c_manufacturerUniqueId VARCHAR(100);
DECLARE c_images NVARCHAR(3000);
DECLARE import_cursor CURSOR FOR SELECT ean, sku, mpn, manufacturerName, manufacturerUniqueId, images FROM importjob;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done := TRUE;
DROP TEMPORARY TABLE IF EXISTS importjob;
SET @sqlstatement = CONCAT('CREATE TEMPORARY TABLE importjob SELECT ean, sku, mpn, manufacturerName, manufacturerUniqueId, images FROM ', tablename);
PREPARE stmt FROM @sqlstatement;
EXECUTE stmt;
DEALLOCATE PREPARE stmt;
SET @DEBUG = true;
OPEN import_cursor;
importloop: LOOP
FETCH import_cursor INTO c_ean, c_sku, c_mpn, c_manufacturerName, c_manufacturerUniqueId, c_images;
IF done THEN
LEAVE importloop;
END IF;
CALL upsert_article(c_ean, c_sku, c_mpn, c_manufacturerName, c_manufacturerUniqueId, c_images);
END LOOP importloop;
CLOSE import_cursor;
DROP TEMPORARY TABLE IF EXISTS importjob;
END