【问题标题】:Oracle cursor loop that calls stored procedure调用存储过程的Oracle游标循环
【发布时间】:2019-08-12 10:17:10
【问题描述】:

如何创建一个调用存储过程的循环? 我有一个包含产品列表的表,我想使用存储过程对照表检查它。

示例表格内容:

  • 苹果
  • 橙色
  • 香蕉

在本例中,我想使用参数执行此过程 3 次:(苹果、橙子、香蕉)。

我无法使用光标来工作...

DECLARE
  CURSOR cur_product
  IS
    SELECT product_name FROM test.products;
BEGIN
  FOR product IN cur_product
  LOOP
    BEGIN
        EXECUTE TEST_PRODUCT( product);
    END;
  END LOOP;
END;

存储过程:

CREATE OR REPLACE PROCEDURE TEST_PRODUCT 
(
  PRODUCT IN VARCHAR2 
) AS 
BEGIN
  INSERT INTO TABLE test.product_counts
  SELECT COUNT(*) FROM test.products WHERE product_name = &PRODUCT

END TEST_PRODUCT;

【问题讨论】:

  • execute 在 PL/SQL 中不需要调用存储过程。并且在 PL/SQL 中也不使用& 引用参数。
  • 但您不需要循环或存储过程来执行此操作。而test.product_counts如果不将产品名称和计数一起存储有什么用?

标签: oracle loops stored-procedures plsql cursor


【解决方案1】:

您不需要在 for 循环中放置另一个 begin end 块。也执行立即不需要你做这项工作。传递参数时不需要使用'&'。

DECLARE
  CURSOR cur_product`enter code here`
  IS
    SELECT product_name FROM test.products;
BEGIN
  FOR product IN cur_product
  LOOP
        TEST_PRODUCT( product);
  END LOOP;
END;

存储过程(不要忘记 COMMIT 语句):

CREATE OR REPLACE PROCEDURE TEST_PRODUCT 
(
  PRODUCT IN VARCHAR2 
) AS 
BEGIN
  INSERT INTO test.product_counts
  SELECT COUNT(*) FROM test.products WHERE product_name = PRODUCT;

COMMIT;

END TEST_PRODUCT;

【讨论】:

    【解决方案2】:

    试试这个:

    DECLARE
      CURSOR cur_product
      IS
        SELECT product_name FROM test.products;
    BEGIN
      FOR product IN cur_product
      LOOP
        BEGIN
            -- removed execute and added .product_name
            TEST_PRODUCT( product.product_name); 
        END;
      END LOOP;
    END;
    

    存储过程:

    CREATE OR REPLACE PROCEDURE TEST_PRODUCT 
    (
      PRODUCT IN VARCHAR2 
    ) AS 
    BEGIN
      INSERT INTO TABLE test.product_counts
      SELECT COUNT(*) FROM test.products WHERE product_name = PRODUCT -- removed ampersand
    
    END TEST_PRODUCT;
    

    干杯!!

    【讨论】:

      【解决方案3】:

      最简单的版本是:

      begin
          for r in (
              select dummy from dual
          )
          loop
              dbms_output.put_line(r.dummy);
          end loop;
      end;
      

      请注意,除非您确实需要 cursor attribute,否则您不必显式声明游标。

      此外,现代编程通常不会以大写形式进行。

      【讨论】:

        【解决方案4】:

        您可以在测试模式中创建它:

        CREATE OR REPLACE PROCEDURE TEST_PRODUCT 
        (
          PRODUCT IN VARCHAR2 
        ) AS 
        BEGIN
          INSERT INTO  product_counts(productCounts)  SELECT COUNT(*) FROM products 
        WHERE product_name = PRODUCT;
        
        END TEST_PRODUCT;
        
        DECLARE
          CURSOR cur_product
          IS
           SELECT distinct PRODUCT_NAME FROM products;
        BEGIN
          FOR product IN cur_product
        LOOP
        BEGIN
             TEST_PRODUCT( product.product_name);
        END;
        END LOOP;
        END;
        

        我在游标中添加了不同的product_name,这是因为product_counts 表中不会有重复的产品。如果您想在该表中使用重复的产品名称,您可以省略 distinct。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2017-02-16
          • 1970-01-01
          • 2011-03-14
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-04-29
          相关资源
          最近更新 更多