【问题标题】:Loop over table and call stored procedure循环表并调用存储过程
【发布时间】:2016-05-27 20:46:55
【问题描述】:

现在,我正在尝试遍历导入过程创建的临时表。我尝试过使用游标,但必须将表名传递给存储过程。

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

注意:此导入脚本将在一天内多次调用,并且可以同时运行。所以定义的表名不是一个选项。

到目前为止我所尝试的:

  1. 使用给定的表名创建游标。 --> 有效,但名称必须是动态的。
  2. 使用动态 sql 创建游标。 --> 失败
  3. 使用游标跳过并以不同的方式循环遍历表。 --> 没有找到使用动态sql的方法

那么,有没有办法使用光标或变通方法来完成这项工作?

【问题讨论】:

    标签: mysql loops stored-procedures cursor


    【解决方案1】:

    创建一个临时表并插入我的动态查询的结果最终起到了作用。 这样我就可以使用带有静态命名临时表的mysql游标。而且由于它是一个临时表,因此多个导入作业不会相互干扰,因为它们对其他会话是隐藏的。

    最后,这是对我有用的代码:

    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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-01-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多