Bài thực hành Bảo mật hệ thống thông tin số 4: PL/SQL có nội dung trình bày về khái niệm PL/SQL, các vấn đề liên quan đến kiểu dữ liệu trong PL/SQL, hằng và biến, cấu trúc khối PL/SQL, các câu lệnh điều khiển,... Mời các bạn cùng tham khảo chi tiết nội dung tài liệu.
Trang 1Bài th c hành s 4 ự ố
PL/SQL (1)
Tóm t t n i dung: ắ ộ
Khái ni m PL/SQLệ
Các v n đ liên quan đ n ki u d li u trong PL/SQLấ ề ế ể ữ ệ
H ng và Bi nằ ế
C u trúc kh i PL/SQLấ ố
Các câu l nh đi u khi nệ ề ể
I PL/SQL là gì ?
PL/SQL (PL : Procedural Language – Ngôn ng Th t c) là m t 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. Nó cho phép các thao tácấ ề ặ ủ ữ ậ ầ
d li u và các câu l nh query SQL bao g m các đo n mã có c u trúc kh i và tính th t cữ ệ ệ ồ ạ ầ ố ủ ụ (blockstructure and procedural unit of code), làm cho PL/SQL thành m t ngôn ng x lý giaoộ ữ ử
d ch m nh m ị ạ ẽ
Trang 2II Các l nh SQL trong PL/SQL ệ
PL/SQL cung c p m t s câu l nh th t c cho vi c thao tác và ki m tra d li u, thấ ộ ố ệ ủ ụ ệ ể ữ ệ ườ ng không c n ph i dính dáng v i các l nh SQL. Dù v y, khi c n l y th ng tin t CSDLầ ả ớ ệ ậ ầ ấ ố ừ
ho c thay đ i trên CSDL thì nên dùng SQL.ặ ổ
PL/SQL h tr t t cho đa s các l nh DML và các l nh đi u khi n giao d ch trong SQL.ỗ ợ ố ố ệ ệ ề ể ị Ngoài ra, các câu l nh SELECT có th dùng đ gán các giá tr query t 1 hàng trong b ngệ ể ể ị ừ ả cho các bi n.ế
M t s đi m l u ý:ộ ố ể ư
M t kh i PL/SQL không ph i là m t đ n v giao d ch (transaction unit) – các l nhộ ố ả ộ ơ ị ị ệ COMMIT và ROLLBACK là đ c l p v i các kh i nh ng có th n m trong nó.ộ ậ ớ ố ư ể ằ
M i câu l nh SQL c n ph i k t thúc b i d u ch m ph y.ỗ ệ ầ ả ế ở ấ ấ ẩ
Câu l nh SELECT có th dùng đ gán các giá tr query t 1 hàng trong b ng cho cácệ ể ể ị ừ ả
bi n.ế
Các câu l nh SELECT mà không tr l i ệ ả ạ đúng m t hàngộ s gây ra m t l i c n ph iẽ ộ ỗ ầ ả
gi i quy t (thả ế ường là ph i dùng phả ương pháp x lý ngo i l ho c cursor).ử ạ ệ ặ
Các l nh DDL không dùng đệ ược trong PL/SQL. Ví d :ụ
T t c các l nh b t đ u b ngấ ả ệ ắ ầ ằ ALTER, CREATE, DROP, FLASHBACK
Các l nh qu n lý quy n: GRANT, REVOKEệ ả ề
Các l nh audit: AUDIT, NOAUDITệ (và còn nhi u l nh khác)ề ệ
Các l nh DML có th x lý nhi u hàng (multiple rows).ệ ể ử ề
III Ki u d li u ể ữ ệ
PL/SQL h tr r t nhi u ki u d li u đ có th khai báo các bi n và các h ng. Có thỗ ợ ấ ề ể ữ ệ ể ể ế ằ ể gán m t giá tr ban đ u cho các bi n khi khai báo bi n và có th thay đ i các giá tr c aộ ị ầ ế ế ể ổ ị ủ chúng thông qua các phát bi u gán v sau trong kh i Các h ng là các danh hi uể ề ố ằ ệ (identifier) l u gi m t giá tr c đ nh và giá tr này ph i đư ữ ộ ị ố ị ị ả ược gán cho h ng khi h ngằ ằ
được khai báo
Các ki u d li u:ể ữ ệ
Trang 3 D li u s : ữ ệ ố NUMBER
Ví d : ụ NUMBER(7,2)
Nghĩa là có 7 ký s trong đó có 2 ký s sau d u th p phân. N u ta không khai báo đố ố ấ ậ ế ộ chính xác là 2 nh câu l nh trên thì đ chính xác m c đ nh là 38 ký s ư ệ ộ ặ ị ố
D li u lu n lí: ữ ệ ậ BOOLEAN
D li u ngày tháng: ữ ệ DATE
D li u chu i:ữ ệ ỗ
Trang 4VARCHAR2 L u tr các d li u ký t có chi u dài thay đ i. Chi u dài m cư ữ ữ ệ ự ề ổ ề ặ
đ nh là 1 ký t Chi u dài t i đa là 32767. Ví d : ị ự ề ố ụ VARCHAR2(30)
CHAR PL/SQL Version 1: gi ng nh VARCHAR2 nh ng chi u dàiố ư ư ề
t i đa là 255.ố PL/SQL Version 2: chu i các ký t chi u dài c đ nh dài t i đaỗ ự ề ố ị ố
là 32767 byte. Khi so sánh hai chu i v i nhau thì các ký tỗ ớ ự
tr ng s đố ẽ ược thêm vào
Chú ý: Khi so sánh 2 chu i CHAR trong PL/SQL Version 1 thìỗ hai chu i này không đỗ ược thêm vào các ký t tr ng, ví d m tự ố ụ ộ
bi n ki u CHAR ch a ‘FRED’ thì khác v i m t bi n ki uế ể ứ ớ ộ ế ể CHAR ch a ‘FRED ’.ứ
IV Khai báo bi n và h ng ế ằ
1. Khai báo các bi nế
Các bi n PL/SQL có th đế ể ược khai báo và có th để ược gán m t giá trộ ị ban đ u trong ph n DECLARE c a kh i. Các bi n khác đầ ầ ủ ố ế ược tham kh o đ n trongả ế
ph n khai báo thì chúng ph i đầ ả ược khai báo trong m t phát bi u trở ộ ể ước đó
Cú pháp:
identifier datatype [(precision, scale)] [NOT NULL] [ := expression];
trong đó
identifier tên bi nế datatype ki u d li u c a bi nể ữ ệ ủ ế precision chi u dài c a bi n (s ký s c a ph n nguyên và ph n th pề ủ ế ố ố ủ ầ ầ ậ phân)
scale s s l (s ký s c a ph n th p phân)ố ố ẻ ố ố ủ ầ ậ
N u không gán giá tr ban đ u cho bi n thì bi n s ch a giá tr NULLế ị ầ ế ế ẽ ứ ị cho đ n khi gán giá tr m i. Ràng bu c NOT NULL không đế ị ớ ộ ược dùng trong trườ ng
h p này.ợ
Ví d : ụ
Trang 5v_count NUMBER NOT NULL := 0;
v_saraly NUMBER(7,2);
v_annsal NUMBER(9,2) := month_sal * 12;
month_sal phải tồn tại trước postcost CHAR(7);
surname VARCHAR2(25) := ‘Skywalker’;
v_message VARCHAR2(80) := ‘Data is wrong !’;
married BOOLEAN := FALSE;
today DATE := SYSDATE;
Không nên đ t tên c a bi n trùng tên v i các tên c t c a b ng đặ ủ ế ớ ộ ủ ả ượ c dùng trong kh i. N u các bi n trong các phát bi u SQL có cùng tên v i tên c t, thìố ế ế ể ớ ộ Oracle xem tên này là tên c t (mà không ph i là tên bi n).ộ ả ế
Ví d : ụ
DECLARE bonus NUMBER(8,2);
emp_id NUMBER(6) := 100;
BEGIN SELECT salary * 0.10 INTO bonus FROM employees WHERE employee_id = emp_id;
END;
2. Khai báo h ngằ
Cú pháp:
identifier CONSTANT datatype [(precision,scale)] := expression;
Ví d : ụ
pi CONSTANT NUMBER(9,5) := 3.14159;
vat CONSTANT NUMBER(4,2) := 17.5;
Chú ý: Có th dung t khóa %TYPE đ dùng cùng ki u v i c t đề ừ ể ể ớ ộ ượ c
ch đ nh trong 1 table ỉ ị Ví d : ụ bi n product_type s có cùng ki u v i c t price c aế ẽ ể ớ ộ ủ
b ng products:ả
product_price products.price%TYPE;
Trang 6V Các bi n k t h p c a SQL*Plus ế ế ợ ủ
SQL*Plus h tr bi n k t h p (bind variable). Đây là các bi n dùng đ g i các giá trỗ ợ ế ế ợ ế ể ử ị vào trong hay ra ngoài m t kh i PL/SQL.ộ ố
Cú pháp:
VARIABLE variable_name [NUMBER | CHAR | CHAR(n) | VARCHAR2 |
VARCHAR2(n) ]
Ví d : ụ
VARIABLE deptnum NUMBER;
/*Chúng có thể dùng trong các khối PL/SQL với dấu 2 chấm phía trước */
BEGIN SELECT DEPTNO INTO :deptnum FROM DEPT WHERE DNAME = ‘ACCOUNTING’;
INSERT INTO RESULTS VALUES( :deptnum);
END;
Trong ví d trên, giá tr DEPTNO đụ ị ượ ấc l y ra và gán cho bi n deptnum. Sau đó đế ược ghi vào b ng RESULTS. Sau khi ch y xong kh i PL/SQL, b n có th hi n th giá tr c aả ạ ố ạ ể ể ị ị ủ
m t bi n k t h p b ng l nh PRINT :ộ ế ế ợ ằ ệ
SQL> PRINT deptnum
DEPTNUM
-10
VI Hàm chuy n đ i ki u ể ổ ể
TO_CHAR
TO_DATE
TO_NUMBER
Trang 8Ví d : ụ
v_message VARCHAR2(80) := ‘SCOTT earns ‘
|| TO_CHAR (month_sal * 12);
VII Đ u tiên c a toán t ộ ư ủ ử
Đ u tiênầ
Cu i cùngố
**, NOT Toán t mũ, ph đ nhử ủ ị
lu n lýậ +, Đ ng nh t, d u âmồ ấ ấ
+, , || C ng, tr , n i chu iộ ừ ố ỗ
=, !=, <, >, <=, >=, IS NULL, LIKE,
VIII C u trúc kh i ấ ố
Cú pháp:
[ DECLARE
declaration_statements ]
BEGIN
executable_statements
[ EXCEPTION
exception_handling_statements ]
END;
DECLARE và EXCEPTION là ph n t ch n, có vài kh i không có 2 ph n này.ầ ự ọ ố ầ
Trang 9Ví d : ụ (ví d trong command line)ụ
SQL> DECLARE
2 x NUMBER(7,2);
3 BEGIN
4 SELECT sal INTO x FROM emp WHERE empno=&&n;
5 IF x<300 THEN
6 UPDATE emp SET sal=3000
7 WHERE empno=&&n;
8 END IF;
9 END;
10
Đóng buffer v i d u ch m (.)ớ ấ ấ
Đ ch y PL/SQL trong buffer, gõ l nh RUN ho c d u g ch chéo (/) t i d u nh c. N uể ạ ệ ặ ấ ạ ạ ấ ắ ế
kh i đố ược thi hành xong, không có m t l i không độ ỗ ược ki m soát nào thì ch m t thôngể ỉ ộ báo được xu t ra :ấ
‘PL/SQL procedure successfully completed’
N i dung c a buffer có th so n th o theo cách thông thộ ủ ể ạ ả ường hay l u xu ng file b ngư ố ằ
l nh SAVE c a SQL*Plus.ệ ủ
IX L nh r nhánh ệ ẽ
Cú pháp:
IF condition THEN actions
[ELSIF condition THEN actions]
[ELSE actions]
END IF;
trong đó ‘actions’ là m t hay nhi u câu l nh PL/SQL hay SQL, m i câu k t thúc b i d uộ ề ệ ỗ ế ở ấ
ch m ph y. Các ‘action’ này có th ch a các câu l nh IF khác l ng nhau.ấ ẩ ể ứ ệ ồ
Trang 10Ví d : ụ
IF count > 0 THEN message := 'count is positive';
IF area > 0 THEN message := 'count and area are positive';
END IF;
ELSIF count = 0 THEN message := 'count is zero';
ELSE message := 'count is negative';
END IF;
X Vòng l p ặ
Cú pháp:
LOOP statements
END LOOP;
M i l n dòng chỗ ầ ương trình g p ph i END LOOP thì quy n đi u khi nặ ả ề ề ể
tr v t i LOOP. Vòng l p không đi u khi n này s l p mãi mãi n u trong thân c aả ề ạ ặ ề ể ẽ ặ ế ủ
nó không có các l nh nh y ra kh i nó.ệ ả ỏ
M t vòng l p có th k t thúc t bên trong n u dùng câu l nh EXIT.ộ ặ ể ế ừ ế ệ EXIT cho phép đi u khi n chuy n cho câu l nh k ti p ngay sau END LOOP và k tề ể ể ệ ế ế ế thúc vòng l p ngay l p t c.ặ ậ ứ
Cú pháp :
EXIT [looplabel] [WHEN condition];
EXIT có th là m t tác v n m trong câu l nh IF ho c đ ng m t mìnhể ộ ụ ằ ệ ặ ứ ộ trong vòng l p. Khi đ ng m t mình thì m nh đ WHEN có th dùng đ k t thúc cóặ ứ ộ ệ ề ể ể ế
đi u ki nề ệ
Trang 11Ví d 1: ụ
LOOP
counter := counter + 1;
INSERT INTO numbered_rows VALUES (counter);
…
IF counter = 10 THEN
COMMIT;
EXIT;
END IF;
END LOOP;
Ví d 2 : ụ
LOOP
… EXIT WHEN total_sals = 60000;
… END LOOP;
Cách ng t vòng l p khác là r nhánh đ n m t nhãn ra ngoài vòng l p, đóắ ặ ẽ ế ộ ặ
là dùng l nh GOTO. Nh ng đây không ph i cách vi t có c u trúc.ệ ư ả ế ấ
Cú pháp :
WHILE condition LOOP
statements
END LOOP;
Đi u ki n này (condition) đề ệ ược tính toán t i đi m b t đ u c a vòng l pạ ể ắ ầ ủ ặ
và vòng l p s k t thúc n u đi u ki n này là FALSE. N u đi u ki n này FALSEặ ẽ ế ế ề ệ ế ề ệ ngay t i lúc b t đ u vào đ n vòng l p thì vòng l p không x y ra.ạ ắ ầ ế ặ ặ ả
Ví d : ụ
counter := 0;
WHILE counter < 6 LOOP counter := counter + 1;
Trang 12END LOOP;
Cú pháp:
FOR loop_variable IN [REVERSE] lower_bound upper_bound LOOP
statements END LOOP;
Ví d : ụ
FOR count2 IN 1 5 LOOP DBMS_OUTPUT.PUT_LINE(count2);
END LOOP;
Thông thường, vòng l p trong k t thúc thì không k t thúc vòng l pặ ế ế ặ ngoài (ngo i tr có l i). Dù v y, các vòng l p có th gán nhãn và có th k t thúcạ ừ ỗ ậ ặ ể ể ế vòng l p ngoài b ng l nh EXIT.ặ ằ ệ
Các nhãn trong PL/SQL được đ nh nghĩa nh sau :ị ư
<< labelname >>
Ví d : ụ
<<main>> LOOP
… LOOP
… thoát cả 2 vòng lặp EXIT main WHEN total_done=’YES’;
thoát khỏi vòng lặp trong EXIT WHEN innder_done=’YES’;
… END LOOP;
END LOOP main;
Trang 13 Ngoài ra nhãn còn dùng đ đ nh danh vòng l p khi chúng có c u trúcể ị ặ ấ
l ng nhau.ồ
Trang 14Ví d : ụ
<<block1>> DECLARE var1 NUMBER;
BEGIN
<<block2>> DECLARE var1 NUMBER := 400;
BEGIN
biến var1 của khối block1 được tăng lên 1 block1.var1 := block1.var1 + 1;
END block2;
END block1;
XI Bài t p ậ
Trong m i bài t p dỗ ậ ưới đây, b n có th t o các kh i PL/SQL trong buffer c aạ ể ạ ố ủ SQL*Plus và sau đó l u chúng xu ng file ho c t o ra file riêng b ng các trình so n th oư ố ặ ạ ằ ạ ả khác
Trong nhi u bài t p, b n s c n ph i l u tr các k t qu trong b ng, gi thi t là b ngề ậ ạ ẽ ầ ả ư ữ ế ả ả ả ế ả chung MESSAGES được dùng. Nó được đ nh nghĩa nh sau :ị ư
Table MESSAGES
-
1 T o m t kh i dùng các bi u th c PL/SQL đ n gi n, trong đó khai báo 4 bi n :ạ ộ ố ể ứ ơ ả ế
V_BOOL1 Boolean V_BOOL2 Boolean V_CHAR Character (chi u dài thay đ i)ề ổ
Trang 15V_NUM Number Sau đó gán cho nó các giá tr sau :ị
Variable Value
V_CHAR Câu ’42 is the answer’
V_NUM Hai ký t đ u t V_CHARự ầ ừ V_BOOL1 TRUE ho c FALSE (tùy vào V_NUM có nh l n 100 hayặ ỏ ơ không)
V_BOOL2 Ngượ ạ ớc l i v i V_BOOL1
2 T o và ch y m t kh i PL/SQL nh n 2 bi n c a SQL*Plus. Bi n đ u tiên c n ph i lũyạ ạ ộ ố ậ ế ủ ế ầ ầ ả
th a lên v i s mũ là s th hai và k t qu đừ ớ ố ố ứ ế ả ược gán cho bi n PL/SQL. L u k t quế ư ế ả này trong b ng MESSAGES ho c trong bi n k t h p (bind) c a SQL*Plus.ả ặ ế ế ợ ủ
3 Vi t m t kh i PL/SQL đ chèn m t hàng vào trong b ng MESSAGES v i NUMCOL1ế ộ ố ể ộ ả ớ
có giá tr 1 n u hàng đ u tiên đị ế ầ ược chèn vào, 2 n u là hàng th 2, … Không chèn hàngế ứ vào n u đ m đ n 6 ho c 8 và thoát kh i vòng l p sau khi sau khi chèn đ n 10. COMMITế ế ế ặ ỏ ặ ế khi k t thúc vòng l p.ế ặ