Bài giảng Cơ sở dữ liệu nâng cao: Chương 4 Lập trình PL/SQL cung cấp cho người học những kiến thức như: Cấu trúc chương trình PL/SQL; Các kiểu dữ liệu cơ bản của PL/SQL; Các kiểu dữ liệu tham chiếu; Các loại mệnh đề; Cấu trúc điều khiển; Kiểu con trỏ. Mời các bạn cùng tham khảo!
Trang 1Bài giảng
CƠ SỞ DỮ LIỆU
NÂNG CAO
Số tc: 2; LT: 20; Btập: 10 GV: Nguyễn Thị Mỹ Dung Khối lớp: Đại học L2
Trang 2NỘI DUNG MÔN HỌC
Trang 3Chương 4: Lập trình PL/SQL
II Các kiểu dữ liệu cơ bản của PL/SQL
III Các kiểu dữ liệu tham chiếu
IV Các loại mệnh đề
VI Kiểu con trỏ
VII Bài tập thực hành
Trang 4I Cấu trúc chương trình PL/SQL
1 Giới thiệu
Language) là một ngôn ngữ lập trình lập trình hướng
thủ tục sử dụng cho Oracle SQL
hằng số, biến, cấu trúc điều khiển, thủ tục, hàm, bẫy lỗi sự kiện, thao tác con trỏ, và xử lý giao tác…
Mọi thứ được lưu trữ trong DB được tái sử dụng bởi các ứng dụng bất kỳ giao tiếp với ứng dụng Oracle
Từ phiên bản 8 trở về sau có thêm các tính năng hướng đối tượng
Trang 5Cấu trúc PL/SQL – giới thiệu(tt)
- Mỗi lệnh SQL kết thúc bằng dấu chấm phẩy (;)
- PL/SQL tổ chức theo từng khối lệnh (block), mỗi khối lệnh có thể lồng nhau Các biến có thể khai báo nội (local) bên trong khối và điều khiển báo lỗi bên trong khối nơi lỗi phát sinh
- Một block bao gồm ba phần: phần khai báo là nơi để khai báo biến, phần thi hành lệnh và phần xử
lý các ngoại lệ (điều kiện lỗi hoặc cảnh báo)
- Khai báo biến trong PROCEDURE hay
FUNCTION: nếu là Block ngoài cùng (đầu tiên) của
PROCEDURE, FUNCTION thì không dùng từ khóa DECLARE (Ngược lại với TRIGGER, Block ngoài
cùng (đầu tiên) phải có DECLARE)
Trang 6DECLARE /*Phần Khai báo biến Block 2*/
Các xử lý ngoại lệ (Exception Handlers)
Trang 8II Kiểu dữ liệu trong PL/SQL
1 Các kiểu dữ liệu cơ bản như sau:
Trang 9Các kiểu dữ liệu cơ bản (tt)
- DATE: thế kỷ, năm, tháng, ngày, giờ, phút, giây
- CHAR (max_length): kiểu ký tự
- VARCHAR2 (max_length): max_length<=32767
- LONG: <=32760 bytes
Trang 10Ghi chú: Ký hiệu := được sử dụng như là toán tử gán
Trang 12Kiểu dữ liệu (tt)
3 Nhập xuất dữ liệu
- Lệnh xuất:
DBMS_OUTPUT.PUT_LINE ('Nội dung');
Lưu ý: trước khi thực hiện lệnh xuất ta phải chạy lệnh SET SERVEROUTPUT ON
- Lệnh nhập: 2 cách để nhập giá trị cho biến
Biến thay thế &: dấu & đặt trước biến Biến
được nhập giá trị lúc thực thi
Biến thay thế &&: dấu && đặt trước biến Giá trị
nhập vào được lưu trữ cho những lần sau
Lưu ý:
Biến kiểu chuỗi, kiểu ngày đặt trong cặp dấu ' '
VD: a char(5):= '&a';
Trang 13Kiểu dữ liệu – Nhập xuất (tt)
Ví dụ:
SET SERVEROUTPUT ON;
DECLARE
x number; BEGIN
Trang 14III Kiểu dữ liệu tham chiếu
Dùng để khai báo một biến mà nó tham chiếu đến một cột trong CSDL
Khai báo:
<TÊNBIẾN>
<TÊNTRƯỜNG | TÊNBIẾNKHÁC> % TYPE
SET SERVEROUTPUT ON;
Trang 15Kiểu dữ liệu tham chiếu (tt)
Dùng để khai báo một biến mà nó tham chiếu đến
một dòng trong cơ sở dữ liệu (Có cấu trúc như một dòng trong Table)
Khai báo: <TÊNBIẾN>
SELECT * INTO row_detai
FROM detai WHERE MADT= 'DT001';
DBMS_OUTPUT.PUT_LINE (row_detai.MADT || ' : ' ||
row_detai.TENDT );
END;
Trang 16Kiểu dữ liệu tham chiếu (tt)
Dùng để khai báo một biến mà nó tham chiếu đến
một bảng trong CSDL (Có cấu trúc như một Table)
Khai báo:
TYPE <TÊNBẢNG> IS TABLE OF <KIỂU> [ NOT NULL ]
<TÊNBIẾN><TÊNBẢNG>;
Trang 17Kiểu dữ liệu tham chiếu - table(tt)
END;
Trang 18SELECT MASV, HOTENSV INTO vMASV, vHOTENSV
FROM SINHVIEN WHERE MASV= ' SV002 ' ;
DBMS_OUTPUT.PUT_LINE (vMASV|| ' : ' || vHOTENSV);
END;
Trang 19TENKH := 'Su pham Toan - Tin';
INSERT INTO KHOA (MAKH, TENKH)
VALUES (MAKH, TENKH);
EXCEPTION WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE (SQLERRM);
END;
Trang 20V Các cấu trúc điều khiển
Trang 22IF n=1 THEN ngay := 'Sunday';
ELSIF n=2 THEN ngay :='Monday';
ELSIF n=3 THEN ngay :='Tuesday';
ELSIF n=4 THEN ngay :='Wedsday';
ELSIF n=5 THEN ngay :='Thursday';
ELSIF n=6 THEN ngay :=‘Friday';
ELSIF n=7 THEN ngay :=‘Saturday';
END IF ;
DBMS_OUTPUT.PUT_LINE (ngay);
END ;
Trang 23Các cấu trúc điều khiển (tt)
Trang 24Cấu trúc điều khiển - Loop(tt)
End IF ; END LOOP ;
Trang 25Cấu trúc điều khiển (tt)
3 Lệnh lặp FOR…LOOP
Cú pháp:
FOR <biến-chạy>
IN giá-trị-khởi-tạo giá-trị-kết-thúc LOOP
<khối lệnh>
END LOOP;
Trang 26Cấu trúc điều khiển - For (tt)
END ;
Trang 27Cấu trúc điều khiển – For (tt)
Trang 28Cấu trúc điều khiển – While (tt)
END ;
Trang 29Cấu trúc điều khiển (tt)
- GOTO không được phép trong một số trường hợp:
Từ một xử lý ngoại lệ vào trong khối hiện hành
Nhảy ra ngoài chương trình con
Trang 30Cấu trúc điều khiển – Goto (tt)
End ; /*End của <<inner_block>>*/
End ; /*End của <<outer_block>>*/
END ;
Trang 31Cấu trúc điều khiển (tt)
VD: Nếu chia một số cho zero, một ngoại lệ do Oracle định nghĩa trước (ví dụ: ZERO_DIVIDE) sẽ tự động sinh ra
Trang 32Cấu trúc điều khiển – Exception (tt)
IF <điều kiện lỗi> then
RAISE loi_ngoai_le; /*bật ngoại lệ*/
Trang 33Cấu trúc điều khiển – Exception (tt)
Ví dụ: (ta quy định trả về 1 nếu trùng mã số, trả về 2: bình thường)
Create Function Test_Exception (maso number) return number As
trung_ma_so EXCEPTION; /*khai báo 1 ngoại lệ tên “trung_ma_so”*/
WHEN trung_ma_so then
return 1; /*đã có mã số này rồi*/
WHEN OTHERS then
/*sử dụng từ khóa OTHERS cho các lỗi khác past_due, việc sử dụng OTHERS
đảm bảo không có ngoại lệ nào sẽ không được xử lý*/
return 0; /*lỗi phát sinh*/ END ;
Trang 34Cấu trúc điều khiển – Exception (tt)
Các lỗi ngoại lệ do Oracle định nghĩa
Ngoại lệ Điều kiện khi ngoại lệ xảy ra
CURSOR_ALREADY_OPEN Mở một cursor, mà cursor đó đã ở trạng thái đang
LOGIN_DENIED Đăng nhập sai username/password
NO_DATA_FOUND Câu lệnh SELECT INTO không trả về dòng nào NOT_LOGGED_ON Một chương trình PL/SQL cần thao tác đến CSDL
Oracle nhưng lại chưa đăng nhập vào CSDL
PROGRAM_ERROR Một số lỗi chương trình, ví dụ một hàm (function)
không chứa mệnh đề RETURN trả về giá trị
Trang 35Cấu trúc điều khiển – Exception (tt)
Các lỗi ngoại lệ do Oracle định nghĩa (tt)
Ngoại lệ Điều kiện khi ngoại lệ xảy ra
TIMEOUT_ON_RESOURCE Lỗi timeout xảy ra khi Oracle đang chờ tài nguyên TOO_MANY_ROWS Câu lệnh SELECT INTO trả về nhiều hơn một
dòng VALUE_ERROR Lỗi chuyển kiểu dữ liệu hoặc thao tác vi phạm
ràng buộc toàn vẹn (RBTV) ZERO_DIVIDE Lỗi chia một số cho zero
Trang 36Cấu trúc điều khiển – Exception (tt)
Ví dụ ngoại lệ ZERO_DIVIDE do Oracle định nghĩa:
Create Function Test_Exception (so number)
WHEN ZERO_DIVIDE then
/*lỗi do Oracle định nghĩa*/
return 0; /*Lỗi chia zero*/
Trang 37Cấu trúc điều khiển – Exception (tt)
Ví dụ ngoại lệ NO_DATA_FOUND do Oracle định nghĩa: DECLARE
Masv_t Char(5);
BEGIN
Masv_t := 'A2345';
select * into Sinhvien_Row
from SINHVIEN where masv = masv_t;
DBMS_OUTPUT.PUT_LINE (Sinhvien_Row.HotenSV);
EXCEPTION
WHEN NO_DATA_FOUND then
DBMS_OUTPUT.PUT_LINE ('khong co sv nay');
END ;
Trang 38VI Kiểu con trỏ
1 Giới thiệu
Con trỏ (cursor) là một đối tượng liên kết với một tập dữ liệu và cho phép người lập trình làm việc với từng dòng của tập dữ liệu đó
Cho phép xử lý dữ liệu gồm nhiều dòng Số dòng được lấy ra xử lý phụ thuộc vào lệnh xử lý sau đó
Trong xử lý, các thao tác sẽ tác động lên từng mẩu tin của dữ liệu đã được nạp vào con trỏ
Có hai loại con trỏ: con trỏ đuợc khai báo tường minh (explicit cursor) và con trỏ không được khai báo tường minh (hay còn gọi là con trỏ tiềm ẩn
(implicit cursor))
Trang 39Con trỏ (tt)
Con trỏ tiềm ẩn: một lệnh SQL được xử lý bởi Oracle và không được đặt tên bởi người sử dụng
Các lệnh SQL được thực hiện trong một con trỏ tiềm ẩn
bao gồm UPDATE, INSERT, DELETE
Con trỏ tường minh: Là con trỏ được đặt tên bởi người
sử dụng (câu SELECT được đặt tên)
Ví dụ:
CURSOR c_kh IS
SELECT MAKH, TENKH FROM KHOA
Trang 40Con trỏ (tt)
2 Khai báo cursor (khai báo con trỏ)
Các bước thực hiện trên con trỏ:
Khai báo -> mở cursor -> lấy dữ liệu để xử lý
Cú pháp:
Khai báo con trỏ
CURSOR tên_cursor IS Câu_SELECT;
Trang 41Con trỏ (tt)
3 Thuộc tính con trỏ tường minh
Mọi con trỏ khai báo tường minh đều có 4 thuộc tính: %NOTFOUND, %FOUND, %ROWCOUNT,
%ISOPEN Các thuộc tính này được thêm vào sau phần tên của con trỏ
Thuộc tính Diễn giải
về FALSE
%NOTFOUND Trả về TRUE khi đã fetch đến dòng cuối
cùng của con trỏ, ngược lại bằng FALSE
Trang 42Con trỏ (tt)
Ví dụ 1 con trỏ: in danh sách đề tài
DECLARE
CURSOR C_DETAI IS 1 Khai báo con trỏ
SELECT MADT, TENDT, CHUNHIEM, KINHPHI
FROM DETAI;
V_DETAI C_DETAI %ROWTYPE ; Khai báo biến con trỏ truy cập
DBMS_OUTPUT.PUT_LINE('MADT | TENDT | CHUNHIEM| KINHPHI');
LOOP
FETCH C_DETAI INTO V_DETAI; 3 Lấy mẩu con trỏ
EXIT WHEN C_DETAI %NOTFOUND ; Thoát khỏi vòng lặp khi ctrỏ rỗng
Trang 44Con trỏ (tt)
SELECT FOR UPDATE
Cho phép khóa các mẫu tin đang truy xuất để tiến hành xử lý
Các mẫu tin tự động bị khóa khi mở Cursor và khóa khi được COMMIT/ ROLLBACK
Cú pháp: UPDATE <têncột> [ | DELETE <tên cột>]
WHERE CURRENT OF <têncontrỏ>
Trang 45SET HOTENSV = ‘Nguyen Van An’
WHERE CURRENT OF C_SINHVIEN -
Trang 46VII Bài tập
A Viết chương trình tính tổng từ 1 n, với n nhập vào
B Viết khối PL/SQL cho phép:
1 Hiển thị họ tên cán bộ, chức vụ và hệ số, với mã số cán bộ
được nhập từ bàn phím
2 Tăng hệ số cho những cán bộ:
• Nếu có chức vụ thì tăng 0.5
• Ngược lại thì không tăng
3 Xuất thông báo khi không có cán bộ có hệ số trên 4.0
Trang 47Tóm tắt chương
- Tìm hiểu cấu trúc chương trình PL/SQL
- Các mệnh đề trong PL/SQL
- Cấu trúc điều khiển IF
- Cấu trúc vòng lặp loop, for, while
- Lập trình con trỏ PL/SQL