【问题标题】:Subscription beyond count with bulk collect批量收集的订阅数不胜数
【发布时间】:2021-11-15 22:19:21
【问题描述】:

您好,我遇到了错误:订阅数不胜数。我有一个创建订单的程序(为了代码的清晰,这部分被删除)。程序从篮子中挑选产品,然后降低循环中仓库(可以有 1 个或多个仓库)中特定产品的数量。你能解释一下我做错了什么吗?非常感谢。

这是我的程序的主体:

PROCEDURE cpr_create_order (pin_intCustomer       IN customer.customer_id%TYPE,
                            pin_strPayment        IN payment.payment_type%TYPE,
                            pin_strTransp         IN transp.transp_type%TYPE,
                            pout_strErrorCode     OUT NUMBER,
                            pout_strErrorMessage  OUT VARCHAR2)
IS

    lv_warehouse_balance    NUMBER;
    lv_intQuantity          NUMBER;
    lv_intOrder             NUMBER;
    
    TYPE collection_list IS TABLE OF NUMBER;
    lv_products     collection_list := collection_list();
    lv_quantities   collection_list := collection_list();
    
    lv_warehouses   collection_list := collection_list();
    lv_balances     collection_list := collection_list();
    
BEGIN
    pout_strErrorCode    := 0;
    pout_strErrorMessage := '';
    
    SAVEPOINT S1;
        
        -- fill collections of products and quantities from basket
        SELECT product_id, basket_quantity
        BULK COLLECT INTO lv_products, lv_quantities
        FROM basket
        WHERE order_id IS NULL
        ORDER BY product_id;
        
        FOR i IN 1.. lv_products.COUNT LOOP    -- 1
            
             -- fill collection of warehouses and actual product balances
             SELECT warehouse_id, product_balance  --1,2   -- 5,10
             BULK COLLECT INTO lv_warehouses, lv_balances
             FROM warehouse
             WHERE product_id = lv_products(i)
             ORDER BY warehouse_id;
             
             lv_intQuantity := lv_quantities(i);   --8
             
             FOR j IN 1..lv_warehouses.COUNT LOOP
                IF lv_intQuantity > 0 THEN
                    SELECT product_balance
                    INTO lv_warehouse_balance
                    FROM warehouse
                    WHERE product_id = lv_products(i)
                    AND warehouse_id = lv_warehouses(j);
                    
                    -- lower the balance of the product at the warehouse by the given quantity
                    IF lv_intQuantity < lv_warehouse_balance THEN   --8 --10
                        UPDATE warehouse
                        SET product_balance = product_balance - lv_intQuantity
                        WHERE product_id = lv_products(i)
                        AND warehouse_id = lv_warehouses(j);
                        
                        lv_intQuantity := lv_intQuantity - lv_intQuantity; -- 0
                    
                    -- remove product from the warehouse    
                    ELSIF lv_intQuantity >= lv_warehouse_balance THEN
                        DELETE FROM warehouse
                        WHERE product_id = lv_products(i)
                        AND warehouse_id = lv_warehouses(j);
                        
                        lv_intQuantity := lv_intQuantity - lv_balances(i);
                        
                    END IF;
                END IF;
             END LOOP;  
        END LOOP;     
    
EXCEPTION
    WHEN OTHERS THEN
      pout_strErrorCode := -1;
      pout_strErrorMessage  := substr(SQLERRM,
                                instr(SQLERRM, 'ORA') + 11,
                                length(SQLERRM));
      ROLLBACK TO S1;
END cpr_create_order;

【问题讨论】:

  • 你遇到了什么 Oracle 错误?
  • 订阅数不胜数
  • 这篇文章对你有帮助asktom.oracle.com/pls/apex/…
  • 我将尝试复制该问题。能贴出过程中涉及的表的DDL结构吗?
  • @AlexPoole,你是完全正确的。我的错误;)

标签: sql oracle plsql


【解决方案1】:

这一行:

lv_intQuantity := lv_intQuantity - lv_balances(i);

应该是:

lv_intQuantity := lv_intQuantity - lv_balances(j);

lv_productslv_quantities 集合由第一个批量集合填充,因此它们具有相同数量的成员,并且应该由相同的变量 i 进行索引 - 您正在这样做。

lv_warehouseslv_balances 集合由第二个批量收集填充,因此它们具有相同数量的成员,并且应该由相同的变量 j 进行索引。

你不应该参考lv_balances(i) - 它有时会给出一个结果,但它不会是你所期望的,当j 低于i 它会得到这个错误,因为没有成员在该集合中索引i

【讨论】:

  • 非常感谢亚历克斯!这解决了问题
  • @Alex Poole,很好看!
猜你喜欢
  • 2010-12-24
  • 2015-11-24
  • 1970-01-01
  • 1970-01-01
  • 2013-12-07
  • 1970-01-01
  • 1970-01-01
  • 2016-03-20
  • 1970-01-01
相关资源
最近更新 更多