oracle pl/sqlkczxsp.hnu.edu.cn/upload/20191017093113878.pdf · 16 run/call stored function ....
TRANSCRIPT
1
Oracle PL/SQL
January 9, 2007
Dai Mu-Hong Copyright 2007
2
1. Introduction
• SQL vs. PL/SQL
SQL: A command or statement to 1. Query ( select ) 2. DML. Manipulate ( insert, update, delete ) 3. DDL. Create database objects ( table, view, index,..) PL/SQL: Procedural programming extention of SQL Developed and used by Oracle only PL/SQL = SQL + Loop, Condition, Error handling
3
1. Introduction
• SQL vs. PL/SQL
3 Basic Types of PL/SQL program: Procedure: Return none or multiple values Function: Return one value Trigger: An event driven program Package is a group of procedures and functions organized together for easier management and higher performance
4
2. Components of PL/SQL program
1. Declare - Use this part to declare all the variables with their datatype and default values used in the program. If no variables used in the program, this section can be omitted.
2. Begin - Start of the execution part
3. Exception - In case of run time errors occured, program enter this section
automatically. You can write codes here to handle the errors. This section may be omitted. In this case, the program will stop to run and error out when there is a run time error.
4. End - End of Program - Do not forget to put a dash / at the begining of next line, as the final end of the program.
5
Why need a - / - at the end of the program? Declare Begin For Loop Declare Begin Exception End; End Loop; Exception End; /
6
A Sample Program
CITY table has 2 coumns, ID and Name.
For ID (5) and name (changsha), the program: 1. Query the table with ID 5 2. If ID already exists, do Update Else, do a insert
DECLARE v_cnt number; v_id number; v_name varchar2(10); BEGIN v_id := 5; v_status := 'changsha'; SELECT count(*) INTO v_cnt FROM CITY WHERE ID = v_id;
IF v_cnt > 0 Then
UPDATE CITY SET name = v_name WHERE id = v_id;
ELSE
INSERT INTO CITY ( id, name ) values (v_id, v_name);
END IF; COMMIT; Exception when others then null; END; /
SQL> @ test21.sql
2. Components of PL/SQL program
7
Varable datatype in Declare Section
1. Number v_id number; Number(4) Number(5,2)
Integer Binary_integer
char(5) varchar2(20) v_name varchar2(30);
Date v_entry_date Date;
Boolean v_pass Boolean; 2. %type v_Emp_name EMP.ename%type; %rowtype v_EMP_REC EMP%rowtype; 3. Cursor Cursor c_emp is select * from emp; 4. Exception E_1 Exception; 5. Self defined type Record or array
2. Components of PL/SQL program
8
Assignment
V_ID := 5; V_Name := 'Chang Sha'; V_Phone := '0371-888 1234'; V_Phone_area_code := substr ( v_phone, 1, 4); V_Start_Date := Sysdate; V_Start_date := to_date('1/2/2007','MM/DD/YYYY'); V_Full_Name := v_last_name || v_first_name; V_Pass := TRUE;
1. Select count(*) Into v_cnt From emp Where deptno = v_deptno; 2. Select * Into R_Emp From emp where deptno = v_deptno; v_empno := R_Emp.empno;
2. Components of PL/SQL program
For direct asignment, using :=
For asignment with Select, using INTO
For comparism, equal =, Not Eaqual != or <>
9
Logic Control IF
IF x=5 Then Insert ….. Elsif .................. Else Update …. End If;
WHILE
X := 1; While x < 5 Loop Do something; X := X + 1; End Loop;
CASE A. Case X when 5 then y := 50; when 8 then y := 1000; else y := 0; End case; B. Case when x=5 then y := 50; when x>5 then y := 1000; Else y := 0; End case;
GOTO IF x=5 Then GOTO some_where; End If; ........ <<some_where>> At least one line here .......
2. Components of PL/SQL program
10
LOOP
1. LOOP ..... Exit when .... End Loop;
2. For k in 1..5 LOOP ....... End Loop;
3. While x < 5 LOOP ..... x := x + 1; End Loop;
4. -- c_emp is a cursor For v_emp in c_emp Loop Insert Into ...... values ( v_emp.sal, ...); End Loop;
2. Components of PL/SQL program
11
Exception
Declare v_ename emp.ename%type; v_sal number;
-- e1 exception; -- e2 exception;
Begin
select ename into v_ename from emp where enmno = '123456'; select sal into v_sal from emp where deptno = 10;
--Exception
End; /
2. Components of PL/SQL program
1. Without exception part 2. With exception part use when others syntax in exception handling. 3. Handle exception for each select statement 4. Raise exception in the select, then pass the exception to the main Exception part
12
• Exception
• When no_data_found then
• V_msg := 'no company for id '||TO_CHAR (v_id);
• V_err := SQLCODE;
• V_prog := 'fixdebt';
• INSERT INTO errlog VALUES
• (V_err,v_msg,v_prog,SYSDATE,user);
• When others then
• V_err := SQLCODE;
• V_msg := SQLERRM;
• V_prog := 'fixdebt';
• INSERT INTO errlog VALUES
• (V_err,v_msg,v_prog,SYSDATE,user);
• Raise;
13
Anonymous Procedure
1. Declare ...... Begin .... Exception ...... End; / Save above codes as Test.sql This file is saved in the client hard drive, not in the Database. Runing this file is running the code inside the file. SQL> @test.sql
2. Create or replace procedure T1 as ...... Begin .... Exception ...... End; / Save above codes as Test.sql, in the hard drive. Runing this file only compile and create a procedure named T1 in the database, NOT running the code inside the file. To run the codes, we need to execute the procedure T1. SQL> @test.sql SQL> Exec T1
Stored Procedure
3. Procedure and Function
14
Pass Parameters
1. Declare x number; Begin x := &1; .... Exception ...... End; / Save above codes as Test.sql SQL> @test.sql
2. Create or replace procedure T1 ( p1 in number, p2 in varchar2 ) as ...... Begin .... Exception ...... End; / Save above codes as Test.sql SQL> @test.sql SQL> Exec T1(5, 'Mike')
Stored Procedure Anonymous Procedure
3. Procedure and Function
15
Run/Call Stored procedure
Procedure T1: Create or replace procedure T1 ( p1 in number, p2 in number, p3 out number ) as Begin p3 := p1 + p2; End; / Save above codes as P_Test1.sql to create T1 SQL> @P_test1.sql SQL> Exec T1(5, 'Mike')
Procedure T2: Create or replace procedure T2 (x number, y number) as Z number; Begin T1(X, Y, Z); dbms_output.put_line ('The sum of ' || x || ' and ' || Y || ' is ' || Z); End; / Save above codes as P_Test2.sql to create T2 SQL> @P_test2.sql SQL> Exec T2(5, 8)
3. Procedure and Function
16
Run/Call Stored function
Procedure T1: Create or replace function T1 ( p1 in number, p2 in number -- p3 out number ) Return number as Begin return( p1 + p2); End; / Save above codes as P_Test1.sql to create T1 SQL> @P_test1.sql SQL> select T1(3,5) from dual;
Procedure T2: Create or replace procedure T2 (x number, y number) as Z number; Begin Z := T1(x,y); dbms_output.put_line ('The sum of ' || x || ' and ' || Y || ' is ' || Z); End; / Save above codes as P_Test2.sql to create T2 SQL> @P_test2.sql SQL> Exec T2(5, 8)
3. Procedure and Function
17
Run/Call Stored Function
Function F1: Create or replace function F1 (p1 in varchar2) Return varchar2 as v_in varchar2(30) := p1; v_out varchar2(30); Begin while length(v_in) > 0 Loop v_out := v_out || substr(v_in, length(v_in),1); v_in := substr(v_in, 1, length(v_in)-1); End Loop; Return v_out; End; / Save as F_Test1.sql, to create function F1 SQL> @F_test1.sql After Function F1 created, we may use it in SQL or programs.
Run/Call Function F1 A. In SQL statement SQL> select f1('ABCD') from dual;
SQL> select dname, substr(f1(dname),1,20) from dept; B. Call from procedure or function Set serveroutput on Declare Z varchar2(20); Begin Z:= F1('HuNan University'); dbms_output.put_line( Z); End; / Save above codes as Test3.sql SQL> @test3
3. Procedure and Function
18
Using Cursor
Procedure T5: Set serveroutput on size 100000 Declare Cursor c1 is select * from Emp; Begin For v1 in c1 loop dbms_output.put_line (v1.ename || ' makes a salary of ' || v1.sal); End; / Save above codes as P_Test3.sql SQL> @P_test3.sql
3. Procedure and Function
19
Exception
3. Procedure and Function
Declare v_ename emp.ename%type; v_sal number; -- e1 exception; -- e2 exception; Begin select ename into v_ename from emp where enmno = '123456'; select sal into v_sal from emp where deptno = 10; --Exception End; /
1. Without exception part 2. With exception part use when others syntax in exception handling. 3. Handle exception for each select statement 4. Raise exception in the select, then pass the exception to the main Exception part
20
Procedure T6: handle exception while continue to process Declare Begin For Loop Declare Begin Exception End; End Loop; Exception End; /
3. Procedure and Function Exception
21
Create or Replace procedure P1 (p_in number) as v_line varchar2(20):= '*'; Begin For i in 1..p_in Loop v_line := Rpad(v_line, i, '*'); DBMS_Output.put_line(v_line); End Loop; End; / SQL> Set Serveroutput on SQL> Exec p1(6)
3. Procedure and Function Examples: 1a. Single For Loop
22
Create or Replace procedure P99 as v_line varchar2(150); z varchar2(20); Begin For i in 1..9 Loop v_line := NULL; For j in 1..9 Loop z := i || '*' || j || '=' || i*j; z := rpad(z, 7); v_line := v_line || ' ' || z; End Loop; -- j loop DBMS_output.put_line(v_line); End Loop; -- i loop End; / SQL> Set Serveroutput on SQL> Exec p99
3. Procedure and Function Examples: 1b. Double For Loop
23
Create or Replace function Is_Prime (p_in number) Return Boolean as v_prime boolean := true; Begin If P_in in (1,2,3) Then v_prime := true; goto print_section; End if; For i in 2.. round(p_in/2)
Loop if mod(p_in, i) = 0 Then v_prime := false; exit; end if; End Loop; <<print_section>> return v_prime; End; /
3. Procedure and Function Examples: 2. Prime Number Create or Replace procedure G_Guess
(p_in number) as j number; v_result varchar2(100) := null;
Begin If is_prime(p_in) then v_result := P_in || ' itself is a prime'; goto print_result; End If;
For i in 1..p_in/2 Loop j := p_in - i; if is_Prime(i) and is_prime(j) Then v_result :=p_in || ' = ' || i || ' + ' || j; Exit; End if;
End Loop; <<print_result>> If v_result is not null Then dbms_output.put_line (v_result); else dbms_output.put_line ('G Guess fail.'); end if; End; /
24
3. Procedure and Function
Tracing and Debugging
Find/Correct Compiling Syntax errors SQL> show error Find/Correct Run time error Using a loc variable, then Display loc at exception section Using GOTO to bypass some parts of the program
25
4. Trigger
A unique Implementation of PL/SQL • Stored in DB, but not stored procedure or functions
• Event Driven
• Perform some kind of action in the database
Purpose of Trigger • Maintain complex integrity constraints
• Auditing
• Automatically signaling other programs when changes are made to a table
26
A. System Trigger on system events, such as Logon and logoff on DDL, such as create database objects B. Database Trigger Fired by a DML statement, such as Insert, update, or delete
4. Trigger
Types of Triggers
27
Create table Test9 ( User_name varchar2(20), Log_Time date ); Create or replace trigger T9 after logon on schema -- Before logoff on schema when (user = 'SCOTT') Begin Insert into Test9 values (user, sysdate); End; /
4. Trigger Example of System Trigger
28
4. Trigger
Create Table Test_10 (Greeting varchar2(30)); Create or Replace Trigger T_10 Before Insert on Test_10 For Each Row Declare Begin IF upper(:new.greeting) like '%BAD%' then :new.greeting := replace(upper(:new.greeting), 'BAD', 'GOOD'); :new.greeting := initcap(:new.greeting); End IF; End; /
Example of Database Trigger (1)
29
4. Trigger
Create Table test_10 (Greeting varchar2(30));
Create Table Good_Bad (B_Word varchar2(20), G_Word varchar2(20)); Insert into Good_Bad values ('BAD' , 'GOOD' ); Insert into Good_Bad values ('HATE', 'LOVE' ); Insert into Good_Bad values ('SAD' , 'HAPPY'); COMMIT;
Create or Replace Trigger T_10B Before Insert on Test_10 For Each Row Declare Cursor c1 is select * from Good_Bad; Begin For v1 in c1 Loop :new.greeting := replace(upper(:new.greeting), v1.B_Word, v1.G_Word); :new.greeting := initcap(:new.greeting); End Loop; End; /
Example of Database Trigger (1B)
30
4. Trigger
Create Table test_10 (Greeting varchar2(30)); Create Table test_11 (username varchar2(10), insert_time date, comment varchar2(50));
Create or Replace Trigger T_11 After Insert on Test_10 For Each Row Begin Insert into Test_11 values (user, sysdate, 'Inserted value is: ' || :new.greeting); End; /
Example of Database Trigger (2)
31
4. Trigger
Create Table Account ( Cust_name varchar2(20), account# varchar2(10), balance number, interest number ); Create Table Account_Audit ( account# varchar2(10), username varchar2(10), upd_time date, old_balance number, new_balance number, old_interest number, new_interest number );
Example of Database Trigger (3)
Create or Replace Trigger T_12 After Update on Account For Each Row Begin Insert into Account_Audit values ( :old.account#, user, sysdate, :old.balance, :new.balance, :old.interest, :new.interest ); End; /