PL / SQL If语句,游标和记录集。我在使用光标后如何使用IF语句?

时间:2016-03-31 18:16:42

标签: oracle plsql

我想知道我是否正确地走这条路。 编译器给出的主要问题是这一行 IF SELECT 1 FROM works WHERE an_employee.employee_name IN works.manager_name THEN

  

错误(17,8):PLS-00103:当遇到以下情况之一时遇到符号“SELECT”:( - + case mod new not null继续avg计数当前存在max min before sql stddev sum variance execute forall merge时间戳间隔日期管道

我想要做的是使用一个光标来检测第一个条件,如果它们在该城市的公司中工作。在我的表中的这个例子中,它将给出2个公司,大约7或8个雇员。然后我把它放到我的变量an_employee中。我想要做的是然后使用该员工来查看他们是否是来自我的管理表的管理员,其中有多行/元组。不是每个人都是经理。如何查看我的employee_name是否在manager_name列表中?

我是否为管理器声明了另一个游标,然后执行嵌套循环? 我可以使用现有游标并执行选择查询以从表manages.manager_name获取管理器列表吗?如果我这样做,我怎么能在IF语句中使用它作为我的条件?

-- Give all employees that work in a company located in city X 
-- a Y percent raise if they are managers and 
-- a Z percent raise if they are not a manager
-- X, Y, and Z will be the three parameters for the stored procedure.
-- Build / compile a stored procedure
CREATE OR REPLACE PROCEDURE give_raises(X company.city%TYPE, Y NUMBER, Z NUMBER) IS
    an_employee works.employee_name%TYPE;

-- cursor declaration
cursor Cursor1 IS
  select works.employee_name
  from works
  where works.company_name IN (select company_name from company where city = 'London');

BEGIN
  SELECT manager_name INTO managers FROM manages;
  OPEN Cursor1;
  LOOP
    FETCH Cursor1 INTO an_employee;
    EXIT WHEN Cursor1%NOTFOUND;
    -- is a manager give Y percent raise
    IF SELECT 1 FROM works WHERE an_employee.employee_name IN works.manager_name THEN
      update works
      set works.salary = works.salary + (works.salary * Y)
      where works.employee_name = an_employee.employee_name;
    ELSE  -- is not a manager give Z percent raise
      update works
      set works.salary = works.salary + (works.salary * Z)
      where works.employee_name = an_employee.employee_name;
    END IF;
  END LOOP;
  CLOSE Cursor1;
END;

你也应该知道。我使用的是Oracle,Oracle Sql Developer和IDE。

3 个答案:

答案 0 :(得分:2)

如果在逻辑条件下工作并且不支持条件中的Select语句。

你需要像这样重做你的代码

SELECT count(*) 
INTO v_value
FROM works 
WHERE an_employee.employee_name = works.manager_name;

IF v_value = 1 THEN
   --do some stuff
ELSE
   --do some other stuff
END IF;

答案 1 :(得分:1)

如果我正确地理解了您的问题,那么您正在尝试确定员工是否是经理,而不是根据该工资进行计算。希望在片段下方有所帮助。

CREATE OR REPLACE PROCEDURE give_raises(
    X company.city%TYPE,
    Y NUMBER,
    Z NUMBER)
AS
  managers PLS_INTEGER;
BEGIN
  FOR an_employee IN
  (SELECT works.employee_name
  FROM works
  WHERE works.company_name IN
    (SELECT company_name FROM company WHERE city = 'London'
    )
  )
  LOOP
    SELECT COUNT(1)
    INTO managers
    FROM manages m
    WHERE m.manager_name = an_employee.employee_name; 
    -- is a manager give Y percent raise
    IF managers <> 0 THEN
      UPDATE works
      SET works.salary          = works.salary + (works.salary * Y)
      WHERE works.employee_name = an_employee.employee_name;
    ELSE -- is not a manager give Z percent raise
      UPDATE works
      SET works.salary          = works.salary + (works.salary * Z)
      WHERE works.employee_name = an_employee.employee_name;
    END IF;
  END LOOP;
END;

答案 2 :(得分:0)

你的问题基本上与例如在昨天发布的a question中。 PL / SQL if statement期望布尔表达式不是query result set

一个好的做法是将查询封装到返回合适值的函数中。

示例:

SQL> !cat so53.sql
declare
  function is_foo_1(p_foo in varchar2) return boolean is
    v_exists number;
  begin
    select count(*)
      into v_exists
      from dual
     where dummy = p_foo
       and rownum = 1
    ;
    return
      case v_exists
        when 1 then true
        else        false
      end;
  end;
  function is_foo_2(p_foo in varchar2) return number is
    v_exists number;
  begin
    select count(*)
      into v_exists
      from dual
     where dummy = p_foo
       and rownum = 1
    ;
    return v_exists;
  end;
begin
  -- is_foo_1 returns a boolean value than is a valid boolean expression
  if is_foo_1('X')
  then
    dbms_output.put_line('1:X');
  end if;

  if not is_foo_1('Y')
  then
    dbms_output.put_line('1:not Y');
  end if;

  -- is_foo_2 returns a number that is not a valid boolean expression (PL/SQL
  -- doesn't have implicit type conversions) so one have to use an operator
  -- (in this example `=`-operator) to construct an explicit boolean
  -- expression
  if is_foo_2('X') = 1
  then
    dbms_output.put_line('2:X');
  end if;

  if is_foo_2('Y') = 0
  then
    dbms_output.put_line('2:not Y');
  end if;
end;
/

示例运行:

SQL> @so53.sql
1:X
1:not Y
2:X
2:not Y

PL/SQL procedure successfully completed.

SQL>