【问题标题】:PL/SQL If statement, cursors, and a record set. How to use an IF statement after I use the Cursor?PL/SQL If 语句、游标和记录集。使用光标后如何使用 IF 语句?
【发布时间】:2016-04-01 15:39:04
【问题描述】:

我想知道我是否以正确的方式解决这个问题。 编译器给出的主要问题是这一行 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 continue avg count current exists max min prior 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。

【问题讨论】:

    标签: oracle plsql


    【解决方案1】:

    If 适用于逻辑条件并且不支持条件中的 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;
    

    【讨论】:

    • 谢谢,很有帮助。我要去工作了。是的,这更有意义哈哈
    【解决方案2】:

    如果我正确理解了您的问题,您正在尝试根据计算的薪水来确定员工是否是经理。希望下面的 sn-p 有所帮助。

    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;
    

    【讨论】:

      【解决方案3】:

      您的问题与例如您的问题基本相同。在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>
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-06-07
        • 1970-01-01
        • 2021-11-26
        • 1970-01-01
        • 2017-08-30
        • 2014-11-25
        相关资源
        最近更新 更多