如何通过使用游标从oracle数据库中检索数据?

时间:2019-05-09 07:19:17

标签: sql oracle plsql

set serveroutput on;
CREATE OR REPLACE PROCEDURE invoice_report AS


orderDetail Orders%ROWTYPE;

CURSOR c_order IS 
    SELECT Orders.ono AS OrderNo,
        Customer.cno AS CustomerNo,
        Customer.cname AS CustomerName,
        Orders.shipped AS OrderDate,
        Part.pno AS PartNo,
        Part.pname AS PartName,
        OrderItem.qty AS Quantity,
        Part.price AS Price 
    FROM Orders,Customer,Part,OrderItem where Orders.ono='&order_no';


BEGIN
    Open c_order;
Loop
    FETCH c_order INTO orderDetail;
    EXIT WHEN c_order %NOTFOUND;
    DBMS_OUTPUT.PUT_LINE(orderDetail);
END LOOP;
    Close c_order;
ENd;
/

我是PL / SQL的新手,尤其是使用游标。我要执行invoice_report,然后在客户输入订单号后显示他们的订单明细。 然后显示错误信息: PLS-00394 FETCH语句的INTO列表中的值数错误。

2 个答案:

答案 0 :(得分:1)

如果您正在运行Oracle 12c及更高版本,只需将DBMS_SQL.RETURN_RESULTREF光标一起使用。不需要循环或dbms_output

请注意,过程的主体不应具有接收用户输入的代码。可以将其作为参数传递。

set serveroutput on
CREATE OR REPLACE PROCEDURE invoice_report(p_orderno Orders.ono%TYPE) AS
c_order SYS_REFCURSOR;
BEGIN
OPEN  c_order FOR 
    SELECT Orders.ono AS OrderNo,
        Customer.cno AS CustomerNo,
        Customer.cname AS CustomerName,
        Orders.shipped AS OrderDate,
        Part.pno AS PartNo,
        Part.pname AS PartName,
        OrderItem.qty AS Quantity,
        Part.price AS Price 
    FROM Orders,Customer,Part,OrderItem where Orders.ono=p_orderno; --The argument
                    --Change it to explicit join syntax
   DBMS_SQL.RETURN_RESULT(c_order);
END;
/

现在,用户可以在执行过程中传递值。

BEGIN
  invoice_report('&order_no');
END;
/

答案 1 :(得分:-1)

原因: FETCH语句的INTO子句中的变量数与游标声明中的列数不匹配。

解决方案: 更改INTO子句中的变量数或游标声明中的列数,以使数字匹配。

CREATE OR REPLACE PROCEDURE invoice_report
AS


    CURSOR c_order
    IS
        SELECT   orders.ono AS orderno,
                 customer.cno AS customerno,
                 customer.cname AS customername,
                 orders.shipped AS orderdate,
                 part.pno AS partno,
                 part.pname AS partname,
                 orderitem.qty AS quantity,
                 part.price AS price
          FROM   orders,
                 customer,
                 part,
                 orderitem
         WHERE   orders.ono = '&order_no';
    orderdetail   c_order%ROWTYPE;
BEGIN

    FOR orders IN orderdetail   
    LOOP
        DBMS_OUTPUT.PUT_LINE(orders.orderDetail);
    END LOOP;
END;