【问题标题】:Oracle error while running created procedure运行创建的过程时出现 Oracle 错误
【发布时间】:2013-02-12 04:43:15
【问题描述】:

我有基于酒店房间住宿的 Oracle 数据库。 我创建了一个程序 Room_taken,但我无法让它工作。

这是我的 SQL 过程代码:

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;

当我输入以下参数后运行程序时:

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.

我做错了什么?

【问题讨论】:

    标签: oracle plsql procedure


    【解决方案1】:

    您收到错误是因为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
    

    【讨论】:

    • 我明白了。我现在可以在表中输入新的住宿数据,但是如果同一时间已经有人在同一个房间里,我不能使用你的代码引发“房间被占用”错误......这就是我需要这个程序的原因。我仍然对如何做到这一点感到困惑。
    • @drazen 您正在插入NOCENJE 表并检查STAYOVER 表。如果您在两种情况下都使用同一张桌子,您应该得到“房间被占用!”提前预订时出错。
    • 对不起,我的错。我在代码中输入了错误的列...它正在工作,非常感谢:)
    【解决方案2】:

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

    错误原因

    您尝试了以下方法之一:

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-02-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-08-01
      相关资源
      最近更新 更多