【发布时间】:2016-07-25 03:18:01
【问题描述】:
我查看了类似查询的答案,但继续收到另一个错误,似乎无法通过添加创建 proc 的架构来解决。
这是我尝试运行的代码:
create or replace procedure prcReturnDVD
-- define the parameters that this proc will accept
(memberid_in integer, dvd_in integer)
is
-- Define local variables
vNumRem number(2);
BEGIN
-- Update the rental table with the current date
update rental set rentalreturneddate = current_date where memberid = memberid_in and dvdid = dvd_in;
-- update DVD quantityonhand to reflect the return
update dvd set dvdquantityonhand = dvdquantityonhand + 1 where dvdid = dvd_in;
-- Check to see how many DVDs are available for rent for this member
select get_rentalsremaining(memberid_in) into vNumRem from dual;
-- Evaluate the next action depending on number of remaining DVD rentals available
if vNumRem >= 1 then
-- need to write a for loop in order to cycle through the DVDs that need to be shipped out
while vNumRem >= 0
loop
SYSTEM.prcShipNextDVD(memberid_in);
vNumRem := vNumRem - 1;
end loop;
elsif vNumRem = 0 then
-- message that no rentals are allowed
dbms_output.put_line('No more rentals allowed.');
end if;
EXCEPTION
WHEN NO_DATA_FOUND THEN
dbms_output.put_line('No Data Returned, process failed.');
WHEN TOO_MANY_ROWS THEN
dbms_output.put_line('Too many rows returned into variable, check data and try again.');
WHEN OTHERS THEN
dbms_output.put_line('An unidentified error has occured. Please research issue with procedure.');
END;
/
在 LOOP 语句中,我试图调用由同一用户先前编写的另一个过程(我使用 SYSTEM 只是因为它只是一个家庭作业并且它简化了权限):
create or replace procedure prcShipNextDVD
-- define the parameters that this proc will accept
(memberid_in integer)
is
-- Define local variables
vCountOut number(2);
vAllowedOut number(2);
vNextDvd number(16);
vAddedInQueue date;
vPlaceInQueue number(5);
BEGIN
-- ensure the member is eligible to take out another DVD at this time
-- See how many movies the member currently has out
select count(*) into vCountOut from rental where memberid = memberid_in and rentalreturneddate is null;
-- See how many movies the member is allowed to have out
select membershiplimitpermonth into vAllowedOut from membership m, member p where m.membershipid = p.membershipid and p.memberid = memberid_in;
IF vCountOut < vAllowedOut then
-- If the number out currently is less than the number allowed out currently
-- Get next DVD in queue available for shipment
select get_nextdvd(memberid_in) into vNextDVD, datedaddedinqueue into vAddedInQueue, rentalpriority into vPlaceInQueue from rentalqueue where memberid = memberid_in;
-- create new record in rental table for this shipment
insert into rental (rentalid, memberid, dvdid, rentalrequestdate, rentalshippeddate) values (rental_seq.nextval, memberid_in, vNextDVD, vAddedInQueue, current_date);
-- decrement dvdquantityon hand in dvd table
update dvd set quantityonhand = quantityonhand - 1 where dvdid = vNextDVD;
-- remove dvd from queue
delete from rentalqueue where memberid = memberid_in and dvdid = vNextDVD ;
-- manage remaining rentalpriority records by decrementing them properly (like in 2.1)
update rentalqueue set rentalpriority = rentalpriority - 1 where memberid = memberid_in and rentalpriority >= vPlaceInQueue;
ELSE
-- If the member already has the maximum number of movies out at this time
RAISE_APPLICATION_ERROR(-20101, 'Maximum number of movies out reached. You are not allowed to check out another movie at this time.');
END IF;
EXCEPTION
WHEN NO_DATA_FOUND THEN
dbms_output.put_line('No Data Returned, process failed.');
WHEN TOO_MANY_ROWS THEN
dbms_output.put_line('Too many rows returned into variable, check data and try again.');
WHEN OTHERS THEN
dbms_output.put_line('An unidentified error has occured. Please research issue with procedure.');
END;
/
即使将架构名称添加到过程调用后,我也会收到以下错误。我也试过用“执行”和“调用”来运行它,但知道它们不能正常工作。
PROCEDURE PRCRETURNDVD compiled
Errors: check compiler log
19/7 PL/SQL: Statement ignored
19/14 PLS-00905: object SYSTEM.PRCSHIPNEXTDVD is invalid
关于我在这方面做错了什么还有其他建议吗?
我正在调用的过程存在问题,但它确实可以编译。
【问题讨论】:
-
Oracle 允许使用不同的参数列表编译相同的过程。因此,您可以存储同一过程的多个“版本”。这称为重载。例如,您可以拥有 myadd(n1 pls_integer, n2 pls_integer) 和 myadd (n1 pls_integer, n2 pls_integer, n3 pls_integer),Oracle 将保留这两个版本的过程。确保您编译的过程没有错误,与您尝试调用的过程具有相同的参数类型。对于故障排除,我会尝试从 SQL 命令行调用一个存储的 proc,而不是从另一个 proc。
-
我之前有一个我打电话给我的人,但现在……看来我已经把它弄坏了:-/
-
对..再想想,这可能与有几个版本浮动无关。因为我认为除了在包内之外你不能进行重载。编译后,有一个命令“显示错误”来列出遇到的任何错误。 prcshipnextdvd 的编译返回干净,然后“显示错误”也干净了吗?
-
点击返回太快...关于为什么这会导致我立即出现错误的任何想法?
select count(dvdid) into vCountOut from rental where memberid = memberid_in and rentalreturneddate is null;错误指向我在哪里进行计数并将其放入我的局部变量之一。我试过 count(*) 和 count(dvdid) 来查看是否是引用不明确的问题。这两个仍然产生以下错误:20/5 PL/SQL: SQL Statement ignored20/70 PL/SQL: ORA-00923: FROM keyword not found where expected -
很好,我想我明白了如何在你的例子中继续前进,因为我看到了它给出的实际错误。你的错误在 prcshipnextdvd 的第 20 行。一旦你用多个修复了这个错误进入语句,再次编译并修复错误,直到它干净为止。选择应该是
select 1, 2, 3 into var1, var2, var3。写select 1 into var1, 2 into var2, 3 into var3无效。