如何修复邮政编码功能中的PLS-00103错误?

时间:2019-04-03 17:32:48

标签: sql plsql oracle-sqldeveloper

因此,我创建了一个函数来确定表中是否存在邮政编码。我有一个名为“ ZIPCODE”的表和一个名为“ ZIP”的列。对于此功能,无论邮政编码是否存在,我都希望它返回布尔值true或false。但是,出现此错误:

PLS-00103:在预期以下情况之一时遇到符号“ 13501” :(如果使用

,则循环mod null编译指示提高返回选择更新时,开始情况声明goto的退出)

因此问题是在我输入邮政编码后发生的。

CREATE OR REPLACE FUNCTION zip_existence 
RETURN number IS

bool number (2) := 0;

BEGIN
    &zip_input;

     FOR record_current_zip IN current_zip LOOP
        IF record_current_zip = zip_input THEN
            bool := 0;
                DBMS_OUTPUT.PUT_LINE('Zipcode in use!');
        IF record_current_zip != zip_input  THEN
            bool := 1;
                DBMS_OUTPUT.PUT_LINE('Zipcode not in use');
                END IF;
            END IF;
        RETURN boolean; 
    END loop;
END; 

1 个答案:

答案 0 :(得分:3)

&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 / SQL类型)而不是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过滤器。