Как использовать PL / SQL для отображения множества кортежей из базы данных? - PullRequest
0 голосов
/ 27 ноября 2018

Я пытаюсь использовать PL / SQL для отображения данных из двух таблиц, где длительность полета находится в некотором диапазоне ввода.У меня проблемы с выяснением, где я иду не так, так как я новичок в этом.Членами данных Tickets.arrives и Tickets.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

1 Ответ

0 голосов
/ 27 ноября 2018

Очевидной ошибкой, которую я вижу здесь, является ваша Cursor декларация.Вы не должны использовать предложение INTO при объявлении явного курсора.Кроме того, как упоминает @Kaushik, не ясно, каковы типы данных Flights.arrives & Flights.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;

РЕДАКТИРОВАТЬ:

Типы данных Авиабилеты.пытается вычесть вылет из прибывшего, чтобы определить продолжительность полета.

В общем, если вы хотите 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.
...