2013-12-05 3 views
1

Так что я пишу функцию для oracle db, но получаю ошибки, говорящие, что инструкции sql игнорируются и поэтому отсутствуют выражения.Операторы SQL игнорируются в PL/SQL

Функция:

CREATE OR REPLACE FUNCTION getQueueNumber 
(student IN VARCHAR,course IN CHAR) 
RETURN INT 
IS 
    queuePosition INT; 
    date TIMESTAMP; 
    BEGIN 
     SELECT waitingDate INTO date 
     FROM WaitingCourseStudent wcs 
     WHERE wcs.student=student AND wcs.course=course; 
     IF SQL%NOTFOUND THEN queuePosition := NULL; 
     ELSE 
      SELECT COUNT(*) as pos 
      INTO queuePosition 
      FROM WaitingCourseStudent 
      WHERE waitingDate<=date; 
     END IF; 
     RETURN queuePosition; 
END; 

Полное сообщение об ошибке:

LINE/COL ERROR 
8/5  PL/SQL: SQL Statement ignored 
8/29 PL/SQL: ORA-00936: missing expression 
13/9 PL/SQL: SQL Statement ignored 
16/20 PL/SQL: ORA-00936: missing expression 
+2

Пожалуйста, избегайте объявления переменных с зарезервированными словами. date - зарезервированное слово. –

+0

Также не указывайте свои параметры точно так же, как и ваши столбцы. – SQB

+0

Назовите свои параметры такими же, как и столбцы, но имейте их в пространстве с именем функции внутри SQL. т.е. «wcs.student = getQueueNumber.student» –

ответ

0

Что вы, вероятно, ищете, является обработка вместо просто, если ошибка.

CREATE OR REPLACE FUNCTION getQueueNumber 
    (p_student IN VARCHAR, p_course IN CHAR) 
RETURN INT 
IS 
    queuePosition INT; 
    v_date TIMESTAMP; 
BEGIN 
    BEGIN 
     SELECT waitingDate INTO v_date 
     FROM WaitingCourseStudent wcs 
     WHERE wcs.student = p_student AND wcs.course = p_course; 
    EXCEPTION 
     WHEN NO_DATA_FOUND THEN RETURN NULL; 
    END; 

    SELECT COUNT(*) as pos 
    INTO queuePosition 
    FROM WaitingCourseStudent 
    WHERE waitingDate <= v_date; 
    RETURN queuePosition; 
END; 

Внутренний BEGIN/END предназначен для обработки исключений. Исключение может быть обработано только в блоке BEGIN/END, и поскольку вам нужно что-то сделать после вашего исключения, вам понадобится внутренний BEGIN/END. Альтернативой будет

CREATE OR REPLACE FUNCTION getQueueNumber 
    (p_student IN VARCHAR, p_course IN CHAR) 
RETURN INT 
IS 
    queuePosition INT; 
    v_date TIMESTAMP; 
BEGIN 
    SELECT waitingDate INTO v_date 
    FROM WaitingCourseStudent wcs 
    WHERE wcs.student = p_student AND wcs.course = p_course; 

    SELECT COUNT(*) as pos 
    INTO queuePosition 
    FROM WaitingCourseStudent 
    WHERE waitingDate <= v_date; 
    RETURN queuePosition; 

EXCEPTION 
    WHEN NO_DATA_FOUND THEN RETURN NULL; 
END; 
+0

Ahh! Не знал, что ты мог это сделать, отлично работал :). У меня есть некоторые вопросы. Переименование переменной означало что-то или вам просто не нравились имена. Кроме того, почему у вас есть два BEGIN/END? – SiXoS

+0

@SiXoS Скорректированный мой ответ. – SQB

+0

Вам не нужно переименовывать параметры, если вы импоставили их именем функции, когда они используются внутри оператора SQL. "wcs.student = getQueueNumber.student" –

0
SELECT waitingDate INTO date <--- (date is reserved keyword for denoting oracle datatype of date) 
FROM WaitingCourseStudent wcs 
    WHERE wcs.student=student AND wcs.course=course; 
    IF SQL%NOTFOUND THEN queuePosition := NULL; 

Альтернативное предложение:

Префикс ваши переменные с V_ или что-то подобное, чтобы избежать такого рода ошибок.

0

Правильный ответ заключается в следующем:

CREATE OR REPLACE FUNCTION getQueueNumber (vstudent ПО VARCHAR, vcourse IN CHAR) RETURN INT IS queuePosition INT; date1 TIMESTAMP; НАЧАЛО SELECT waitDate INTO date1 FROM WaitingCourseStudent WHERE student = vstudent AND course = vcourse; IF SQL% NOTFOUND THEN queuePosition: = NULL; ELSE SELECT COUNT (*) INTO queuePosition FROM WaitingCourseStudent WHERE waitingDate < = date1; END IF; RETURN queuePosition; исключение когда no_data_found then return -1; когда другие тогда return -1; END;

Смежные вопросы