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; /