Sql 如何修复邮政编码函数中的PLS-00103错误?

Sql 如何修复邮政编码函数中的PLS-00103错误?,sql,plsql,oracle-sqldeveloper,Sql,Plsql,Oracle Sqldeveloper,因此,我创建了一个函数来确定表中是否存在邮政编码。我有一个名为“ZIPCODE”的表和一个名为“ZIP”的列。对于这个函数,我希望它返回一个布尔值true或false,无论邮政编码是否存在。但是,我得到了这个错误: PLS-00103:在预期以下情况之一时遇到符号“13501”:(开始情况下,如果循环模式为null pragma,则为goto声明退出上升返回选择更新,同时使用 所以问题发生在我输入一个zip之后 CREATE OR REPLACE FUNCTION zip_existence

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

PLS-00103:在预期以下情况之一时遇到符号“13501”:(开始情况下,如果循环模式为null pragma,则为goto声明退出上升返回选择更新,同时使用

所以问题发生在我输入一个zip之后

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; 

&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:遇到了符号“13501”…,因为它扩展为:

CREATE OR REPLACE FUNCTION zip_existence 
RETURN number IS

bool number (2) := 0;

BEGIN
    13501;

     FOR record_current_zip IN current_zip LOOP
...
而那不属于那里

您应该将要检查的值作为形式参数传递给函数:

CREATE OR REPLACE FUNCTION zip_existence (zip_input zipcode.zip%TYPE)
RETURN number IS
  bool number (1) := 0;
BEGIN
...
但还有更多的问题

  • 您正在使用尚未定义的
    当前\u 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; 
/
无论如何,您都不想在所有值上循环查找匹配项-对传入的值进行单个选择筛选将更有效,可能类似于:

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哇,感谢您的快速响应和提供2个解决方案。感谢您指出我最初没有发现的其他问题。我肯定喜欢解决方案2如何更有效。我还有一个问题,如果我不能使用替换变量,那么我可以向用户请求输入吗?@moneenja-如果需要,您仍然可以使用客户端功能,如调用的替换变量,例如从dual;
select zip\u existence(&enter\u zip)