如何使用 PL/SQL 显示数据库中的多个元组?

How to use PL/SQL to display many tuples from a database?

我正在尝试使用 PL/SQL 显示来自两个表的数据,其中飞行持续时间在某个输入范围之间。因为我是新手,所以我很难弄清楚我哪里出错了。 Flights.arrives 和 Flights.depart 数据成员是时间戳,这可能是我最大的问题。

problem1.sql

SET serveroutput ON

accept leftLimit prompt "Enter minimum time(min): ";
accept rightLimit prompt "Enter maximum time(min): ";

DECLARE
    flightNo varchar2(20);
    fromAirport varchar2(20);
    toAirport varchar2(20);
    duration varchar2(20);

CURSOR myTuplesCursor IS 
    SELECT Flights.flightNo, 
            Flights.fromAirport, 
            Flights.toAirport, 
            Flights.arrives - Flights.depart 
    FROM Aircraft, Flights 
    WHERE Aircraft.airplaneID = Flights.airplaneID 
    AND (Flights.arrives - Flights.depart)
        BETWEEN &leftLimit AND &rightLimit;

BEGIN
    OPEN myTuplesCursor; -- run the query

    LOOP
        -- Get tuples from data
        FETCH myTuplesCursor INTO flightNo, fromAirport, toAirport, duration ;
        EXIT WHEN myTuplesCursor%NOTFOUND;

        -- Display tuples of data
        dbms_output.put_line('Flight #: ' || flightNo );
        dbms_output.put_line('From: ' || fromAirport );
        dbms_output.put_line('To: ' || toAirport );
        dbms_output.put_line('Duration: ' || duration );
    END LOOP;

    CLOSE myTuplesCursor; -- end the query
END;
/

输出

SQL> @problem1
Enter minimum time(min): '+000000000 01:15:00.000000'
Enter maximum time(min): '+000000000 03:15:00.000000'
old 16:                 BETWEEN &leftLimit AND &rightLimit;
new 16:                 BETWEEN +000000000 01:15:00.000000 AND +000000000 03:15:00.000000;
DECLARE
*
ERROR at line 1:
ORA-06502: PL/SQL: numeric or value error
ORA-06512: at line 22

我在这里看到的明显错误是您的 Cursor 声明。声明显式游标时不得使用 INTO 子句。另外,正如@Kaushik 提到的,不清楚 Flights.arrivesFlights.depart 的数据类型是什么,很难回答您的查询。按如下方式修改您的代码并尝试:

   CURSOR myTuplesCursor IS 
    SELECT Flights.flightNo, 
            Flights.fromAirport, 
            Flights.toAirport, 
            Flights.arrives - Flights.depart 
    --<-- You should not use into clause while using a cursor. Remove it.
    --INTO flightNo, fromAirport, toAirport, duration  FROM Aircraft, Flights 
    WHERE Aircraft.airplaneID = Flights.airplaneID 
    AND (Flights.arrives - Flights.depart) BETWEEN &leftLimit AND &rightLimit;

编辑:

The datatypes of Flights.arrives and Flights.depart are timestamps, and I am trying to subtract the depart from arrives to figure the duration of the flight.

一般来说,如果你想subtract两个timestamps那么就可以按图做。

SQL> select TO_TIMESTAMP('03:15:00.000000', 'HH24:MI:SS.FF') - TO_TIMESTAMP('01:15:00.000000', 'HH24
:MI:SS.FF') tp from dual;

TP
---------------------------------------------------------------------------
+000000000 02:00:00.000000000

既然你的专栏已经 timestamp 就没必要再投了。您可以在 between 子句中使用传递的值,如图所示。

SELECT 1
FROM
  (SELECT TO_TIMESTAMP('03:15:00.000000', 'HH24:MI:SS.FF') - TO_TIMESTAMP('01:15:00.000000', 'HH24:MI:SS.FF') tp
  FROM dual
  )
WHERE tp BETWEEN '+000000000 01:15:00.000000' AND '+000000000 03:15:00.000000' ;

既然你现在知道如何在你的块中减去两个时间戳,你需要声明一个变量来保存你的块中的结果。

我看到您尝试将减法结果保存在变量 duration varchar2(20); 中,这是正确的,但是字符串 buffer 显得太短,因此您遇到了错误。为了安全起见,您必须将其更改为 duration varchar2(100);。见下文:

您将遇到如下所示的错误:

DECLARE
  duration VARCHAR2(20);  
BEGIN
  SELECT TO_TIMESTAMP('03:15:00.000000', 'HH24:MI:SS.FF') - TO_TIMESTAMP('01:15:00.000000', 'HH24:MI:SS.FF') tp
  INTO duration
  FROM dual;
  dbms_output.put_line('Duration: ' || duration );
END;

错误:

Error report:
ORA-06502: PL/SQL: numeric or value error
ORA-06512: at line 4
06502. 00000 -  "PL/SQL: numeric or value error%s"
*Cause:    
*Action:

当您将变量大小更改为 100 时,块将成功完成,如下所示:

DECLARE
  duration VARCHAR2(100);  
BEGIN
  SELECT TO_TIMESTAMP('03:15:00.000000', 'HH24:MI:SS.FF') - TO_TIMESTAMP('01:15:00.000000', 'HH24:MI:SS.FF') tp
  INTO duration
  FROM dual;
  dbms_output.put_line('Duration: ' || duration );
END;

输出:

Duration: +000000000 02:00:00.000000000

PL/SQL procedure successfully completed.