【问题标题】:Component must be declared when trying to access nested tables columns using DBMS_OUTPUT.PUT_LINE尝试使用 DBMS_OUTPUT.PUT_LINE 访问嵌套表列时必须声明组件
【发布时间】:2021-07-27 02:48:37
【问题描述】:

我在访问嵌套表列时遇到问题,当我尝试执行该过程时出现以下错误。我创建了一个名为 order_items 的类型,其中包含下面的列,并将此类型嵌套在我的订单表中,但不确定如何访问这些列。

37/1     PL/SQL: Statement ignored
37/53    PLS-00302: component 'SUB_ORDER_NUMBER' must be declared
41/1     PL/SQL: Statement ignored
41/45    PLS-00302: component 'QUANTITY' must be declared
42/1     PL/SQL: Statement ignored
42/46    PLS-00302: component 'CONDITION' must be declared
43/1     PL/SQL: Statement ignored
43/47    PLS-00302: component 'UNIT_PRICE' must be declared
44/1     PL/SQL: Statement ignored
44/48    PLS-00302: component 'COST_CHARGE' must be declared
CREATE OR REPLACE PROCEDURE find_product 
(prod_no IN INT) AS 
CURSOR p IS SELECT 
            O.order_id,
            O.order_number, 
            O.billing_name, 
            O.billing_email, 
            O.billing_address, 
            O.billing_city, 
            O.billing_province, 
            O.billing_postcode, 
            O.billing_telephone, 
            O.billing_total,
            O.order_date, 
            I.sub_order_number "sub_order_number", 
            I.quantity "quantity", 
            I.condition "condition", 
            I.unit_price "unit_price", 
            I.cost_charge "cost_charge", 
            product.name AS product_name,
            product.description,
            product.category
            FROM orders O, TABLE (O.Items) I
            JOIN product ON product.product_id = I.product_id
            WHERE I.product_id = prod_no;
    BEGIN
    FOR p_rec IN p LOOP
        DBMS_OUTPUT.PUT_LINE ('Order Date: ' || p_rec.order_date);
        DBMS_OUTPUT.PUT_LINE ('Order Number: ' || p_rec.order_number);
        DBMS_OUTPUT.PUT_LINE ('Customer Name: ' || p_rec.billing_name);
        DBMS_OUTPUT.PUT_LINE ('Customer Email: ' || p_rec.billing_email);
        DBMS_OUTPUT.PUT_LINE ('Customer Address: ' || p_rec.billing_address);
        DBMS_OUTPUT.PUT_LINE ('Customer City: ' || p_rec.billing_city);
        DBMS_OUTPUT.PUT_LINE ('Customer Province: ' || p_rec.billing_province);
        DBMS_OUTPUT.PUT_LINE ('Customer Postcode: ' || p_rec.billing_postcode);
        DBMS_OUTPUT.PUT_LINE ('Customer Telephone: ' || p_rec.billing_telephone);
        DBMS_OUTPUT.PUT_LINE ('Sub Order Number: ' || p_rec.sub_order_number);
        DBMS_OUTPUT.PUT_LINE ('Product: ' || p_rec.product_name);
        DBMS_OUTPUT.PUT_LINE ('Product Description: ' || p_rec.description);
        DBMS_OUTPUT.PUT_LINE ('Product Category: ' || p_rec.category);
        DBMS_OUTPUT.PUT_LINE ('Quantity: ' || p_rec.quantity);
        DBMS_OUTPUT.PUT_LINE ('Condition: ' || p_rec.condition);
        DBMS_OUTPUT.PUT_LINE ('Unit Price: ' || p_rec.unit_price);
        DBMS_OUTPUT.PUT_LINE ('Cost Charge: ' || p_rec.cost_charge);
        DBMS_OUTPUT.PUT_LINE ('Total: ' || p_rec.billing_total);
        DBMS_OUTPUT.PUT_LINE ('------------------------------------------------' || null);
    END LOOP;
    EXCEPTION
    WHEN no_data_found THEN 
    DBMS_OUTPUT.PUT_LINE ('prod_no does not exist'); 
    WHEN OTHERS THEN DBMS_OUTPUT.PUT_LINE ('Operation failed  ' || 
        'SQLCODE: ' || SQLCODE); DBMS_OUTPUT.PUT_LINE ('SQL Error Message ' || SQLERRM);
    ROLLBACK;
END;
/

【问题讨论】:

    标签: oracle plsql oracle11g


    【解决方案1】:

    如果您使用带引号的标识符(如I.sub_order_number "sub_order_number")为列添加别名,那么您需要在引用该别名时完全匹配该别名。如果引号之间的字符串仅为大写字母(无空格),则可以省略引号。以下所有选项都将起作用(这是一个带有 emp/dept 示例数据的示例。

    DECLARE
      CURSOR c1 IS
        SELECT ename as "name",
               empno as "NO",
               job as JOB,
               hiredate AS "Fancy Alias !",
               mgr as mgr
               
          FROM emp
          WHERE ename = 'KING';
    BEGIN
      FOR rec IN c1 LOOP
        dbms_output.put_line('name: '||rec."name");
        dbms_output.put_line('NO: '||rec.NO);
        dbms_output.put_line('JOB: '||rec.JOB);
        dbms_output.put_line('Fancy Alias !: '||rec."Fancy Alias !");
        dbms_output.put_line('mgr: '||rec.mgr);
      END LOOP;
    END;
    /
    

    我的建议是使用没有 qoutes 的别名——这总是有效的,但如果你想让它更复杂——嘿,这是你的代码;)

    【讨论】:

    • 谢谢你没有意识到我必须使用带引号的标识符,感谢帮助
    • 你没有 - 如果你不这样做,它会更“干净”我只是用更多例子更新了我的答案
    猜你喜欢
    • 1970-01-01
    • 2016-08-11
    • 2019-01-25
    • 1970-01-01
    • 1970-01-01
    • 2021-01-06
    • 2021-08-13
    • 1970-01-01
    • 2012-05-19
    相关资源
    最近更新 更多