Tên biến không được trùng với tên cột của bảng dữ liệu sử dụng trong khối.. PL/SQL không hỗ trợ trực tiếp các câu lệnh ngôn ngữ định nghĩa dữ liệu DDL như CREATE TABLE, AL
Trang 3Chương 9 Ngôn ngữ thủ tục –PL/SQL 9 - 3
- Mở rộng của SQL
- Mã PL/SQL lưu trữ trực tiếp trong csdl
- Giao tiếp với csdl
cho phép tích hợp lệnh SQL và các ngôn ngữ lập trình
sử dụng cả trong cơ sở dữ liệu và lập trình ứng dụng
dùng để kết hợp các lệnh xử lý chuyển tác
hỗ trợ nhiều thủ tục hơn SQL
đơn vị mã lệnh PL/SQL là dạng khối (Begin… End)
Giới thiệu PL/SQL
Trang 4Khai báo biến
Identifier [CONSTANT] datatype [NOT NULL]
[:=| DEFAULT expr]
Ví dụ:
V_Hiredate DATE;
V_DeptNo NUMBER(3) NOT NULL := 10;
V_Loc VARCHAR2(13) := ‘Atlanta’;
Giới thiệu PL/SQL
Trang 6DECLARE
v VARCHAR2(5);
BEGIN
SELECT EnameINTO v
Trang 8WHERE Dname = 'SALES';
Trang 9Chương 9 Ngôn ngữ thủ tục –PL/SQL 9 - 9
Thuộc tính %Type
- %Type sử dụng khi lưu trữ giá trị nhận được từ một bảng
- đặt %Type ngay sau tên bảng và tên cột
Trang 10Chương 9 Ngôn ngữ thủ tục –PL/SQL 9 - 10
- Một số chú ý
PL/SQL không hỗ trợ các kiểu dữ liệu mảng
Biến phải được khái báo trước khi tham chiếu đến
Kiểu dữ liệu trong phần khai báo có thể có hoặc
không
Trong một khối lệnh các biến không được trùng tên
Tên biến không được trùng với tên cột của bảng dữ liệu sử dụng trong khối
Khởi tạo biến phải chỉ rõ như NOT NULL, CONSTANT
Khai báo mỗi biến trên 1 hàng
Khởi tạo giá trị cho biến bằng cách sử dụng phép
gán (:=) hoặc từ khóa DEFAULT
Giới thiệu PL/SQL
Trang 11TIMESTAMP WITH LOCAL TIME ZONE
INTERVAL YEAR TO MONTHINTERVAL DAY TO SECOND
Trang 12Khối lồng nhau và phạm vi biến
Giới thiệu PL/SQL
Trang 13 Dùng dấu ngoặc đơn để điều khiển thứ tự ưu tiên.
Ví dụ: Tăng biến đếm cho vòng lặp
v_count := v_count + 1;
Giới thiệu PL/SQL
Trang 14- Câu lệnh SQL trong PL/SQL
Một số điểm cần lưu ý
Cần phần biệt từ khóa END của khối lệnh và END của câu lệnh điều khiển chuyển tác
PL/SQL không hỗ trợ trực tiếp các câu lệnh ngôn ngữ định nghĩa dữ liệu (DDL) như CREATE TABLE,
ALTER TABLE, DROP TABLE
PL/SQL không hỗ trợ các câu lệnh ngôn ngữ điều
khiển dữ liệu (DCL) như GRANT, REVOKE
Giới thiệu PL/SQL
Trang 16- Câu lệnh SELECT trong PL/SQL
Ví dụ: Lấy dữ liệu cột DeptId và cột Loc của phòng
SALES trong bảng Dept
WHERE Dname=‘Sales’;
…END;
Giới thiệu PL/SQL
Trang 17INSERT INTO Emp
(Empid, Fname, Email, Hireday, Jobid, Salary)
VALUES (emp_seq.NEXTVAL, ‘Ruth’,
‘Roes@dsc.com’, sysdate, ‘SALES’, 4000);
END;
Giới thiệu PL/SQL
Trang 18- Cập nhật dữ liệu
Ví dụ: Tăng lương thêm $100 cho những nhân
viên có mã công việc là ST_CLERKS
Trang 20- Câu lệnh kết hợp
Ví dụ: Chèn hoặc cập nhật dữ liệu trong bảng
copy_emp phù hợp với bảng emp
UPDATE SET c.Emp_id=e.Emp_id, c.Ename=e.Ename
c.Job_id=e.Job_id, c.salary=e.salary WHEN NOT MATCHED THEN
INSERT VALUES(e.Empid, e.fname, e.Hireday, e.Jobid, e.salary, e.manageid);
END;
Giới thiệu PL/SQL
Trang 21Chương 9 Ngôn ngữ thủ tục –PL/SQL 9 - 21
- Cấu trúc điều khiển (Tương tự C++)
Ví dụ: Gán một trong các chuỗi ‘Excellent’, ‘Very good’,
‘Good’ và ‘No such grade’ cho biến v_app dựa vào biến v_grade
DECLARE v_grade CHAR(1):=UPPER(&grade);
v_app VARCHAR2(20);
BEGIN v_app:= CASE v_grade
WHEN ‘A’ THEN ‘Excellent’
WHEN ‘B’ THEN ‘Very good’
WHEN ‘C’ THEN ‘Good’
ELSE ‘No such grade’
END;
END;
Giới thiệu PL/SQL
Trang 25END LOOP;
END;
Giới thiệu PL/SQL
Trang 26- Kiểu dữ liệu hợp
Kiểu dữ liệu Table
Kiểu dữ liệu Record
Thuộc tính %ROWTYPE
Giới thiệu PL/SQL
Trang 27Chương 9 Ngôn ngữ thủ tục –PL/SQL 9 - 27
- Kiểu dữ liệu Table
TYPE typename IS TABLE OF
Trang 28- Kiểu dữ liệu Table
Ví dụ Khai báo kiểu dữ liệu TABLE có tên t_name và t_date, sau đó khai báo hai biến v_name và v_date DECLARE
TYPE t_name IS TABLE OF
Emp.Fname%TYPE INDEX BY BINARY_INTEGER;
Trang 29Chương 9 Ngôn ngữ thủ tục –PL/SQL 9 - 29
- Kiểu dữ liệu Table
Ví dụ Khai báo kiểu dữ liệu TABLE có tên t_name và t_date, sau đó khai báo hai biến v_name và v_date DECLARE
TYPE t_date IS TABLE OF DATE (Number)
Trang 30Chương 9 Ngôn ngữ thủ tục –PL/SQL 9 - 30
- Kiểu dữ liệu Record
TYPE type_name IS RECORD
(field1 field_type| variable%Type
| table.column%Type| table
%RowType
[NOT NULL{:=|DEFAULT} exrp],
… (fieldn field_type| variable%Type
Trang 31Chương 9 Ngôn ngữ thủ tục –PL/SQL 9 - 31
- Kiểu dữ liệu Record
Ví dụ: Khai báo kiểu dữ liệu RECORD tên t_emp và khai báo biến v_emp kiểu t_emp
TYPE t_Emp IS
RECORD (empno number(4) not null,
ename char(10), job char(9),
deptno number(2) not null);
v_Emp t_Emp;
Giới thiệu PL/SQL
Trang 32- Thuộc tính %ROWTYPE
Khai báo kiểu dữ liệu RECORD dựa trên một tập hợp các cột của các bảng hay khung
Trang 33Chương 9 Ngôn ngữ thủ tục –PL/SQL 9 - 33
- Tổng quan về con trỏ (Cursor)
- Nâng cao về con trỏ
Con trỏ
Trang 34Con trỏ tường minh
Lệnh select được đặt tên
Thực hiện các thao tác xử lý dữ liệu quan
trọng
Con trỏ ngầm
địa chỉ không đặt tên của một lệnh SQL được xử lý
bởi Oracle và cơ chế thực thi PL/SQL
Tổng quan về con trỏ
Khai báo -> mở con trỏ -> xử lý -> đóng con trỏ
Trang 35Chương 9 Ngôn ngữ thủ tục –PL/SQL 9 - 35
- Khai báo con trỏ
CURSOR cursorname[variable_list]
IS select_statement;
Ví dụ: Khai báo biến con trỏ lưu trữ dữ liệu cột
DeptId và Dname trong bảng Dept
DECLARECURSOR c_Dept IS SELECT DeptId, Dname
FROM dept BEGIN
…
Tổng quan về con trỏ
Trang 36Lệnh OPEN thực hiện các tháo tác sau:
1 Cấp vùng nhớ động để chứa thông tin
2 Phân tích câu lệnh select
3 Chấp nhận các biến đầu vào
4 Kích hoạt con trỏ
5 Định vị con trỏ ngay dòng đầu tiên
Tổng quan về con trỏ
Trang 37Chương 9 Ngôn ngữ thủ tục –PL/SQL 9 - 37
- Lấy dữ liệu
FETCH CursorName INTO variable_list;
Ví dụ: Đọc con trỏ c_dept và đưa dữ liệu vào biến
v_dept
FETCH c_Dept INTO v_Dept;
Quá trình thực hiện lệnh FETCH như sau:
1 Đọc dòng hiện tại và đưa dữ liệu vào các biến
PL/SQL
2 Dịch chuyển con trỏ đến dòng tiếp theo
Tổng quan về con trỏ
Trang 38- Đóng con trỏ
CLOSE cursorName;
Ví dụ: CLOSE c_Dept;
- Một số thuộc tính của con trỏ
%isopen trả về giá trị True nếu con trỏ đang mở
%notfound lệnh fetch hiện thời không trả về
hàng nào
%found lệnh fetch hiện thời trả về một hàng
%rowcount số hàng đã được thực hiện bằng
lệnh fetch
Tổng quan về con trỏ
Trang 39EXIT WHEN c_Emp%notfound;
INSERT INTO Emp_ext(EmpNo, Ename, Job) VALUES(v_Emp.empid, v_Emp.fname,
Trang 40Ví dụ: Dùng biến con trỏ in DS NV thuộc phòng 10.
EXIT WHEN c_Emp%notfound;
DBMS_OUTPUT.OUTLINE(v_Emp.EmpId || “,” ||v_emp.Fname ||”,”||v_emp.Job);
END LOOP;
CLOSE c_Emp;
END;
Tổng quan về con trỏ
Trang 41Chương 9 Ngôn ngữ thủ tục –PL/SQL 9 - 41
- Con trỏ với tham số
mềm dẻo hơn,
mở và đóng con trỏ nhiều lần trong một khối lệnh,
trả về một tập giá trị khác nhau tại mỗi thời điểm
CURSOR cursor_name [(parameter_name datatype,…)]
IS select_statement;
OPEN cursor_name (parameter_value,…);
Nâng cao về con trỏ
Trang 429 - 42
Ví dụ: Khai báo con trỏ emp_cursor hai tham số
p_deptno và p_job
DECLARE
CURSOR emp_cursor(p_deptno Number, p_job
Varchar2) IS
SELECT Empid, fname FROM emp
WHERE Deptid = p_deptno AND Jobid=p_job;
BEGIN
OPEN emp_cursor (80, ‘SA_REP’);
…CLOSE emp_cursor;
OPEN emp_cursor (60, ‘IT_PROG’);
…END;
Nâng cao về con trỏ
Trang 43NOWAIT Trả về lỗi nếu các dòng bị khóa bởi phiên
làm việc khác
Nâng cao về con trỏ
Trang 44Nâng cao về con trỏ
Trang 45Chương 9 Ngôn ngữ thủ tục –PL/SQL 9 - 45
- Mệnh đề WHERE CURRENT OF
cho phép cập nhật hay xóa dòng hiện tại mà
không cần đến thuộc tính ROWID
WHERE CURRENT OF cursor;
Ví dụ: Tăng 10% lương cho những người thuộc bộ phận
có mã số 60 và mức lương thấp hơn 5000
Nâng cao về con trỏ
Trang 46SET Salary = emp_record.Salary * 1.1 WHERE CURRENT OF sal_cursor;
Trang 47Chương 9 Ngôn ngữ thủ tục –PL/SQL 9 - 47
- Con trỏ với truy vấn con
chứa câu lệnh truy vấn con trong câu lệnh truy vấn của con trỏ
AND t2.staf >= 3;
Nâng cao về con trỏ
Trang 48Xử lý ngoại lệ (Exception - bẩy lỗi)
một định danh xuất hiện khi có lỗi xảy ra hoặc do ta
khai báo
định nghĩa trước (predefined exception),
người dùng định nghĩa (user-defined
exception)
tiền xử lý (pragma exception)
Nâng cao về con trỏ
Trang 50- Bẫy ngoại lệ
Ví dụ: Lấy dữ liệu cột fname trong bảng Emp đưa vào biến v_name Nếu có lỗi xuất hiện thì xuất dòng thông báo lỗi ra màn hình
Trang 51Chương 9 Ngôn ngữ thủ tục –PL/SQL 9 - 51
- Một số nguyên tắc bẫy ngoại lệ
Từ khóa Exception bắt đầu phần bẫy và xử lý
Mệnh đề WHEN OTHERS nằm cuối cùng
Nâng cao về con trỏ
Trang 52- Một số ngoại lệ thường gặp
NO_DATA_FOUND Không có dữ liệu
TOO_MANY_ROWS Quá nhiều dòng
INVALID_CURSOR Con trỏ không hợp lệ
Trang 54- Hàm bẫy ngoại lệ
SQLCODE: Trả về giá trị số là mã lỗi
SQLERRM: Trả về thông báo kết hợp với mã lỗi
Nâng cao về con trỏ
Trang 56Ngoại lệ do người dùng định nghĩa
Nâng cao về con trỏ
Trang 58- Ngoại lệ tiền xử lý
mã hoá một số ngoại lệ kết hợp với lỗi.
xử lý các lỗi chưa được xử lý rõ ràng
Sử dụng từ khóa PRAGMA để khai báo.
Nâng cao về con trỏ
Trang 59END;
Nâng cao về con trỏ
Trang 60- Tổng quan về chương trình con
Trang 61Chương 9 Ngôn ngữ thủ tục –PL/SQL 9 - 61
Một nhóm các lệnh thực hiện một chức năng nào đó
Nâng cao hiệu suất
Nâng cao khả năng bảo trì
Tăng tính bảo mật và toàn vẹn của dữ liệu
Chương trình con
Trang 62 được lưu giữ ngay trong cơ sở dữ liệu như một đối tượng csdl (Store procedure)
được biên dịch thành dạng p-code khi lưu giữ
Trang 63IS | AS BEGIN
PL/SQL Block;
END Proc_name;
Thủ tục
Trang 64Chương 9 Ngôn ngữ thủ tục –PL/SQL 9 - 64
CREATE OR REPLACE PROCEDURE change_sal
(p_Percentage IN number, p_Error OUT varchar2)
Trang 71Chương 9 Ngôn ngữ thủ tục –PL/SQL 9 - 71
- Lợi ích của việc sử dụng hàm
thực hiện các thao tác phức tạp ngay trong mệnh
đề của câu lệnh SQL
phân tích và xử lý dữ liệu được thực hiện ngay trên Server
gọi các hàm ngay trong câu lệnh SQL
có thể sử dụng hàm để thao tác trên các kiểu dữ liệu tự tạo
cho phép thực hiện đồng thời các câu lệnh truy
vấn
Hàm
Trang 72- Hạn chế khi sử dụng hàm
Phải định nghĩa hàm trước khi sử dụng
Chỉ được áp dụng cho điều kiện WHERE, không thể áp dụng cho điều kiện HAVING
Tham số sử dụng trong hàm chỉ có thể là loại IN, không chấp nhận giá trị OUT hay giá trị IN OUT
Kiểu dữ liệu trả về của các hàm phải là kiểu dữ
liệu DATE, NUMBER, NUMBER
Không cho phép hàm trả về kiểu dữ liệu như
BOOLEAN, RECORD, TABLE Kiểu dữ liệu trả về này phải tương thích với các kiểu dữ liệu bên trong
Oracle Server
Hàm
Trang 73Chương 9 Ngôn ngữ thủ tục –PL/SQL 9 - 73
- Tập các kiểu dữ liệu, biến, thủ tục và các hàm
có cùng một mối liên hệ với nhau, được gộp
chung lại.
Tăng tính phân nhỏ các thành phần (Modularity)
Đơn giản trong việc thiết kế ứng dụng
Ẩn dấu thông tin (hiding information)
Nâng cao hiệu suất sử dụng
Thực hiện chồng (overloading)
(Xem giáo trình)
9.3.5 Phát triển gói (Package)
Trang 74- Trigger là những thủ tục được thực hiện ngầm định ngay khi thực hiện lệnh SQL
đảm bảo thực hiện tất cả các thao tác có liên quan tới lệnh can thiệp dữ liệu được thực hiện
sử dụng trigger đối với các thao tác trọng tâm
không sử dụng trigger để thực hiện các ràng buộc sẵn có trong cơ sở dữ liệu Oracle
9.3.6 Phát triển Triggers
Trang 75Chương 9 Ngôn ngữ thủ tục –PL/SQL 9 - 75
- Tạo TRIGGER
Khi tạo trigger, cần lưu ý tới một số tiêu chí
sau:
Thời gian thực hiện: BEFORE, AFTER
Hành động thực hiện: INSERT, UPDATE, DELETE
Đối tượng tác động: bảng dữ liệu
Loại trigger thực hiện: trên dòng lệnh hay trên câu lệnh
Mệnh đề điều kiện thực hiện
Nội dung của trigger
9.3.6 Phát triển Triggers
Trang 76- Phân loại trigger
+ Phân loại theo thời gian
BEFORE trigger: được kích hoạt trước khi thực hiện câu lệnh(INSERT hoặc UPDATE)
AFTER trigger: được kích hoạt sau khi lệnh được
thực hiện xong
INSTEAD OF trigger: cho phép người sử dụng có
thể thay đổi một cách trong suốt dữ liệu của một số khung nhìn mà không thể thực hiện thay đổi trực
tiếp được
9.3.6 Phát triển Triggers
Trang 77Chương 9 Ngôn ngữ thủ tục –PL/SQL 9 - 77
- Phân loại trigger
+ Phân loại theo câu lệnh kích hoạt (INSERT,
UPDATE, DELETE)
+ phân loại theo số lần kích hoạt
Mức lệnh: được kích hoạt mỗi khi thực hiện câu
lệnh
Mức dòng dữ liệu: được kích nhiều lần ứng với mỗi dòng dữ liệu chịu ảnh hưởng bởi thao tác thực hiện lênh
9.3.6 Phát triển Triggers
Trang 78- Tạo trigger mức câu lệnh
CREATE [OR REPLACE] TRIGGER name timing event1 [OR event2 OR event3]
ON table Trigger_body
9.3.6 Phát triển Triggers
Trang 79Chương 9 Ngôn ngữ thủ tục –PL/SQL 9 - 79
- Tạo trigger mức câu lệnh
Ví dụ: Tạo trigger để giới hạn dữ liệu chèn vào bảng
Emp
CREATE OR REPLACE TRIGER secure_emp
BEFORE INSERT ON Emp BEGIN
IF TO_CHAR(sysdate,’DAY’) IN (‘SAT’,’SUN’) OR TO_CHAR(sysdate,’HH24’) NOT BETWEEN
‘08’
AND ’18’ THEN RAISE_APPLICATION_ERROR (-20500,
END IF;
END;
9.3.6 Phát triển Triggers