You are on page 1of 11

Giới thiệu PL/SQL

Bài 3: Lập trình PL/SQL


 Khái niệm PL/SQL
– PL/SQL (PL: Procedural Language – Ngôn ngữ
Thủ tục) là mở rộng của SQL, kết hợp vào trong
đó rất nhiều đặc tính của các ngôn ngữ lập trình
gần đây.
Trần Thị Bach Huệ – PL/SQL = SQL + các cấu trúc điều khiển của một
ngôn ngữ lập trình.

1 3

Nội dung bài học

 Giới thiệu PL/SQL  Cấu trúc một đoạn PL/SQL


– Biến và hằng DECLARE
– Các lệnh điều khiển Các khai báo
 Thủ tục (Procedure) BEGIN
 Hàm (Function) Các câu lệnh thực hiện
EXCEPTION
 Trigger
Xử lý ngoại lệ
 Package END;

2 4

1
Phép gán

 Ví dụ:  Ký hiệu: (:=)


– Ví dụ: c_heso NUMBER(3,2):=0.33;
declare
v_num NUMBER(2);
v_num number(2); v_num:=10;
begin  Sử dụng SELECT INTO
v_num:=3; SELECT ds cột INTO ds biến
FROM … WHERE …
dbms_output.put_line(v_num); – Ví dụ:
end; SELECT hosv, tensv INTO v_ho, v_ten
FROM sinhvien WHERE masv=‘A01’

5 7

Biến Toán tử

 Khai báo biến  Toán tử số: +, -, *, /


Tên_biến KDL(độ lớn)  Toán tử chuỗi: +, -, ||
 Ví dụ:  Toán tử so sánh: =, !=, <, >, <=, >=, IS
mahd NUMBER(5); NULL, LIKE, BETWEEN, IN
flag BOOLEAN;  Toán tử logic: AND, OR, NOT
 Toán tử mũ: **

6 8

2
Các thuộc tính %TYPE, %ROWTYPE Cấu trúc lệnh IF

Cú pháp  Ví dụ:
 Thuộc tính %TYPE 
declare
– Để khai báo 1 biến có cùng KDL với 1 cột trong IF <điều kiện> THEN v_num number(2);
Các lệnh của if begin
table. v_num:=4;
– Ví dụ: s_ho sinhvien.hosv%TYPE ELSE if v_num=3 then
Các lệnh của else dbms_output.put_line('bang 3');
 Thuộc tính %ROWTYPE END IF;
else
dbms_output.put_line('khong
– Để khai báo 1 biến có cùng KDL với 1 dòng trong bang 3');
table. end if;
end;
– Ví dụ: sv_rec sinhvien%TYPE

9 11

Vòng lặp

 Ví dụ:  Vòng lặp LOOP


declare LOOP
s_ho sinhvien.hosv%TYPE; Câu lệnh trong vòng lặp;
s_ten sinhvien.tensv%TYPE; END LOOP;
begin
select hosv, tensv into s_ho, s_ten from sinhvien
 Vòng lặp thoát khi gặp lệnh EXIT hoặc EXIT
where masv='a01'; WHEN
dbms_output.put_line(s_ho || ' ' || s_ten); – IF … THEN EXIT;
end; – EXIT WHEN <điều kiện>;

10 12

3
Xử lý ngoại lệ

 Vòng lặp LOOP WHILE  Là đoạn mã xử lý khi có lỗi xảy ra.


WHILE <điều kiện>  Đoạn mã xử lý ngoại lệ phải được đặt trong
LOOP phần exception.
Lệnh trong vòng lặp;  Có 2 loại ngoại lệ:
END LOOP; – Do Oracle định nghĩa trước
 Vòng lặp thoát khi <điều kiện> sai – Do người dùng định nghĩa

13 15

 Vòng lặp LOOP FOR  Các ngoại lệ do Oracle định nghĩa


– NO_DATA_FOUND: Câu lệnh SELECT INTO không trả về
FOR biến IN [REVERSE] gtdau .. gtcuoi dòng nào.
LOOP – CURSOR_ALREADY_OPEN: Mở một cursor mà cursor đó
đã ở trạng thái mở.
statements
– DUP_VAL_ON_INDEX: Khi có thao tác INSERT hoặc
END LOOP; UPDATE vi phạm ràng buộc UNIQUE.
– INVALID_CURSOR: Mở 1 cursor chưa tạo hoặc đóng 1
cursor mà chưa được mở.
– TOO_MANY_ROWS: Câu lệnh SELECT INTO trả về nhiều
hơn 1 dòng.

14 16

4
 Ví dụ:  Ngoại lệ do người dùng định nghĩa
 Ví dụ:
begin declare
loi exception;
insert into khoa values('kt','kinh te'); s_ho sinhvien.hosv%TYPE;
s_ten sinhvien.tensv%TYPE;
exception begin
when DUP_VAL_ON_INDEX then select hosv, tensv into s_ho,s_ten from sinhvien where masv='a01';
if s_ten != 'Mai' then
dbms_output.put_line('Trung khoa chinh'); raise loi;
end if;
when OTHERS then exception
dbms_output.put_line('Loi'); when loi then dbms_output.put_line('Khong co du lieu');
end;
end;

17 19

Con trỏ (Cursor)

 Để xử lý tất cả các lỗi khác mà nó không  Cursor là kiểu biến có cấu trúc hay là một đối
được định nghĩa trong khối exception, ngoại tượng liên kết với một tập dữ liệu  cho
lệ “OTHERS” có thể được sử dụng. phép ta xử lý dữ liệu gồm nhiều dòng. Số
dòng phụ thuộc vào câu lệnh SQL sau đó.

18 20

5
 Khai báo cursor  Ví dụ:
declare
CURSOR <tên> IS câu lệnh select; s_ho sinhvien.hosv%TYPE;
s_ten sinhvien.tensv%TYPE;
cursor sv is select hosv,tensv from sinhvien;
begin
 Chú ý: open sv;
loop
– Lệnh khai báo trên phải được đặt trong khối fetch sv into s_ho, s_ten;
declare. exit when sv%NOTFOUND;
dbms_output.put_line(s_ho || ' ' ||s_ten);
– Khi khai báo cursor là cursor chưa được mở. end loop;
end;

21 23

 Một số thao tác trên cursor: Open, Fetch,  Các thuộc tính của con trỏ
Close – %NOTFOUND: Là TRUE khi fetch đến dòng cuối
– Open <tên cursor>: Mở cursor. cùng, ngược lại là FALSE.
– Close <tên cursor>: Đóng cursor.
– %FOUND: Là TRUE khi fetch cuối cùng thành
– Fetch <tên cursor> INTO biến 1,…; hoặc
công, ngược lại FALSE.
Fetch <tên cursor> INTO biến mẫu tin;
Lệnh Fetch được dùng truy lục 1 dòng trong tập – %ROWCOUNT: Trả về số dòng đã được fetch.
dữ liệu của cursor. Lệnh fetch có thể được dùng – %ISOPEN: Là TRUE nếu cursor ở trạng thái mở,
chung với LOOP để quyết tất cả các dòng dữ FALSE nếu cursor ở trạng thái đóng.
liệu.

22 24

6
Thủ tục (procedure)

 Cú pháp tạo thủ tục  Gọi thủ tục


CREATE [OR REPLACE] PROCEDURE tên_tt Tên_thủ_tục(đối số 1,…);
[(tham số 1,…)] IS
 Xóa thủ tục
Khai báo
BEGIN
DROP PROCEDURE tên_thủ_tục;
Lệnh của thủ tục;
[EXCEPTION ngoại lệ]
END;

25 27

 OR REPLACE: Tự động xóa procedure và  Ví dụ:


tạo mới nếu nó đã tồn tại. CREATE OR REPLACE PROCEDURE hello
 Tham số 1: có dạng như sau: IS
Tên_tham_số [IN | OUT | IN OUT] KDL BEGIN
dbms_output.put_line('hello');
 Chú ý: KDL của tham số KHÔNG được quy
END;
định độ lớn.
 Gọi thủ tục:
hello();

26 28

7
CREATE OR REPLACE PROCEDURE update_diem
(ma IN ketqua.masv%TYPE, mon IN ketqua.mamh%TYPE,
diemmoi IN ketqua.diem%TYPE)
IS kq NUMBER(2);
BEGIN
Hàm
SELECT COUNT(*) INTO kq FROM ketqua
WHERE masv=ma AND mamh=mon;  Hàm tương tự thủ tục nhưng có kết quả trả về
IF kq = 1 THEN  Cú pháp tạo hàm:
UPDATE ketqua CREATE [OR REPLACE] FUNCTION tên_hàm(tham số 1,…)
SET diem = diemmoi RETURN KDL_trả_về
WHERE masv=ma AND mamh=mon; IS khai báo
COMMIT; BEGIN
END IF; Lệnh trong hàm;
EXCEPTION RETURN kết_quả_trả_về;
WHEN OTHERS THEN ROLLBACK; [EXCEPTION ngoại lệ]
END;
END;
29
31

• Gọi thủ tục


Update_diem(‘a01’,’01’,7);  Gọi hàm
Tên_hàm(đối số 1,…);
– Chú ý: Khi gọi hàm cần phải lấy kết quả trả về.

 Xóa hàm
DROP FUNCTION tên_hàm;

30
32

8
 Ví dụ:  Ví dụ:
CREATE OR REPLACE FUNCTION cong
(so1 NUMBER,so2 NUMBER) CREATE OR REPLACE PROCEDURE tong(so1 IN
RETURN NUMBER NUMBER,so2 IN NUMBER,kq OUT NUMBER)
IS kq NUMBER(3);
IS
BEGIN
kq:=so1 + so2; BEGIN
RETURN kq; kq:=so1 + so2;
END;
 Gọi hàm: END;
dbms_output.put_line(cong(3,5));

33 35

 Tham số của hàm và thủ tục  Gọi hàm:


– IN: Là tham số (biến) mà giá trị sẽ được truyền từ DECLARE
bên ngoài vào khi gọi hàm/thủ tục.
x NUMBER(3);
– OUT: Là tham số trả về giá trị khi hàm/thủ tục
thực hiện xong. Đối số truyền vào cho tham số BEGIN
này khi gọi hàm/thủ tục phải là 1 biến. tong(3,5,x);
– IN OUT: Là tham số vừa truyền giá trị vào vừa trả dbms_output.put_line(x);
về giá trị.
END;

34 36

9
Trigger

 Đặc điểm của trigger  Khi trigger thực thi, Oracle tạo ra 2 dòng
– Gán vào 1 table cụ thể. :new và :old
– Được gọi tự động khi cho hành động thêm, sửa – :new: Lưu dữ liệu mới được INSERT hoặc
hoặc xóa trên table. UPDATE.
– :old: Lưu dòng dữ liệu mới bị xóa.

37 39

 Tạo trigger  Ví dụ: Tạo trigger để kiểm tra điểm phải từ 0 đến 10
CREATE [OR REPLACE] TRIGGER tên_trigger CREATE TRIGGER kt_diem
AFTER INSERT ON ketqua
BEFORE | AFTER
FOR EACH ROW
[UPDATE (OF column)] | [DELETE] | [INSERT] BEGIN
ON TABLE IF :new.diem<=0 OR :new.diem>10 THEN
[FOR EACH ROW] raise_application_error(-20101,:new.masv);
BEGIN rollback;
END IF;
Lệnh trong trigger;
END;
END;

38 40

10
 Vô hiệu hóa trigger
ALTER TRIGGER tên_trigger DISABLE;
 Hiệu lực hóa trigger
ALTER TRIGGER tên_trigger ENABLE;
 Disable/enable tất cả các trigger liên quan đến 1
table:
ALTER TABLE tên_bảng
DISABLE | ENABLE ALL TRIGGERS
 Xóa trigger
DROP TRIGGER tên_trigger

41

Bài tập

 Tạo trigger không cho xóa những dòng kết


quả có điểm hợp lệ (từ 0 đến 10).
 Tạo trigger kiểm tra việc trùng khóa chính khi
thêm 1 dòng mới vào bảng khoa.

42

11

You might also like