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列表中的值数错误。
答案 0 :(得分:1)
如果您正在运行Oracle 12c及更高版本,只需将DBMS_SQL.RETURN_RESULT
与REF
光标一起使用。不需要循环或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;