PL / SQL IF语句和变量声明

时间:2018-08-14 14:01:31

标签: oracle plsql

我正在尝试使下面发布的代码正常工作,但是我收到有关IF语句的错误:

DECLARE 
    a number; 
BEGIN
    SELECT Pers_API.Is_Manager_(10018) INTO a from dual;
EXCEPTION
    WHEN no_data_found THEN a := 0;
END;

IF (a >0) THEN 
    SELECT 1 from dual;
ELSE 
    SELECT 0 from dual;
END IF;

在第一个块中,我声明一个'A'变量并将其设置为0(顺便说一句,API调用结果将为0或1,仅此而已)。第一块工作正常,或者-至少-我认为是这样。但是IF块不起作用,并出现以下错误:

  

PLS-00103:遇到符号“ IF”

感谢您的帮助。


更新:我已经尝试过这种方式:

DECLARE 
    a number:=0; 
BEGIN
    SELECT Pers_API.Is_Manager_(10018) INTO a from dual;

    IF (:a >0) THEN
        SELECT 1 from dual;
    ELSE 
        SELECT 0 from dual;
    END IF;
END; 

我收到以下异常:

  

ORA-01008:并非所有变量都已绑定


更新

换句话说,我想做的是:

  • 如果Pers_API.Is_Manager_(10018)返回true(为1),则必须执行另一个选择语句
  • 如果它为假(为0),则必须返回null。

任何其他想法都会受到赞赏。

2 个答案:

答案 0 :(得分:2)

如果可以的话,我会提出一些反对意见。

  • 当函数通过函数 assign 返回该 value 值时,无需从双精度对象中选择 即可为该变量赋值。 em>它
  • 异常处理程序似乎是多余的。您说is_manager_函数返回0或1,并且没有其他返回。因此,它将总是返回某些内容,所以-为什么您期望SELECT返回NO_DATA_FOUND?此外,这种情况应由函数本身处理(即,您必须确保它返回0或1,并且没有其他值)
  • 您写的最后一段有些奇怪。您说过-如果函数返回1,则必须运行另一个SELECT语句。否则,您必须返回 null (在您编写的代码中,select 0 ...表示零(0),而不是 null );那么,哪个是真的?
  • 还说,您必须返回 某些东西(null,0,随便什么),这表明您编写的代码段应该是一个返回值的函数。是吗?

实际上编译的代码在此示例中可能类似于

首先,该函数(基于Scott的架构)检查员工是否为经理:

SQL> create or replace function is_manager_ (par_empno in number)
  2    return number
  3  is
  4    /* function checks whether PAR_EMPNO belongs to a manager and returns:
  5       - 1 - employee is     a manager
  6       - 0 - employee is NOT a manager
  7    */
  8    retval number := 0;
  9  begin
 10    select max(1)
 11      into retval
 12      from emp e
 13      where mgr = par_empno;
 14
 15    return retval;
 16  exception
 17    when no_data_found then
 18      return retval;
 19  end;
 20  /

Function created.

SQL>

您发布并重新编写的代码可以执行以下操作:

  • 如果员工是经理,则返回其薪金
  • 否则,不会

SQL> declare
  2    a      number := is_manager_(&&l_empno);
  3    l_sal  emp.sal%type;
  4  begin
  5    if a > 0 then
  6       select sal
  7         into l_sal
  8         from emp
  9         where empno = &&l_empno;
 10       dbms_output.put_line('Employee is a manager and his/her salary is ' || l_sal);
 11    else
 12       null;
 13       dbms_output.put_line('Employee is not a manager');
 14    end if;
 15  end;
 16  /
Enter value for l_empno: 7698
Employee is a manager and his/her salary is 2850

PL/SQL procedure successfully completed.

SQL> undefine l_empno
SQL> /
Enter value for l_empno: 7369
Employee is not a manager

PL/SQL procedure successfully completed.

SQL> undefine l_empno
SQL> /
Enter value for l_empno: -1
Employee is not a manager

PL/SQL procedure successfully completed.

SQL>

查看是否可以调整它以满足您的需求。如果不是,请回答此消息开头发布的反对意见,我们将下一步做什么。

答案 1 :(得分:1)

在我看来,您真正要实现的目标是运行查询,该查询必须使用从package函数获得的结果作为条件。如果是这样,则不需要PL / SQL块,并将其编写为基本的选择操作。

从您的解释中仍然不清楚的是您是否选择查询 SELECT 1 from dual是您将在代码中使用的实际查询。通常,在select statement中,我们使用CASE表达式来评估条件逻辑,该条件逻辑实际上执行{{1} }条件应该返回期望的结果。查询将具有这种形式的结构,

IF ELSE

更具体地说,如果您希望结果表达式来自另一个数据库表,则查询可以采用以下形式

SELECT
    CASE
        WHEN pers_api.is_manager_(10018) = 1 THEN some_expression
        ELSE some_other_expression --If you omit the else condition, it defaults to null when all others are false
    END
    END
as
FROM DUAL;

如果您说表中的结果表达式包含许多其他构造,那么挑战将是巧妙地将其组成在单个查询中,以完全避免任何PL / SQL。这是可以实现的,但需要您提供一些示例数据和预期结果,以向我们解释您到底想要什么,最好是在新问题中。

如果我不提到SELECT CASE WHEN pers_api.is_manager_(10018) = 1 THEN some_expression ELSE some_other_expression --If you omit the else condition, it defaults to null when all others are false END as FROM table_to_run_query WHERE where_clauses = some_values; 技术来从PL / SQL中的选择查询中获取结果,那将是不完整的。它可以通过DBMS_SQL.RETURN_RESULT(Oracle 12c及更高版本),也可以使用REFCURSOR绑定变量在SQL * Plus中运行,或在其他工具中作为脚本(F5)。

REFCURSOR