Oracle——PL/SQL

What is PL/SQL

PL/SQL is a procedural SQL language (Procedural Language/SQL). PL/SQL is an extension of the Oracle database to SQL statements. The use of ordinary SQL statements adds the characteristics of programming languages, so PL/SQL organizes data operations and query statements in procedural units of PL/SQL code, and realizes complex functions or calculations through logical judgment, looping and other operations. programming language.

PL/SQL syntax

1)hello,world

--print Hello World

declare
  --Description section
begin
  -- program part
  dbms_output.put_line('Hello World'); -- dbms_output is equivalent to a class in java
end;
/

2) Define the variable type

  • reference variable
--reference variable: query and print the name and salary of 7839

declare
  --Define variables to hold name and salary
  --pename varchar2(20); -- Method 1 of declaring the variable type: directly define the type of the variable
  --psal   number;
  penname emp.ename%type; -- way of declaring variable type 2 (reference variable): the same type as the ename column in the emp table
  psal   emp.sal%type;
begin
  -- Get 7839's name and salary
  select ename,sal into penname,psal from emp where empno=7839; -- use into to assign values ​​to variables

  --Print
  dbms_output.put_line(pename||''s salary is'||psal); -- || is the string concatenation in Oracle
end;
/
  • record variable
--Record variable: query and print the name and salary of 7839

declare
  --Define a record variable: representing a row in the emp table
  emp_rec emp%rowtype;
begin
  select * into emp_rec from emp where empno=7839;
  
  dbms_output.put_line(emp_rec.ename||''s salary is'||emp_rec.sal);
end;
/

3) if statement

-- Determine the number entered by the user from the keyboard

--accept keyboard input
--Variable num: is an address value where the entered value is stored
accept num prompt 'Please enter a number';

declare
  --Define a variable to hold the entered number
  pnum number := #
begin
  if pnum = 0 then dbms_output.put_line('you entered 0');
     elsif pnum = 1 then dbms_output.put_line('you entered 1');
     elsif pnum = 2 then dbms_output.put_line('you entered 2');
     else dbms_output.put_line('other numbers');
  end if;
end;
/

4) Loop

-- print 1~10
declare
  -- define variables
  pnum number := 1;
begin
  loop
    -- exit condition
    exit when pnum > 10;
    
    --Print
    dbms_output.put_line(pnum);
    --plus one
    pnum := pnum + 1
  end loop;
end;
/

5) Cursor

-- Query and print employee's name and salary
/*
Attributes of the cursor: %isopen (whether to open) %rowcount (the number of rows affected)
             %found (whether there is a value) %notfound (whether there is no value)

*/
declare
   --Define cursor (cursor)
   cursor cemp is select ename,sal from emp;
   pename emp.ename%type;
   psal   emp.sal%type;
begin
  -- open cursor
  open cemp;

  loop
       -- get current record
       fetch cemp into pename,psal;
       --exit when no record is retrieved;
       exit when cemp%notfound;
       
       dbms_output.put_line(pename||''s salary is'||psal);
  end loop;

  --close cursor
  close cemp;
end;
/

Example: Raising wages for employees

-- Raise wages for employees, president 1000, manager 800, other 400
declare
  -- define cursor
  cursor cemp is select empno,job from emp;
  pempno emp.empno%type;
  pjob   emp.job%type;
begin

  -- open cursor
  open cemp;  
  loop
       -- take an employee
       fetch cemp into pempno,pjob;
       exit when cemp%notfound;
       
       -- Judging position
       if pjob = 'PRESIDENT' then update emp set sal=sal+1000 where empno=pempno;
          elsif pjob = 'MANAGER' then update emp set sal=sal+800 where empno=pempno;
          else update emp set sal=sal+400 where empno=pempno;
       end if;

  end loop;
  --close cursor
  close cemp;
  
  --commit----> why?: Transaction ACID
  commit;
  
  dbms_output.put_line('完成');
end;
/
  • Cursor with parameters
-- Query the names of employees in a department
declare
   --form parameter
   cursor cemp(dno number) is select ename from emp where deptno=dno;
   pename emp.ename%type;
begin
   --Arguments
   open cemp(20);
   loop
        fetch cemp into pename;
        exit when cemp%notfound;
        
        dbms_output.put_line(pename);

   end loop;
   close cemp;
end;
/

6) Exception (exception)

  • System exception
-- divide by 0
declare
   pnum number;
begin
  pnum := 1/0;
  
exception
  when zero_divide then dbms_output.put_line('1:0 cannot be used as a denominator');
                        dbms_output.put_line('2:0 cannot be used as a denominator');
  when value_error then dbms_output.put_line('arithmetic or conversion error');                      
  when others then dbms_output.put_line('其他例外');
end;
/
  • custom exception
-- Query employees in department 50 (department 50 does not exist)
declare
  cursor cemp  is select ename from emp where deptno=50;
  pename emp.ename%type;
  
  -- custom exception
  no_emp_found exception;
begin
  open cemp;
  
  -- get the first record
  fetch cemp into pename;
  if cemp%notfound then
    -- throw an exception, use raise
    raise no_emp_found;
  end if;
  
  --Process: pmon process (proccesss monitor)
  close cemp;

exception
  when no_emp_found then dbms_output.put_line('employee not found');
  when others then dbms_output.put_line('其他例外');
end;
/

Example 1: Count the number of employees hired each year (using PL/SQL)

/*
1. SQL statement
select to_char(hiredate,'yyyy') from emp;
---> Collection ---> Cursor ---> Loop ---> Exit: notfound

2. Variables: (*) how to get the initial value (*) in the end
Number of people hired each year
count80 number := 0;
count81 number := 0;
count82 number := 0;
count87 number := 0;
*/
declare
   -- define cursor
   cursor cemp is select to_char(hiredate,'yyyy') from emp;
   phiredate varchar2(4);
   
   - Number of people hired each year
  count80 number := 0;
  count81 number := 0;
  count82 number := 0;
  count87 number := 0;
begin
  -- open cursor
  open cemp;
  loop
    -- Take an employee's entry year
    fetch cemp into phiredate;
    exit when cemp%notfound;
    
    --Determine what year it is
    if phiredate = '1980' then count80:=count80+1;
       elsif phiredate = '1981' then count81:=count81+1;
       elsif phiredate = '1982' then count82:=count82+1;
       else count87:=count87+1;
     end if;
  end loop;
  
  --close cursor
  close cemp;
  
  --output
  dbms_output.put_line('Total:'||(count80+count81+count82+count87));
  dbms_output.put_line('1980:'|| count80);
  dbms_output.put_line('1981:'|| count81);
  dbms_output.put_line('1982:'|| count82);
  dbms_output.put_line('1987:'|| count87);
end;
/

Example 2: Raise wages for employees. The person with the lowest total salary starts to increase. No one has a 10% increase, but the total salary does not exceed 10,000 yuan. Please calculate the number of people with long wages and the total wages after long wages.

/*
1. SQL statement
selet empno,sal from emp order by sal;
---> cursor ---> loop ---> exit: 1. total > 5w 2. notfound

2. Variables: (*) how to get the initial value (*) in the end
Number of people who have raised wages: countEmp number := 0;
The total salary after the increase: salTotal number;
(1)select sum(sal) into salTotal from emp;
(2) After the rise = before the rise + sal *0.1

Exercise: Number of people: 8 Total: 50205.325
*/
declare
    cursor cemp is select empno,sal from emp order by sal;
    pempno emp.empno%type;
    psal   emp.sal%type;
    
    --The number of people with salary increase:
    countEmp number := 0;
    --The total salary after the increase:
    salTotal number;
begin
    -- Get the initial value of the total salary
    select sum(sal) into salTotal from emp;
    
    open cemp;
    loop
         -- 1. Total >5w
         exit when salTotal > 50000;
         -- take an employee
         fetch cemp into pempno,psal;
         --2. notfound
         exit when cemp%notfound;
         
         --rise salary
         update emp set sal=sal*1.1 where empno=pempno;
         --Number +1
         countEmp := countEmp +1;
         --After the rise = before the rise + sal *0.1
         salTotal: = salTotal + psal * 0.1;

    end loop;
    close cemp;
    
    commit;
    dbms_output.put_line('Number: '||countEmp||' Total: '||salTotal);
end;
/

Example 3:

/*
1. SQL statement
Dept: select deptno from dept; ---> cursor
Salary of employees in a department: select sal from emp where deptno=?? ---> cursor with parameters

2. Variables: (*) how to get the initial value (*) in the end
Number of people in each segment
count1 number; count2 number; count3 number;
Department's gross salary
salTotal number: = 0;
(1)select sum(sal) into salTotal  from emp where deptno=??
(2) Accumulation
*/
declare
  --Department
  cursor cdept is select deptno from dept;
  pdeptno dept.deptno%type;
  
  -- Salary of employees in the department
  cursor cemp(dno number) is select sal from emp where deptno=dno;
  psal emp.sal%type;
  
  -- the number of people in each segment
  count1 number; count2 number; count3 number;
  --Department's total salary
  salTotal number: = 0;
begin
  --Department
  open cdept;
  loop
       -- take a department
       fetch cdept into pdeptno;
       exit when cdept%notfound;
       
       --initialization
       count1:=0; count2:=0; count3:=0;
       --Get the total salary of the department
       select sum(sal) into salTotal  from emp where deptno=pdeptno;
       
       --Take the salary of middle employees in the department
       open cemp(pdeptno);
       loop
            -- Take an employee's salary
            fetch cemp into psal;
            exit when cemp%notfound;
            
            --judge
            if psal < 3000 then count1:=count1+1;
               elsif psal >=3000 and psal<6000 then count2:=count2+1;
               else count3:=count3+1;
            end if;
       end loop;
       close cemp;

       --save results
       insert into msg values(pdeptno,count1,count2,count3,nvl(saltotal,0));

  end loop;
  close cdept;
  
  commit;
  dbms_output.put_line('完成');
  
end;
/

 

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325859754&siteId=291194637