Introduction to PLSQL
PLSQL is an extension of Oracle to SQL99. Basically every database will extend SQL. Oracle's extension to SQL is called PLSQL.
What is SQL99
- (1) Rules for operating all relational databases
- (2) It is the fourth generation language.
- (3) It is a structured query language
- (4) Only by issuing legitimate and reasonable orders can the corresponding results be obtained.
Characteristics of SQL
- (1) Interactive and non-procedural
- (2) Strong database manipulation ability, just send commands, no need to pay attention to how to achieve.
- (3) In multi-table operation, automatic navigation is simple, such as:
- select emp.empno,emp.sal,dept.dname
- from emp,dept
- where emp.deptno = dept.deptno
- (4) Easy debugging, error prompting, straightforward
- (5) SQL emphasizes results
What is PLSQL
- It's dedicated to Oracle server. On the basis of SQL, it adds some procedural control statements, called PLSQL.
- Proceduralization includes type definitions, judgments, loops, cursors, exception or exception handling...
- PLSQL emphasizes process
Why PLSQL
- Because SQL is the fourth generation imperative language, it can not display the procedural business, so we have to use a procedural programming language to make up for the deficiencies of SQL.
- SQL and PLSQL are not substitutes, but complements.
PLSQL grammar
declare and exception can be omitted, begin and end; / can not be omitted.
[declare] Variable declaration; Variable declaration; begin DML/TCL operation; DML/TCL operation; [exception] Exceptions; Exceptions; end; /
In PLSQL programs:; Numbers denote the end of each statement, / denotes the end of the entire PLSQL program.
What is the difference between PLSQL and SQL execution?
- (1) SQL is executed singly
- (2) PLSQL is executed as a whole and cannot be executed alone. The whole PLSQL is terminated with /, in which each statement is terminated with a number.
PLSQL variable
Since PLSQL is process-oriented, there must be a basic grammar for writing process programs. First, let's introduce the variables of PLSQL.
PLSQL has four variables
- number
- varchar2
- Same as column name type
- The same column type as the entire table
Example
Write a PLSQL program, output "hello world" string, grammar: dbms_output.put_line('the string to be output'); begin Output string to the SQLPLUS client tool dbms_output.put_line('hello'); end; / Be careful: dbms_output is an output object in oracle put_line is a method of the above object to output a string to wrap automatically Set to display the results of PLSQL program execution, by default, do not display the results of PLSQL program execution, grammar: set server routput on / off; set serveroutput on; Using basic type variables, constants, and annotations, find the sum of 10 + 100 declare Define variables mysum number(3) := 0; tip varchar2(10): ='result'; begin /* Business Algorithms*/ mysum := 10 + 100; /* Output to Controller*/ dbms_output.put_line(tip || mysum); end; / Output 7369 employee name and salary, the format is as follows: 7369 employee name is SMITH, salary is 800, grammar: use table name. Field% type declare Define two variables, name and salary, respectively pename emp.ename%type; psal emp.sal%type; begin --SQL statement --select ename,sal from emp where empno = 7369; PLSQL statement, which puts the value of ename in the pename variable and the value of sal in the psal variable select ename,sal into pename,psal from emp where empno = 7369; - Output dbms_output.put_line('7369 employee's name is'| pename | salary is' | | psal); end; / Output 7788 employee name and salary, the format is as follows: 7788 employee name is SMITH, salary is 3000, grammar: use table name% rowtype declare emp_record emp%rowtype; begin select * into emp_record from emp where empno = 7788; dbms_output.put_line('7788 employee's name is'| emp_record.ename |', salary is' | | emp_record.sal); end; /
When do you use% type and% rowtype?
- When defining a variable, the type of the variable is the same as that of a field in the table, you can use% type
- When defining a variable, which is exactly the same as the whole table structure, you can use% rowtype, and then you can get the corresponding value in the variable by the variable name. field name.
- In projects, commonly used% type
Judgment body
Grammar:
It's worth noting that eslif is not wrong. It's missing an e.
Example
//Useif-else-end ifWhat day is it today? Yes."Working day"still"Rest Day"
declare
pday varchar2(10);
begin
select to_char(sysdate,'day') into pday from dual;
dbms_output.put_line('Today is the day.'||pday);
if pday in ('Saturday','Sunday') then
dbms_output.put_line('Rest Day');
else
dbms_output.put_line('Working day');
end if;
end;
/
//Receive values from the keyboard, usingif-elsif-else-end ifdisplay"age<16","age<30","age<60","age<80"
declare
age number(3) := &age;
begin
if age < 16 then
dbms_output.put_line('You're under age');
elsif age < 30 then
dbms_output.put_line('Your youth');
elsif age < 60 then
dbms_output.put_line('You struggle');
elsif age < 80 then
dbms_output.put_line('You enjoy people');
else
dbms_output.put_line('Unfinished');
end if;
end;
/
loop
In PLSQL, there are three grammars of loops:
WHILE cycle:
- while is followed by a loop condition, similar to java, LOOP and END LOOP are the keywords **
WHILE total <= 25000
LOOP
total : = total + salary;
END LOOP;
LOOP cycle:
- The condition behind exit is set before it exits the loop.
Loop
exit [when Conditions hold];
total:=total+salary;
end loop;
FOR cycle:
- The increment of the loop can only be 1. You can't customize the step size.
FOR I IN 1 . . 3 LOOP Statement sequence; END LOOP ;
Example
//Using loop loops to display1-10
declare
i number(2) := 1;
begin
loop
--Wheni>10Exit the loop
exit when i>10;
--outputiValue
dbms_output.put_line(i);
--Independent addition of variables
i := i + 1;
end loop;
end;
/
//UsewhileCyclic display1-10
declare
i number(2) := 1;
begin
while i<11
loop
dbms_output.put_line(i);
i := i + 1;
end loop;
end;
/
//UsewhileCycle, to emp Insert in table999A record
declare
i number(4) := 1;
begin
while( i < 1000 )
loop
insert into emp(empno,ename) values(i,'Ha-ha');
i := i + 1;
end loop;
end;
/
//UsewhileCycle, from emp Delete from the table999A record
declare
i number(4) := 1;
begin
while i<1000
loop
delete from emp where empno = i;
i := i + 1;
end loop;
end;
/
//UseforCyclic display20-30
declare
i number(2) := 20;
begin
for i in 20 .. 30
loop
dbms_output.put_line(i);
end loop;
end;
/
cursor
The cursor in Oracle is actually a resultSet similar to that in JDBC, which is the concept of a pointer.
Since it is similar to resultSet, cursors are only valid for queries.
grammar
CURSOR cursor name [(parameter name data type [, parameter name data type]...] IS SELECT statement;
Example
//Use cursor without reference to query the names and salaries of all employees. [If you need to traverse more than one record, use cursor with no record to find the use of cemp%notfound]
declare
--Define cursors
cursor cemp is select ename,sal from emp;
--Define variables
vename emp.ename%type;
vsal emp.sal%type;
begin
--Open the cursor, which is before the first record
open cemp;
--loop
loop
--Move the cursor down once
fetch cemp into vename,vsal;
--Exit the cycle,When the cursor is moved down once and no record is found, the loop exits.
exit when cemp%notfound;
--Output results
dbms_output.put_line(vename||'--------'||vsal);
end loop;
--Close the cursor
close cemp;
end;
/
//Using cursor with reference cursor, query10Name and salary of employees in No. 1 Department
declare
cursor cemp(pdeptno emp.deptno%type) is select ename,sal from emp where deptno=pdeptno;
pename emp.ename%type;
psal emp.sal%type;
begin
open cemp(&deptno);
loop
fetch cemp into pename,psal;
exit when cemp%notfound;
dbms_output.put_line(pename||'The salary is'||psal);
end loop;
close cemp;
end;
/
//Use cursor without reference cursor to really raise employees'salary and analyYST to increase1000,MANAGER rise800,Other gains400,Request display number, name, position, salary
declare
cursor cemp is select empno,ename,job,sal from emp;
pempno emp.empno%type;
pename emp.ename%type;
pjob emp.job%type;
psal emp.sal%type;
begin
open cemp;
loop
fetch cemp into pempno,pename,pjob,psal;
--Cyclic exit conditions must be written
exit when cemp%notfound;
if pjob='ANALYST' 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;
commit;
close cemp;
end;
/
Exceptions, anomalies
As we have seen from the PLSQL grammar above, there is an exception, which is called an exception in Oracle, and we can also simply see that achievement is an exception in Java...
Grammar:
Define exceptions in the declare section out_of exception ; Throw an exception in a feasible statement in the begin section raise out_of ; Handling exceptions in the exception section when out_of then ...
Example
//Using the built-in exceptions of oracle system, the demonstration except 0 cases [zero_divide]
declare
myresult number;
begin
myresult := 1/0;
dbms_output.put_line(myresult);
exception
when zero_divide then
dbms_output.put_line('The divisor cannot be zero');
delete from emp;
end;
/
//Use the built-in exceptions of oracle system to query the employee name of department 100 and demonstrate that no data was found.
declare
pename varchar2(20);
begin
select ename into pename from emp where deptno = 100;
dbms_output.put_line(pename);
exception
when NO_DATA_FOUND then
dbms_output.put_line('No staff in this department');
insert into emp(empno,ename) values(1111,'ERROR');
end;
/
Stored Procedures and Stored Functions
In Oracle, the concepts of stored procedures and stored functions are similar. Generally, we can use them together. But sometimes the process is better, sometimes the function is better. Next, we will explain when to use a process or a function.
First, before we learn stored procedures and stored functions, we need to understand why we need to learn them. .
In fact, stored procedures and functions are similar to the concept of functions in Java. .
So far, our PLSQL has several shortcomings:
- PLSQL can't encapsulate it. Every time it calls, it copies the whole code to call it.
- Sometimes, we want to save PLSQL code, we can only save it manually in the hard disk, very troublesome.
- We learn about databases so that programs can be called, but PLSQL can't make programs (java) call.
Therefore, stored procedures and stored functions can solve the above problems, can encapsulate the code, save it in the database, let the programming language to invoke. .
Grammar of stored procedures and functions
The grammar of process:
create [or replace] procedure Process name[(parameter list)]
as
PLSQLProcedure body;[begin...end;/]
Grammar of functions:
CREATE [OR REPLACE] FUNCTION Function name[(parameter list) ]
RETURN return type
AS
PLSQL Subprogram body;
[begin...end;/]
The declare keyword is replaced by the as keyword in both process and function.
Process examples
Create the first process:
CREATE OR REPLACE PROCEDURE hello
AS
BEGIN
dbms_output.put_line('hello world');
END;
There are three ways to invoke a procedure:
- exec procedure name [used in SQLPLUS]
- PLSQL program call
- Java calls
PLSQL Call
BEGIN
hello();
END;
Create a reference stored procedure raiseSalary (No.) to increase the salary of Employee 7369 by 10%. Demonstrate the use of in, default in, case insensitive
CREATE or REPLACE PROCEDURE bb(pempno in NUMBER)
AS
BEGIN
UPDATE EMP
SET sal = sal * 1.2
WHERE empno = pempno;
END;
Call:
BEGIN
bb(7369);
END;
Create FindEmpName AndSalAndJob (Number) with reference stored procedure, query 7788 employee's name, position, monthly salary, return multiple values, demonstrate the use of out
Creation process: In the process parameters, the default value is IN, if it is output, then we need to specify OUT.
CREATE OR REPLACE PROCEDURE find(pempno IN NUMBER, psal OUT VARCHAR2, pename OUT VARCHAR2, pjob OUT VARCHAR2)
AS
BEGIN
SELECT
ename,
sal,
job
INTO pename, psal, pjob
FROM emp
WHERE empno = pempno;
END;
Invocation: When invoking, the psal, pname and pjob used are not defined at the time of invocation, so we need to define variables before using them!
DECLARE
psal emp.sal%TYPE;
pename emp.ename%TYPE;
pjob emp.job%TYPE;
BEGIN
find(7369, psal, pename, pjob);
dbms_output.put_line(psal || pename || pjob);
END;/
Examples of functions
Create a parametric storage function findEmpIncome (number), query the annual income of employees 7369, demonstrate the use of in, default in
CREATE OR REPLACE FUNCTION findEmpIncome(pempno IN NUMBER)
--What is specified here is the return value type.
RETURN NUMBER
AS
income NUMBER;
BEGIN
SELECT sal * 12
INTO income
FROM emp
WHERE empno = pempno;
/*There must be a return statement in PLSQL*/
RETURN income;
END;
Call: In PLSQL, the assignment statement is not a direct "=", but::=
DECLARE
income number;
BEGIN
income := findEmpIncome(7369);
dbms_output.put_line(income);
END;/
If you write the = sign, the following error will occur:
[2017-07-11 13:58:14] [65000][6550] ORA-06550: Line 4, Column 10:
PLS-00103: Appearance Symbol "="When one of the following is needed:
:= . ( @ % ;
ORA-06550: Line 4, Column 31:
PLS-00103: Appearance Symbol ";"When one of the following is needed:
. ( ) , * % & -
+ / at mod remainder rem <an exponent (**)> and or ||
multiset
ORA-06550: Line 7, Column 4:
PLS-00103: Appearance Symbol "end-of-file"When one of the following is needed:
end
not pragma final instantiable order overriding static member
constructor map
Create a parameter storage function findEmpName AndJob AndSal (number), query the name (return), position (out), monthly salary (out) of 7788 employees, and return multiple values.
CREATE OR REPLACE FUNCTION findEmpNameAndJobAndSal(pempno IN NUMBER, pjob OUT VARCHAR2, income OUT NUMBER)
--What is specified here is the return value type.
RETURN VARCHAR
AS
/*Queried fields are the same as column names, so use the same type of column names.*/
pename emp.ename%TYPE;
BEGIN
SELECT
sal,
ename,
job
INTO income, pename, pjob
FROM emp
WHERE empno = pempno;
/*There must be a return statement in PLSQL*/
RETURN pename;
END;
Call function:
DECLARE
/*The output field is of the same type as the column name.*/
income emp.sal%TYPE;
pjob emp.job%TYPE;
pename emp.ename%TYPE;
BEGIN
pename := findEmpNameAndJobAndSal(7369, pjob, income);
dbms_output.put_line(pename || pjob || income);
END;/
Scenarios for the Use of Processes and Functions
We find that the difference between process and function is not very big. Generally, when we can use function to achieve, we can also use process to achieve. .
However, there are always some situations, using function is better than using process, using process is better than using function, when to use process, when to use function???
It is not difficult to find that a function must have a return value. When we call it, we accept the return value and get it directly.
In other words
- When the return value has only one parameter, the storage function is used!
- When the return value has no parameter or more than one parameter, use the procedure!
Scenarios for the Use of SQL and Procedural Functions
[Suitable for use] Process functions:
- > Need to be stored in the database for a long time
- > Need to be called repeatedly by multiple users
- > Business logic is the same, but parameters are different
- > Batch manipulation of large amounts of data, e.g. batch insertion of large amounts of data
[Suitable for use] SQL:
- > Any of the above negative, you can use SQL
- > Use SQL for tables, views, sequences, indexes, etc.
trigger
In PLSQL, there is a concept similar to filter in our Java Web, which is trigger. The idea of trigger is almost the same as that of Filter. .
It is worth noting that for triggers, they are not for query operations. That is to say: triggers only for deletion, modification, insertion operations!
Trigger grammar
CREATE [or REPLACE] TRIGGER Trigger Name
{BEFORE | AFTER}
{ INSERT | DELETE|-----Statement level
UPDATE OF Column names}----Row level
ON Table name
-- Traverse through each row of records
[FOR EACH ROW]
PLSQL Block [declare...begin...end;/]
Example
Create a statement-level trigger insertEmpTrigger to display "hello world" before adding an insert operation to the table [emp]
CREATE OR REPLACE TRIGGER insertempTiriger
BEFORE
INSERT
ON EMP
BEGIN
dbms_output.put_line('helloword');
END;
Call:
INSERT INTO EMP (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO) VALUES (1, '2', '3', 4, NULL, NULL, NULL, 10);
Result:
Monday to Friday, and 9-20 points can insert data into the database emp table, otherwise use functions to throw exceptions.
Syntax: raise_application_error('-20000','exceptional cause')
CREATE OR REPLACE TRIGGER securityTrigger
BEFORE
INSERT
ON EMP
DECLARE
pday VARCHAR2(10);
ptime NUMBER;
BEGIN
/*Get Wednesday*/
SELECT to_char(sysdate, 'day')
INTO pday
FROM dual;
/*Get Time*/
SELECT to_char(sysdate, 'hh24')
INTO ptime
FROM dual;
IF pday IN ('Saturday', 'Sunday') OR ptime NOT BETWEEN 7 AND 23
THEN
RAISE_APPLICATION_ERROR('-20000', 'Non-work events, please come back at work time!');
END IF;
END;
Insert data, response trigger:
INSERT INTO EMP (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO) VALUES (3, '2', '3', 4, NULL, NULL, NULL, 10);
Create a row-level trigger checkSalary Trigger to ensure that the salary column after the increase is larger than the salary before the increase. Grammar: for each row/:new.sal/:old.sal
You can use: new.sal/:old.sal to compare values before and after insertion
CREATE OR REPLACE TRIGGER checkSalTrigger
BEFORE
UPDATE OF sal
ON EMP
FOR EACH ROW
BEGIN
IF :new.sal <= :old.sal
THEN
RAISE_APPLICATION_ERROR('-20001', 'Your salary increase is too small!!!');
END IF;
END;
Call:
UPDATE emp
SET sal = sal - 1
WHERE empno = 7369;