2013-02-26 70 views
2

我有基于酒店房间停留的Oracle数据库。 我创建了一个过程Room_taken,我无法使它工作。运行创建的过程时出现Oracle错误

这是我的SQL程序代码:

DECLARE 
v_guestID NUMBER; 
v_stayfrom DATE; 
v_stayto DATE; 
v_roomID NUMBER; 
v_paymentID NUMBER; 
v_totalprice NUMBER; 
BEGIN 
v_guestID := 1; 
v_stayfrom := '17.01.2012'; 
v_stayto := '19.01.2012'; 
v_roomID := 1; 
v_paymentID := 1; 
v_totalprice := 300; 

Room_taken(
v_guestID => v_guestID, 
v_stayfrom => v_stayfrom, 
v_stayto => v_stayto, 
v_roomid => v_roomid, 
v_paymentID => v_paymentID, 
v_totalprice => v_totalprice 
); 
END; 

我得到了一个错误:

Connecting to the database HOTEL. 
ORA-01403: no data found 
ORA-06512: at "HOTEL_ROOMS.ROOM_TAKEN", line 18 
ORA-06512: at line 16 
Process exited. 
Disconnecting from the database HOTEL. 

CREATE 
PROCEDURE Room_taken 
(
v_guestID IN NUMBER DEFAULT NULL , 
v_stayfrom IN DATE DEFAULT NULL , 
v_stayto IN DATE DEFAULT NULL , 
v_roomID IN NUMBER DEFAULT NULL , 
v_paymentID IN NUMBER DEFAULT NULL , 
v_totalprice IN NUMBER DEFAULT NULL 
) 
AS 
v_nofrom DATE; 
v_noto DATE; 
v_idroom NUMBER(10,0); 

BEGIN 

BEGIN 
SELECT Stay_from, Stay_to  
INTO v_nofrom, v_noto 
FROM Stayover 
WHERE ID_room = v_roomID; 
IF NOT (v_nofrom >= v_stayfrom 
AND v_noto <= v_stayto) THEN 

BEGIN 
INSERT INTO Stayover 
(Stay_from, Stay_to, Total_price, ID_Room, ID_Guest, ID_Payment) 
VALUES (v_stayfrom, v_stayto, v_totalprice, v_roomID, v_guestID, v_paymentID); 
END; 
ELSE 

BEGIN 
raise_application_error(-20002, 'Room is taken!'); 
END; 
END IF; 
END; 
END; 

当我输入下面的参数后运行程序

我在做什么错?

回答

4

由于SELECT INTO构造必须在PL/SQL中必须返回正好1行,所以出现错误。您的第一个选择不会返回任何行,因此会引发NO_DATA_FOUND错误。

如果有2行(例如1月的预留,2月的另一个预留),则会引发TOO_MANY_ROWS错误。

你想要做的,是确保如果你插入,将有不重叠。例如,下面的查询会期间返回所有的预订:

SELECT * 
    FROM Stayover 
WHERE ID_room = v_roomID 
    AND stay_from <= v_stayto 
    AND stay_to >= v_stayfrom 

请注意,我比较stay_fromv_stayto,这不是一个错字。

你可以包括上述查询到你的代码是这样的:

CREATE OR REPLACE PROCEDURE Room_taken(v_guestID IN NUMBER, 
             v_stayfrom IN DATE, 
             v_stayto  IN DATE, 
             v_roomID  IN NUMBER, 
             v_paymentID IN NUMBER DEFAULT NULL, 
             v_totalprice IN NUMBER DEFAULT NULL) AS 
    l_nb_reservation NUMBER; 
BEGIN 
    SELECT COUNT(*) 
    INTO l_nb_reservation 
    FROM Stayover 
    WHERE ID_room = v_roomID 
     AND stay_from <= v_stayto 
     AND stay_to >= v_stayfrom; 
    IF l_nb_reservation > 0 THEN 
     raise_application_error(-20002, 'Room is taken!'); 
    END IF; 

    INSERT INTO Stayover 
     (Stay_from, Stay_to, Total_price, ID_Room, ID_Guest, ID_Payment) 
    VALUES 
     (v_stayfrom, v_stayto, v_totalprice, v_roomID, v_guestID, v_paymentID); 
END; 

现在,您将能够每周期只有一次预订:

SQL> EXEC Room_taken(1, trunc(SYSDATE), trunc(SYSDATE), 1); 

PL/SQL procedure successfully completed 

SQL> EXEC Room_taken(1, trunc(SYSDATE), trunc(SYSDATE), 1); 

begin Room_taken(1, trunc(SYSDATE), trunc(SYSDATE), 1); end; 

ORA-20002: Room is taken! 
ORA-06512: à "APPS.ROOM_TAKEN", ligne 16 
ORA-06512: à ligne 2 
+0

我知道了。我现在可以在表格中输入新的数据,但是如果您的代码已经有人在同一个房间,那么我无法提出'房间被占用'的错误......这就是为什么我需要这个程序。我仍然对如何做到这一点感到困惑。 – Drazen 2013-02-26 17:15:24

+0

@drazen你插入到'NOCENJE'表中并且检查'STAYOVER'表。如果你在这两种情况下使用同一张桌子,你应该得到“房间被采取!”在事先预约的情况下出现错误。 – 2013-02-26 17:33:44

+0

对不起,我的坏。我在代码中输入错误的列...这是工作,非常感谢:) – Drazen 2013-02-26 17:38:24

1

错误消息
ORA-01403:找不到数据

错误原因

您试图执行下列操作之一:

  1. 您执行SELECT INTO语句并没有返回行。
  2. 您在表中引用了未初始化的行。
  3. 您使用UTL_FILE包读取文件末尾。

要显示的建议解决方案
检查此链接
http://www.techonthenet.com/oracle/errors/ora01403.php