简体   繁体   English

如何在 PL/SQL 中解决此过程

[英]How do I resolve this procedure in PL/SQL

I'm stanqued in sequence of PL/SQL procedure I need to do a procedure that receives as parameters a department number, a salary, and a percentage;我在 PL/SQL 程序的序列中感到厌烦,我需要执行一个接收部门编号、薪水和百分比作为参数的程序; and to raise the salary of all employees of the department indicated in the call.并提高电话中指定部门的所有员工的工资。 The increase will be the percentage or salary indicated in the call (whichever is more beneficial for the employee in each case).增加的金额将是电话中显示的百分比或工资(在每种情况下,以对员工更有利的为准)。 I have this code but doesn't work.我有这个代码,但不起作用。

CREATE OR REPLACE PROCEDURE pujarSalari (numdept number,diners number,percentatge number)
AS
souapujar number(10);
CURSOR buscarnoms IS SELECT codi_emp FROM empleats WHERE codi_dept=numdept;
BEGIN
OPEN buscarnoms;
FETCH buscarnoms INTO souapujar;
WHILE buscarnoms%FOUND LOOP
IF (empleats.sou*(1+percentatge/100))>=(empleats.sou+diners) THEN
UPDATE empleats set empleats.sou=empleats.sou*(1+percentatge/100) where codi_emp=souapujar;
ELSE
UPDATE empleats set empleats.sou=empleats.sou+diners where codi_emp=souapujar;
END IF;
FETCH buscarnoms INTO souapujar;
END LOOP;
CLOSE buscarnoms;
END; 

And the error code is错误代码是

Procedure PUJARSALARI compilado

LINE/COL  ERROR
--------- -------------------------------------------------------------
9/1       PL/SQL: Statement ignored
9/14      PLS-00357: Table,View Or Sequence reference 'EMPLEATS.SOU' not allowed in this context
Errores: comprobar log de compilador

Your IF statements are referencing table columns .您的 IF 语句正在引用表列 In PL/SQL we can only reference variables (including implicit cursors).在 PL/SQL 中,我们只能引用变量(包括隐式游标)。 (That is outside of embedded SQL statements.) (这在嵌入式 SQL 语句之外。)

You have a cursor buscarnoms which selects from empleats but doesn't include all the columns you need.您有一个 cursor buscarnomsempleats中选择,但不包括您需要的所有列。 So you must change the cursor projection then reference the cursor in your code.因此,您必须更改 cursor 投影,然后在代码中引用 cursor。

CREATE OR REPLACE PROCEDURE pujarSalari 
  (numdept number,
   diners number,
   percentatge number)
AS
  CURSOR buscarnoms IS 
    SELECT * 
    FROM empleats 
    WHERE codi_dept = numdept;
  souapujar buscarnoms%rowtype; -- inherits the projection of the cursor
BEGIN
  OPEN buscarnoms;
  FETCH buscarnoms INTO souapujar;
  WHILE buscarnoms%FOUND LOOP
    IF (souapujar.sou*(1+percentatge/100)) >= (souapujar.sou+diners) THEN
        UPDATE empleats 
        set empleats.sou = empleats.sou*(1+percentatge/100) 
        where codi_emp = souapujar.codi_emp;
    ELSE
      UPDATE empleats 
      set empleats.sou = empleats.sou+diners 
      where codi_emp = souapujar.codi_emp;
    END IF;
    FETCH buscarnoms INTO souapujar;
  END LOOP;
  CLOSE buscarnoms;
END; 

There are several ways to simplify this code, for instance by replacing the explicit cursor with an implicit cursor.有几种方法可以简化此代码,例如将显式 cursor 替换为隐式 cursor。 Or even replacing the cursor loop with a set-based update statement.甚至用基于集合的更新语句替换 cursor 循环。 But I have left the code as close to the original as possible, to highlight the solution to the problem as presented.但我已将代码尽可能接近原始代码,以突出显示问题的解决方案。


You say that are several ways to simplify the code.您说这是简化代码的几种方法。 How can i simplify my code?我怎样才能简化我的代码?

Implicit cursor:隐式 cursor:

CREATE OR REPLACE PROCEDURE pujarSalari 
  (numdept number,
   diners number,
   percentatge number)
AS
BEGIN
  FOR buscarnoms in (SELECT * 
                     FROM empleats 
                     WHERE codi_dept = numdept)
  LOOP
    IF (souapujar.sou*(1+percentatge/100)) >= (souapujar.sou+diners) THEN
        UPDATE empleats 
        set empleats.sou = empleats.sou*(1+percentatge/100) 
        where codi_emp = souapujar.codi_emp;
    ELSE
      UPDATE empleats 
      set empleats.sou = empleats.sou+diners 
      where codi_emp = souapujar.codi_emp;
    END IF;
  END LOOP;
END; 

Set-based:基于集合:

CREATE OR REPLACE PROCEDURE pujarSalari 
  (numdept number,
   diners number,
   percentatge number)
AS
BEGIN

  UPDATE empleats 
  set    sou = greatest(empleats.sou + diners, 
                        empleats.sou * (1+percentatge/100) )
  where codi_dept = numdept;

END; 

Well that actually is a different question and should be posed that way.好吧,这实际上是一个不同的问题,应该以这种方式提出。 But how about max simplification.但是最大简化怎么样。 Reduce it to a single statement:将其简化为一条语句:

 create or replace procedure pujarsalari 
      (numdept     number,
       diners      number,
       percentatge number)
    as
    begin
        update empleats 
           set sou = greatest(sou*(1+percentatge/100), sou+diners)   
         where codi_dept = numdept;
    end  pujarsalari;

Tip of the day: In SQL stop thinking in terms of individual rows.每日提示:在 SQL 中停止考虑个别行。 Think instead of the set of all rows at one time.考虑一次而不是所有行的集合。

NOTE: Not tested as you did not see fit to post neither sample data not table definitions.注意:未测试,因为您认为不适合发布样本数据和表定义。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM