尝试使用 DBMS_OUTPUT.PUT_LINE 访问嵌套表列时必须声明组件

Component must be declared when trying to access nested tables columns using DBMS_OUTPUT.PUT_LINE

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

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;
/

如果您使用带引号的标识符为列设置别名(如 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;
/

我的建议是使用不带引号的别名 - 这总是有效的,但如果你想让它更复杂 - 嘿,这是你的代码 ;)