&zip_input
- это переменная подстановки клиента, которая оценивается при компиляции функции, что вряд ли будет тем, что вам нужно.Где бы вы ни использовали, это все равно не имеет смысла, и более поздние немного больше логических ссылок не имеют префикса &
.Итак, в данный момент вы, кажется, делаете:
define zip_input = 13501;
CREATE OR REPLACE FUNCTION zip_existence
RETURN number IS
bool number (2) := 0;
BEGIN
&zip_input;
FOR record_current_zip IN current_zip LOOP
....
END;
/
, который действительно получает PLS-00103: Encountered the symbol "13501"...
, потому что он расширен до:
CREATE OR REPLACE FUNCTION zip_existence
RETURN number IS
bool number (2) := 0;
BEGIN
13501;
FOR record_current_zip IN current_zip LOOP
...
и что 13501
не принадлежит
Вы должны передать значение, которое вы хотите проверить, в качестве формального аргумента функции:
CREATE OR REPLACE FUNCTION zip_existence (zip_input zipcode.zip%TYPE)
RETURN number IS
bool number (1) := 0;
BEGIN
...
Но есть и другие проблемы
- вывы используете курсор
current_zip
, который вы не определили; в этом цикле вы сравниваете
IF record_current_zip = zip_input THEN
, который ссылается на запись вместо поляв записи, так что это должно быть
IF record_current_zip.zip = zip_input THEN
, тогда у вас есть второй IF
в пределах первого, который имеет ту же проблему поля, но большеважно то, что никогда не может быть истиной - вы действительно хотите, чтобы это было ELSE
, я думаю;
- также внутри цикла, который вы собираетесь установить
bool
в ноль, когда вы найдете совпадение, но он все равно начинается с нуля, и даже если вы исправите проблему IF
, вы вернетесь на основе первой записиполучить от курсора.Похоже, что вы хотите перебрать все возможные почтовые индексы - но вы этого не сделаете, и если вы это сделали (вернувшись позже), вы бы продолжали перезаписывать этот bool
результат; - , чтобы вы могли начать с
bool
установить в состояние "не найдено", и только изменить, если вы найдете совпадение; - ваш
return
имеет boolean
(что является PL / SQLtype) вместо bool
(ваша переменная).
Так что одним из способов сделать это может быть что-то вроде:
CREATE OR REPLACE FUNCTION zip_existence (zip_input zipcode.zip%TYPE)
RETURN number IS
bool number (1) := 1; -- start with not-found state
cursor current_zip is
select * from zipcode;
BEGIN
FOR record_current_zip IN current_zip LOOP
IF record_current_zip.zip = zip_input THEN
bool := 0;
END IF;
END loop;
-- debugging only - client may not see this
IF bool = 0 THEN
DBMS_OUTPUT.PUT_LINE('Zipcode in use!');
ELSE
DBMS_OUTPUT.PUT_LINE('Zipcode not in use');
END IF;
RETURN bool;
END;
/
Вы действительно не хотите зацикливатьсяв любом случае все значения ищут совпадение - фильтрация одного выбора по переданному значению будет гораздо более эффективной, возможно, что-то вроде:
CREATE OR REPLACE FUNCTION zip_existence (zip_input zipcode.zip%TYPE)
RETURN number IS
bool number (1);
BEGIN
select case when count(*) > 0 then 0 else 1 end
into bool
from zipcode
where zip = zip_input;
-- debugging only - client may not see this
IF bool = 0 THEN
DBMS_OUTPUT.PUT_LINE('Zipcode in use!');
ELSE
DBMS_OUTPUT.PUT_LINE('Zipcode not in use');
END IF;
RETURN bool;
END;
/
Если ZIP
не уникален, то вы можете воспользоватьсядобавление фильтра where rownum <= 1
к запросу.