当前位置:网站首页>Usage methods and cases of PLSQL blocks, cursors, functions, stored procedures and triggers of Oracle Database
Usage methods and cases of PLSQL blocks, cursors, functions, stored procedures and triggers of Oracle Database
2022-06-11 20:05:00 【The head is really heavy y】
One ,PL SQL
1) Introduce
PL/SQL Block is in sql An application developed on the basis of language in a sentence , It can deal with all kinds of complex SQL operation .
Sentence format :
DECLARE:
Declaration part
BEGIN
Write a topic
EXCEPTION
Capture exception
END
/
2)do…while loop
PL/SQL It also includes : loop 、 Conditional control statements such as branches .
Sentence format :
LOOP
A circular statement
EXIT WHEN Termination conditions
The loop condition must be changed
END LOOP ;
Cyclic output 1~10:
DECLARE
cou NUMBER ;
BEGIN
-- You must give an initial value
cou := 1;
LOOP
DBMS_OUTPUT.put_line('cou = ' || cou);
EXIT WHEN cou > 10;
cou := cou + 1;
END LOOP;
END ;
/
-- This loop will be executed once before the loop

3)while loop
Format :
while( Judge the conditions of the cycle ) loop
A circular statement ;
Changes in cycle conditions ;
END loop;
Cyclic output 1~10:
DECLARE
cou NUMBER ;
BEGIN
-- You must give an initial value
cou := 1;
WHILE(cou < 10) LOOP
DBMS_OUTPUT.put_line('cou = ' || cou);
cou := cou + 1;
END LOOP;
END;
/
-- This loop will judge before executing the statement
4)for loop
Format :
FOR Variable name in The initial value of the variable .. End value lOOP
Loop statement ;
END loop;
Cyclic output 1~10:
DECLARE
cou NUMBER ;
BEGIN
-- This statement will automatically 1 To 10 Assign a value to cou
FOR cou in 1..10 loop
DBMS_OUTPUT.put_line('cou = ' || cou);
END LOOP;
END ;
/
5)if conditional
Format :
IF Conditions THEN
When conditions are met , Execute this statement
END IF;
Case study :
DECLARE
cou NUMBER ;
BEGIN
cou := 11;
IF cou > 10 THEN
DBMS_OUTPUT.put_line('cou = ' || cou);
end if;
END ;
/
-- Output 11
6)if…else conditional
Format :
IF Conditions THEN
When conditions are met , Execute this statement
END IF;
Case study :
DECLARE
cou NUMBER ;
BEGIN
cou := 8;
IF cou > 10 THEN
DBMS_OUTPUT.put_line('cou = ' || cou);
ELSE
DBMS_OUTPUT.put_line('cou = ' || cou);
end if;
END ;
/
-- Output 8
7)if…elsif…else conditional
Format :
IF Conditions THEN
When conditions are met , Execute this statement
ELSIF Conditions THEN
When this condition is met , Execute this statement
ELSE
END IF;
Case study :
DECLARE
cou NUMBER ;
BEGIN
cou := 8;
IF cou > 10 THEN
DBMS_OUTPUT.put_line('cou = ' || cou);
ELSIF cou < 5 THEN
DBMS_OUTPUT.put_line('cou = ' || cou);
ELSE
DBMS_OUTPUT.put_line('cou = ' || cou);
end if;
END ;
/
-- Output 8
8)GOTO sentence
Format :
IF Conditions THEN
When conditions are met , Execute this statement
ELSIF Conditions THEN
When this condition is met , Execute this statement
ELSE
END IF;
Case study :
DECLARE
emo EMPLOYEE.EMP00%TYPE;
name EMPLOYEE.EMP01%TYPE;
BEGIN
emo := '70443BA4-7174-46CC-8A7D-6DA04627B770';
SELECT EMP01 INTO name FROM EMPLOYEE WHERE EMP00 = emo;
IF name=' Zhou Kang ' THEN
GOTO po1;
ELSIF name=' Bai an ' THEN
GOTO po2;
ELSE
GOTO po3;
end if;
<<po1>>
DBMS_OUTPUT.put_line('po1');
<<po2>>
DBMS_OUTPUT.put_line('po2');
<<po3>>
DBMS_OUTPUT.put_line('po3');
END ;
/
Two , The cursor 、 function
1) The cursor
A cursor is a kind of PL/SQL Control structure , It can be done to SQL Statement processing for display control , It is convenient to process the row data of the table one by one . A cursor is not a database object , Just stored in memory .
Operation steps :
- declare cursor
- Open cursor
- Take out the results , At this time, the result is a whole row of data
- Close cursor
- Use ROWTYPE type , This type indicates that a whole row of data can be loaded in
DECLARE
emp EMPLOYEE.EMP00%TYPE; -- Define a parameter
empInfo EMPLOYEE%rowtype; -- Define a rowType, Used to hold a whole row of data
BEGIN
emp := '7350F9DE-F5BC-461A-B499-F86680D2DA4E';
SELECT * INTO empInfo FROM EMPLOYEE WHERE EMP00 = emp;
DBMS_OUTPUT.PUT_LINE(' full name =' || empInfo.EMP01); -- Can pass emoInfo. To access all the fields in this row
end;
2) Use for Loop operation cursor ( Commonly used )
DECLARE
CURSOR mycur IS SELECT * FROM EMPLOYEE; --List(EMPLOYEE)
empInfo EMPLOYEE%rowtype;
BEGIN
-- Cursor operations use loops , But the cursor must be opened before operation
OPEN mycur;
-- Move the cursor down one line
FETCH mycur INTO empInfo;
-- Determine whether there is any data found in this line
WHILE (mycur%FOUND) LOOP
DBMS_OUTPUT.put_line(' full name =' || empInfo.EMP01);
-- Modify the cursor
FETCH mycur INTO empInfo;
end loop;
end;
/
-- The names of all the people in the table are output
3) Cursor case exercise
Now we need to raise wages for employees in all departments , Raise wages according to their department , The following rules :
- 10 The sector rose
10% - 20 The sector rose
20% - 30 The sector rose
30% - The salary increase of employees in all departments can not exceed 5k, If it exceeds, press 5k Calculation .
DECLARE
cursor mycur is SELECT * FROM emp;
empInfo emp%rowtype;
s emp.sal%TYPE;
BEGIN
for empInfo in mycur loop
if empInfo.deptno = 10 then
s := empInfo.sal * 1.1;
elsif empInfo.deptno = 20 then
s := empInfo.sal * 1.2;
elsif empInfo.deptno = 30 then
s := empInfo.sal * 1.3;
end if;
if s > 5000 then
s = 5000;
end if;
UPDATE emp SET sal = s WHERE emp00 = empInfo.emp00;
end loop;
end;
/
4) function
A function is a process with a return value . Define a function , This function can find out the current position of the employee according to the transferred employee number .
CREATE OR REPLACE FUNCTION "function"(emp IN varchar2) RETURN VARCHAR2
AS
DMCPT VARCHAR2(1024);
BEGIN
SELECT DMCPT INTO DMCPT FROM EMPLOYEE LEFT JOIN DM07 ON EMPLOYEE.EMP11 = DM07.DMCOD WHERE EMP00 = emp;
RETURN DMCPT;
end;
/
SELECT "function"('7350F9DE-F5BC-461A-B499-F86680D2DA4E') FROM DUAL;

Function can be used to handle some complex logical business , It's equivalent to using the code sql Write it out in a way , At the same time, some general conversion formats and other codes can also be abstracted into a function . May refer to : Function that returns the time difference between the specified date and the current date
3、 ... and , stored procedure
Compared with the process , A stored procedure is a procedure that exists in a database object . If the compilation is wrong , It can be used show errors or show errors procedure myproc.
Define a simple stored procedure :
CREATE OR REPLACE PROCEDURE myproc1 --PROCEDURE n. The process , Program
AS
i NUMBER;
BEGIN
i := 100;
DBMS_OUTPUT.PUT_LINE('i=' || i); -- Calling stored procedure , Direct output 100
END;
/
If it's a command line window ,exec myproc1 You can call the stored procedure , If it is sql Under the window, you need to use PLSQL sentence
DECLARE
Defining parameters ;
BEGIN
myproc1; -- If the stored procedure has parameters , You need to pass parameters
END;
Write a stored procedure , The number of the person can be passed in 、 full name 、 Gender (0,1 Instead of ), After this stored procedure is invoked, the additional operation of personnel can be completed. .
CREATE OR REPLACE PROCEDURE myproc2(ENO EMPLOYEE.EMP00%TYPE, NAME EMPLOYEE.EMP01%TYPE, XB EMPLOYEE.EMP02%TYPE)
AS
cou NUMBER;
BEGIN
-- First, judge whether the number is used , If used, you cannot add
SELECT COUNT(EMP00) INTO cou FROM EMPLOYEE WHERE EMP00 = ENO;
IF cou = 0 THEN
-- You can add
INSERT INTO EMPLOYEE(EMP00, EMP01, EMP02) VALUES (ENO, NAME, XB);
DBMS_OUTPUT.PUT_LINE(' Personnel inserted successfully !');
ELSE
DBMS_OUTPUT.PUT_LINE(' This person number already exists , Can't insert !');
END IF;
END;
/
begin
myproc2('7350F9DE-F5BC-461A-B499-F86680D2DA4F', ' Yin yang man ', '1');
end;

Parameter types of stored procedures , Add... When specifying the parameter type , similar myproc2(ENO IN OUT EMPLOYEE.EMP00%TYPE):
- IN: Value passed , The default value is
- IN OUT: Bring value into , Bring out the value
- OUT: Bring no value into , Bring out the value
Delete stored procedure :
DROP PROCEDURE myproc2;
Four , trigger
Stored in a database , And implicitly executed stored procedure . stay Oracle 8i Before , Only tables and views are allowed DML operation , from 8i after , Not only can it support DML trigger , It is also allowed to give system events and DDL The operation of .
1) Statement triggers
- BEFORE Statement triggers , You can control the of the table
INSERT OR UPDATE OR DELETEFilter before operation :
-- It is forbidden to change employee information on rest days
CREATE OR REPLACE TRIGGER TR_SRC_EMP --TRIGGER n. trigger
BEFORE INSERT OR UPDATE OR DELETE
ON EMP
BEGIN
IF TO_CHAR(SYSDATE, 'DY', 'NLS_DATE_LANGUAGE=AMERICAN') IN ('SAT', 'SUN') THEN
RAISE_APPLICATION_ERROR(-20001, 'CAN‟T MODIFY USER INFORMATION IN WEEKEND');
END IF;
END;
/
-- You can listen to the type of operation here
CREATE OR REPLACE TRIGGER TR_SRC_EMP
BEFORE INSERT OR UPDATE OR DELETE
ON EMP
BEGIN
IF TO_CHAR(SYSDATE, 'DY') IN (' Saturday ', ' Sunday ') THEN
CASE
WHEN INSERTING THEN
RAISE_APPLICATION_ERROR(-20001, 'FAIL TO INSERT');
WHEN UPDATING THEN
RAISE_APPLICATION_ERROR(-20001, 'FAIL TO UPDATE');
WHEN DELETING THEN
RAISE_APPLICATION_ERROR(-20001, 'FAIL TO DELETE');
END CASE;
END IF;
END;
/
- AFTER Statement triggers , Operations after adding, deleting, and modifying tables :
-- For statistics in EMP Added in the table 、 Delete 、 Number of changes , Create a statistical table
CREATE TABLE AUDIT_TABLE
(
NAME VARCHAR2(20),
INS INT,
UPD INT,
DEL INT,
STARTTIME DATE,
ENDTIME DATE
);
-- Set up triggers , The number of additions, deletions and modifications is classified
CREATE OR REPLACE TRIGGER TR_AUDIT_EMP
AFTER INSERT OR UPDATE OR DELETE
ON EMP
DECLARE
V_TEMP INT;
BEGIN
SELECT COUNT(*) INTO V_TEMP FROM AUDIT_TABLE WHERE NAME ='EMP';
IF V_TEMP = 0 THEN
INSERT INTO AUDIT_TABLE VALUES ('EMP', 0, 0, 0, SYSDATE, NULL); -- without EMP The record of the table , Then build a new one
END IF;
CASE
WHEN INSERTING THEN
UPDATE AUDIT_TABLE SET INS=INS + 1, ENDTIME=SYSDATE WHERE NAME = 'EMP'; -- If it's a new operation , will INS+1, The same goes for other types
WHEN UPDATING THEN
UPDATE AUDIT_TABLE SET UPD=UPD + 1, ENDTIME=SYSDATE WHERE NAME = 'EMP';
WHEN DELETING THEN
UPDATE AUDIT_TABLE SET DEL= DEL + 1, ENDTIME=SYSDATE WHERE NAME = 'EMP';
END CASE;
END;
/
2) Row trigger , perform DML In operation , Trigger is triggered once for each line of action
- BEFORE Row trigger
-- When updating employee salaries , The new salary cannot be lower than the original salary
CREATE OR REPLACE TRIGGER TR_EMP_SAL
BEFORE UPDATE OF SAL -- Update trigger of salary field
ON EMP
FOR EACH ROW -- Create row triggers for each row
BEGIN
IF :NEW.SAL < :OLD.SAL THEN -- If the new salary is less than the old salary
RAISE_APPLICATION_ERROR(-20010, 'SAL SHOULD NOT BE LESS');
END IF;
END;
/
- AFTER Row trigger
-- Create a new process table , Count the salary changes of employees
CREATE TABLE AUDIT_EMP_CHANGE
(
NAME VARCHAR2(10),
OLDSAL NUMBER(6, 2),
NEWSAL NUMBER(6, 2),
TIME DATE
);
-- Set up triggers , Statistics of employee salary changes
CREATE OR REPLACE TRIGGER TR_SAL_SAL
AFTER UPDATE OF SAL -- Triggered after salary update
ON EMP
FOR EACH ROW
DECLARE
V_TEMP INT;
BEGIN
SELECT COUNT(*) INTO V_TEMP FROM AUDIT_EMP_CHANGE WHERE NAME = :OLD.ENAME;
IF V_TEMP = 0 THEN
INSERT INTO AUDIT_EMP_CHANGE VALUES (:OLD.ENAME, :OLD.SAL, :NEW.SAL, SYSDATE);
ELSE
UPDATE AUDIT_EMP_CHANGE
SET OLDSAL=:OLD.SAL,
NEWSAL=:NEW.SAL,
TIME=SYSDATE
WHERE NAME = :OLD.ENAME;
END IF;
END;
/
Add trigger row limit :
CREATE OR REPLACE TRIGGER TR_SAL_SAL
AFTER UPDATE OF SAL
ON EMP
FOR EACH ROW
WHEN (OLD.JOB ='SALESMAN') -- Only when employees JOB='SALESMAN' when , This trigger is triggered only when the salary is updated
DECLARE
V_TEMP INT;
BEGIN
SELECT COUNT(*) INTO V_TEMP FROM AUDIT_EMP_CHANGE WHERE NAME = :OLD.ENAME;
IF V_TEMP = 0 THEN
INSERT INTO AUDIT_EMP_CHANGE VALUES (:OLD.ENAME, :OLD.SAL, :NEW.SAL, SYSDATE);
ELSE
UPDATE AUDIT_EMP_CHANGE
SET OLDSAL=:OLD.SAL,
NEWSAL=:NEW.SAL,
TIME=SYSDATE
WHERE NAME = :OLD.ENAME;
END IF;
END;
/
3) Trigger notes
To write DML Trigger time , Trigger code cannot read data from the base table corresponding to the trigger .
If based on EMP Table creation trigger , Then the execution code of the trigger cannot contain pairs EMP Table query operation .
CREATE OR REPLACE TRIGGER TR_EMP_SAL
BEFORE UPDATE OF EMP01
ON EMPLOYEE
FOR EACH ROW
DECLARE
NAME VARCHAR2(8);
BEGIN
SELECT EMP01 INTO NAME FROM EMPLOYEE;
IF :NEW.EMP01 = NAME THEN
RAISE_APPLICATION_ERROR(-21000, 'ERROR');
END IF;
END;
/
-- No error will be reported when creating , But updating the table data will report an error
UPDATE EMPLOYEE SET EMP01=' Zhou Kang ' WHERE EMP00 = '7350F9DE-F5BC-461A-B499-F86680D2DA4E';

4) System event triggers
Triggers can help us do some data verification 、 Data recording, etc , stay Oracle Some system event triggers are built-in , be based on Oracle System events for (LOGON,STARTUP) The trigger created . By using system triggers , Provides a mechanism for tracking system or database changes , Some built-in system triggers are as follows :
| Trigger Name | purpose |
|---|---|
| ORA_CLIENT_IP_ADDRESS | Used to return to the client IP Address |
| ORA_DATABASE_NAME | Used to return the current database name |
| ORA_DES_ENCRYPTED_PASSWORD | For return DES Encrypted user password |
| ORA_DICT_OBJ_NAME | For return DDL The database object name corresponding to the operation |
| ORA_DICT_OBJ_NAME_LIST(NAME_LIST OUT ORA_NAME_LIST_T) | Used to return the list of object names modified in the event |
| ORA_DICT_OBJ_OWNER | For return DDL The owner name of the object corresponding to the operation |
| ORA_DICT_OBJ_OWNER_LIST(OWNER_LIST OUT ORA_NAME_LIST_T) | Used to return the owner list of the object modified in the event |
| ORA_DICT_OBJ_TYPE | For return DDL The type of data object corresponding to the operation |
| ORA_GRANTEE(USER_LIST OUT ORA_NAME_LIST_T) | Used to return the authorizer of the authorization event |
| ORA_INSTANCE_NUM | Used to return routine number |
| ORA_IS_ALTER_COLUMN(COLUMN_NAME IN VARCHAR2) | Used to detect whether a specific column has been modified |
| ORA_IS_CREATING_NESTED_TABLE | Used to detect whether nested tables are being built |
| ORA_IS_DROP_COLUMN(COLUMN_NAME IN VARCHAR2) | Used to detect whether a specific column has been deleted |
| ORA_IS_SERVERERROR(ERROR_NUMBER) | Used to detect whether a specific... Is returned Oracle error |
| ORA_LOGIN_USER | Used to return the login user name |
| ORA_SYSEVENT | Used to return the name of the system event that triggered the trigger |
5) Establish system event trigger
With the above system event trigger , You can create some special triggers .
- Log user login and logout events , Login and exit triggers can be established respectively :
-- Establish login and exit information table
CREATE TABLE log_table
(
USERNAME VARCHAR2(20),
LOGON_TIME DATE,
LOGOFF_TIME DATE,
ADDRESS VARCHAR2(20)
);
Established LOG_TABLE After the table , You can create triggers to operate on this table , Login trigger and exit trigger must be established with privileged user identity , And the login trigger can only use AFTER keyword , The exit trigger can only use BEFORE keyword :
CREATE OR REPLACE TRIGGER tr_logon
AFTER LOGON ON DATABASE
BEGIN
INSERT INTO LOG_TABLE(USERNAME, LOGON_TIME, ADDRESS)
VALUES(ORA_LOGIN_USER, SYSDATE, ORA_CLIENT_IP_ADDRESS);
END;
/
CREATE OR REPLACE TRIGGER tr_logoff
BEFORE LOGOFF ON DATABASE
BEGIN
INSERT INTO LOG_TABLE(USERNAME, LOGOFF_TIME, ADDRESS)
VALUES(ORA_LOGIN_USER, SYSDATE, ORA_CLIENT_IP_ADDRESS);
END;
/

- DDL trigger , In order to record what happened to the system DDL event (create、alter、drop) etc. , Can be established DDL trigger , First, establish a storage system DDL Tables of information :
CREATE TABLE EVENT_DDL
(
EVENT VARCHAR2(20),
USERNAME VARCHAR2(20),
OWNER VARCHAR2(10),
OBJNAME VARCHAR2(20),
OBJTYPE VARCHAR2(10),
TIME DATE
);
Set up triggers , Use AFTER keyword , Record what happened in the table DDL operation :
CREATE OR REPLACE TRIGGER tr_ddl
AFTER DDL ON SCHEMA
BEGIN
INSERT INTO event_ddl1 VALUES (ORA_SYSEVENT, ORA_LOGIN_USER, ORA_DICT_OBJ_OWNER, ORA_DICT_OBJ_NAME, ORA_DICT_OBJ_TYPE, SYSDATE);
END;
/
DROP TABLE TEST;

6) Manage triggers
- See all triggers
SELECT TRIGGER_NAME, STATUS FROM USER_TRIGGERS;
- Disable triggers , Disable trigger means to disable the trigger temporarily , When the trigger is in ENABLE In the state of , If you execute on the table DML operation , The corresponding trigger will be triggered . If based on INSERT The operation establishes a trigger , When using SQL*Loader When loading large amounts of data , In order to speed up efficiency , Triggers should be temporarily disabled :
ALTER TRIGGER TR_CHECK_SAL DISABLE;
- Activate trigger
ALTER TRIGGER TR_CHECK_SAL ENABLE;
- Batch prohibition 、 Activate trigger
ALTER TABLE EMPLOYEE DISABLE ALL TRIGGERS; -- Batch operation of all triggers in a table
ALTER TABLE EMPLOYEE ENABLE ALL TRIGGERS;
- Recompile trigger , When using
ALTER TABLECommand to modify table structure ( Add or delete columns ) when , Will turn its trigger into INVALID state , In this case , In order for the trigger to continue to work , Trigger needs to be recompiled :
ALTER TRIGGER TR_DDL COMPILE;
- Delete trigger
DROP TRIGGER TR_EMP_SAL;
边栏推荐
- QQ贴吧那种图片一点开,就变了的原理
- Template and requirements of curriculum design of reinforced concrete structure in autumn 21 of Dagong [standard answer]
- Off line operation of situation and policy (version) of Dayong in autumn 21 [standard answer]
- In 2021, the global revenue of Indian fragrant rice was about $12530 million, and it is expected to reach $21670 million in 2028
- Experiment report of basic mechanical experiment (II) of School of distance and continuing education, Dalian University of technology [standard answer]
- Golang学习笔记—基础篇
- Poj1028 web navigation
- Questions and requirements of the "high rise building structure" assignment of Dayong in the 21st autumn [standard answer]
- The first bullet of comparative learning
- Flutter Doctor affiche les solutions que xcode n'a pas installées
猜你喜欢
随机推荐
In 2021, the global revenue of minoxidil will be about 1035million US dollars, and it is expected to reach 1372.6 million US dollars in 2028
Chrome V8 source code 48 The secret of weak type addition,'+'source code analysis
Golang学习笔记—基础篇
In 2021, the global revenue of flexible fireproof sealant is about 755.2 million dollars, and it is expected to reach 1211.7 million dollars in 2028
In 2021, the global ceramic substrate revenue will be about US $409.7 million, and it is expected to reach US $657.3 million in 2028
全名单!2022泰晤士亚洲大学排名公布!
Global Market Consulting - Research Report on the overall scale and application segmentation of the global HVDC converter station market in 2022
ORA-01089 ORA-19809 ORA-19815 超过了恢复文件的限制
导师转我800块,让我仿真一个电路(电源设计)
Current situation and future development trend of tropical forage seed market in the world and China from 2022 to 2028
Première formation sur les largeurs modernes
Hanging memory recursive dynamic programming (with example explanation POJ 1163)
周鸿祎:想做直播带货抹不下面子 数据勒索成突出的安全威胁
AHB2APB_bridge 设计
In 2021, the global revenue of Indian fragrant rice was about $12530 million, and it is expected to reach $21670 million in 2028
使用flask框架写挡板
AHB2Standard_handshake_bridge 设计
First modelarts training
秀创意,赢显卡!MMPose姿态估计创意大赛震撼来袭
AHB_Bus_Matrix_3x3 设计









