当前位置:网站首页>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 

 Insert picture description here

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;

 Insert picture description here
   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;

 Insert picture description here
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 DELETE Filter 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';

 Insert picture description here

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

 Insert picture description here

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

 Insert picture description here

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 TABLE Command 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;
原网站

版权声明
本文为[The head is really heavy y]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/03/202203011806342590.html

随机推荐