2012-12-06 3 views
1

Я новичок в хранимых процедурах. Я пытаюсь запустить хранимую процедуру и получить эти ошибки: Я получаю PLS-00103: встретил символ «ВЫБРАТЬ», если ожидал одно из следующего: начало процедуры функции pragma ... PLS-00103: Встретил символ " RETURN ", ожидая одно из следующего: * & = - + < /> at in is mod осталось не rem ... Я попытался найти причины, которые приводят к этим ошибкам и примерам, подобным этому, но результатов было недостаточно , Какие-нибудь подсказки относительно того, почему эти ошибки происходят? вот код:PLS-00103 Ошибка хранимой процедуры Oracle

CREATE OR REPLACE PROCEDURE LIST_ACTIONS_CHECK_ADD 
(
    LISTNAME IN VARCHAR2 
) AS 
BEGIN 
DECLARE CNT NUMBER; 
SELECT COUNT(LIST_NAME) INTO CNT FROM LISTS_MASTER WHERE LIST_NAME = LISTNAME; 
IF (CNT > 0) 
RETURN 1 
ELSE 
RETURN 0 
END IF; 
END LIST_ACTIONS_CHECK_ADD; 

Новый код:

CREATE OR REPLACE PROCEDURE LIST_ACTIONS_CHECK_ADD 
(
    P_LISTNAME IN VARCHAR2 
) 
AS 
L_CNT NUMBER; 
BEGIN 
SELECT COUNT(LIST_NAME) 
    INTO L_CNT 
    FROM LISTS_MASTER 
    WHERE LIST_NAME = P_LISTNAME; 
IF (L_CNT > 0) 
    RETURN 1; 
ELSE 
    RETURN 0; 
    END IF; 
END LIST_ACTIONS_CHECK_ADD; 

ответ

2

Скелет хранимой объявления процедуры является

CREATE OR REPLACE PROCEDURE procedure_name(<<parameters>>) 
AS 
    <<variable declarations>> 
BEGIN 
    <<code>> 
END procedure_name; 

В коде вы в курсе,

  1. Вы ставите BEGIN fore объявления переменных
  2. У вас есть посторонний DECLARE - вы использовали бы это, только если вы объявляете блок PL/SQL, который не включает CREATE.
  3. Вам не хватает точек с запятой после операторов RETURN.
  4. Процедура не может вернуть значение. Если вы хотите вернуть либо 1, либо 0, вам, вероятно, нужна функция, а не процедура. Если вам нужна процедура, вы можете объявить параметр OUT.
  5. Вы пропускаете THEN после IF

Это звучит, как вы хотите что-то вроде

CREATE OR REPLACE FUNCTION LIST_ACTIONS_CHECK_ADD 
(
    LISTNAME IN VARCHAR2 
) 
    RETURN NUMBER 
AS 
CNT NUMBER; 
BEGIN 
SELECT COUNT(LIST_NAME) 
    INTO CNT 
    FROM LISTS_MASTER 
    WHERE LIST_NAME = LISTNAME; 
IF (CNT > 0) 
THEN 
    RETURN 1; 
ELSE 
    RETURN 0; 
    END IF; 
END LIST_ACTIONS_CHECK_ADD; 

Обратите внимание, что в общем плане, то, как правило, лучше использовать какой-то именовании в убедитесь, что параметры и локальные переменные не разделяют имя столбца. Попытка выяснить, является ли LISTNAME параметром или именем столбца, и какая разница между LIST_NAME и LISTNAME, как правило, путает будущих программистов. Лично я использую префикс p_ для параметров и префикс l_ для локальных переменных.Я бы также предложил использовать якорь types-- lists_master.list_name%type, если это то, что передается в

CREATE OR REPLACE FUNCTION LIST_ACTIONS_CHECK_ADD 
(
    P_LIST_NAME IN lists_master.list_name%type 
) 
    RETURN NUMBER 
AS 
L_CNT NUMBER; 
BEGIN 
SELECT COUNT(LIST_NAME) 
    INTO L_CNT 
    FROM LISTS_MASTER 
    WHERE LIST_NAME = P_LIST_NAME; 
IF (L_CNT > 0) 
THEN 
    RETURN 1; 
ELSE 
    RETURN 0; 
    END IF; 
END LIST_ACTIONS_CHECK_ADD; 
+0

Большое вам спасибо за вашу помощь. Я использовал все ваши советы, кроме использования привязанных типов. Из того, что я понимаю, посмотрев на привязанные типы, вот, что ваш параметр заносится из таблицы lists_master из столбца list_name? На самом деле я просто хотел бы, чтобы это был параметр, который я надеялся ввести так: CALL LIST_ACTIONS_CHECK_ADD ('BLACKLIST'); – jon

+0

Теперь, когда я компилирую код, как вы сказали, я получаю сообщение об ошибке (13,4): PLS-00103: встретил символ «ВОЗВРАТ», когда ожидал одно из следующего: * & = - + ... Любая идея почему? Я редактировал оригинальный вопрос, чтобы содержать новый код – jon

+0

@jon - привязанный тип просто указывает, что передаваемый вами параметр - это любой тип 'lists_master.list_name', определенный как текущий. Это не мешает вам проходить жестко закодированную строку, даже если эта строка отсутствует в таблице. Это означает, что тип данных параметра изменится, если изменится тип данных в столбце «list_name» и предоставляет следующему разработчику документацию о том, какие данные следует ожидать. –

2
  • (Correction # 1) Вы не можете вернуть значение в процедуре; LIST_ACTIONS_CHECK_ADD должен быть отброшен и объявлена ​​как функция для того, чтобы возвратить число
  • (Коррекция # 2) Вы должны переместить декларацию CNT следующим образом (см ниже)
  • (Коррекция # 3) Вы должны запятой на заявления возврата:
  • (Коррекция # 4) Вам нужен ТО после IF (CNT> 0) (см):


DROP PROCEDURE LIST_ACTIONS_CHECK_ADD; 
CREATE OR REPLACE FUNCTION LIST_ACTIONS_CHECK_ADD 
(
    LISTNAME IN VARCHAR2 
) 

RETURN NUMBER AS 

    CNT NUMBER; 
BEGIN 
    SELECT COUNT(LIST_NAME) INTO CNT FROM LISTS_MASTER WHERE LIST_NAME = LISTNAME; 
    IF (CNT > 0) THEN 
     RETURN 1; 
    ELSE 
     RETURN 0; 
    END IF; 
END LIST_ACTIONS_CHECK_ADD; 

Это может быть выполнено из SQLPLUS как:

SET SERVEROUTPUT ON SIZE 100000; 
DECLARE 
    V_RESULT NUMBER; 
BEGIN 

    V_RESULT := LIST_ACTIONS_CHECK_ADD('X'); 
    DBMS_OUTPUT.PUT_LINE('RESULT: ' || V_RESULT); 

END;  
+0

Спасибо! Я пытаюсь вызвать эту функцию. Я попробовал позвонить LIST_ACTIONS_CHECK_ADD ('NAME'); и я пробовал то же самое с выполнением – jon

+0

. Это сработало: выберите LISTS_ACTIONS_CHECK_ADD ('BLACKLIST') из dual; – jon

+0

SQLPLUS не принимает LIST_ACTIONS_CHECK_ADD ('NAME'); если LIST_ACTIONS_CHECK_ADD является функцией - вам нужен анонимный блок PLSQL - я отредактирую сообщение выше, ОК? –

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