Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống
1
/ 14 trang
THÔNG TIN TÀI LIỆU
Thông tin cơ bản
Định dạng
Số trang
14
Dung lượng
1,22 MB
Nội dung
BUỔI - MYSQL NÂNG CAO Nội dung: - Tạo thủ tục hàm Tạo giao dịch 2.1 Stored procedure (thủ tục) funtion (hàm) Stored procedure (thủ tục) function (hàm) MySQL, chất tập hợp câu lệnh SQL lưu trữ sẵn server Một thủ tục hay hàm bao gồm tên, danh sách đối số câu lệnh (được gọi thân hàm hay thân thủ tục) Sự khác hàm thủ tục hàm ln trả giá trị kiểu scalar thủ tục trả giá trị thơng qua đối số (output parameter) thủ tục Do đó, thủ tục sử dụng (gọi) câu lệnh SQL thủ tục khơng Hàm thủ tục MySQL gọi chung chương trình (subroutine) 2.1.1 Ưu nhược điểm hàm, thủ tục 2.1.1.1 Ưu điểm Các ưu điểm hàm thủ tục: 1) Bảo mật an ninh Thể điểm là: i) thân hàm che dấu, ii) thủ tục kiểm tra an ninh thực thi trước thực tác vụ, iii) người gọi hàm/thủ tục cần quyền thực thi thủ tục/hàm mà không cần quyền đối tượng CSDL có liên quan câu hàm/thủ tục 2) Hiệu Các câu lệnh thủ tục/hàm biên dịch tối ưu sẵn nên việc thực thi thủ tục/hàm nhanh Ngồi ra, hàm/thủ tục giúp giảm thơng lượng trao đổi client server thay client cần phải 3) Bảo trì Sử dụng hàm/thủ tục giúp cho việc bảo trì ứng dụng dễ dàng Một tác vụ hay đoạn mã sử dụng nhiều vị trí ứng dụng hay nhiều ứng dụng CSDL Do đó, việc tổ chức đoạn mã thành hàm/thủ tục giúp việc bảo trì, cập nhật đoạn mã dễ dàng Sự thay đổi có, cần thực lần thủ tục/hàm tương ứng thay phải thực tất vị trí xuất đoạn mã 2.1.1.2 Nhược điểm Song song với ưu điểm, hàm thủ tục có nhược điểm sau: 1) Tải server bị tăng Nếu đặt nhiều xử lý hệ quản trị CSDL làm cho khối lượng công việc mà server phải xử lý tăng lên 2) Khó debug lỗi Chức ứng dụng bị phân rã nhiều lớp làm cho việc gỡ rối khó khăn 3) Việc hỗ trợ hàm/thủ tục DBMS khác Do đó, sử dụng hàm hay thủ tục làm cho ứng dụng phụ thuộc vào hệ quản trị CSDL TS Trần Công Án - Thực hành Nguyên lý Hệ quản trị CSDL (CT237) -20- 2.1.2 Tạo sử dụng hàm thủ tục 2.1.2.1 Tạo hàm thủ tục Cú pháp tạo thủ tục: CREATE PROCEDURE sp_name ([proc_parameter[, ]]) routine_body proc_parameter: [ IN | OUT | INOUT ] param_name type type: Any valid MySQL data type Có loại tham số: IN: chế độ mặc định, không bị thay đổi thủ tục có tác động đến OUT: biến bên hàm truyền vào cho tham số bị thay đổi thủ tục có tác động thay đổi thay đổi theo Tham số OUT ln có dấu “@” trước tên tham số (xem phần ”Biến” phần 2.1.2.2 để biết ý nghĩa dấu “@”) INOUT: kết hợp kiểu IN OUT, gán giá trị trước bị thay đổi thủ tục có tác động tới Tham số OUT INOUT cho phép thủ tục truyền giá trị cho bên ngồi thơng qua biến truyền vào cho tham số Ngồi ra, thủ tục truyền giá trị cho lời gọi thủ tục thông qua lệnh SELECT bên thủ tục Cú pháp tạo hàm: CREATE FUNCTION sp_name ([func_parameter[, ]]) RETURNS type routine_body func_parameter: param_name type type: Any MySQL data types, except resultset Lưu ý: Mỗi lệnh thân hàm, thủ tục kết thúc dấu “;” Khi tạo hàm/thủ tục từ dòng lệnh, lệnh SQL kết thúc dấu “;”, trùng với ký hiệu kết thúc lệnh chế độ dòng lệnh nên ta cần phải thay đổi ký hiệu kết thúc lệnh chế độ dòng lệnh để tránh trùng hai ký hiệu lệnh: DELIMITER “chuổi/ký tự kết thúc lệnh” TS Trần Công Án - Thực hành Nguyên lý Hệ quản trị CSDL (CT237) -21- Ví dụ: Lệnh dấu “;” sau SELECT dòng thứ làm cho MySQL hiểu nhầm kết thúc lệnh tạo thủ tục nên gây lỗi Ta phải khắc phục sau: 2.1.2.2 Gọi thủ tục hàm Để gọi thủ tục, ta dùng lệnh CALL có cú pháp sau: CALL sp_name([parameter[, ]]) CALL sp_name[()] Hàm gọi cách dùng trực tiếp tên hàm Hàm sử dụng câu lệnh truy vấn thủ tục khơng thể Ví dụ gọi hàm thủ tục giới thiệu phần 2.1.2.3 2.1.2.3 Cú pháp MySQL Subroutine Subroutine cô chương trình máy tính nên để viết subroutine cần có thành phần ngơn ngữ lập trình Trong phần giới thiệu số thành phần ngôn ngữ dùng để viết subroutine MySQL Cặp lệnh BEGIN … END: Lệnh sử dụng để tạo khối lệnh Tất lệnh cặp lệnh tương đương với lệnh đơn Cặp lệnh tương tự cặp ký hiệu “{“ “}” ngôn ngữ lập trình C Java Biến: khai báo lệnh: DECLARE var_name [, var_name] type [DEFAULT value] Nếu không khai báo giá trị mặc nhiên, giá trị NULL Ngồi ra, biến có phạm vi (scope) ngơn ngữ lập trình khác Phạm vi biến từ lệnh khai báo biến đến lệnh END khối lệnh chứa khai báo biến Để thiết đặt giá trị biến ta dùng lệnh SET var_name = expr | value TS Trần Công Án - Thực hành Nguyên lý Hệ quản trị CSDL (CT237) -22- DELIMITER $$ CREATE PROCEDURE my_procedure_Local_Variables() BEGIN DECLARE a INT DEFAULT 1; declare local variables DECLARE b, c INT; SET a = a + 1; set value for the variables SET b = 3; SET c = a + b; BEGIN local variable in nested block DECLARE c INT; SET c = 10; /* local variable c takes precedence over the one of the same name declared in the enclosing block */ SELECT a, b, c; return 2, 3, 10 END; SELECT a, b, c; return 2, 3, END$$ Trong MySQL có loại biến gọi user-defined variable Đây xem biến toàn cục phiên làm việc (session) Biến tồn từ khai báo hết phiên làm việc truy xuất nơi phiên làm việc Một user-defined variable thêm dấu “@” vào trước tên biến CREATE PROCEDURE prc_test() BEGIN DECLARE var2 INT DEFAULT 1; SET var2 := var2 + 1; SET @var2 := @var2 + 1; SELECT var2, @var2; END; SET @var2 = 1; CALL prc_test(); var2 @var2 CALL prc_test(); var2 @var2 TS Trần Công Án - Thực hành Nguyên lý Hệ quản trị CSDL (CT237) -23- Nhãn (label): Nhãn dùng để đánh dấu (bookmark) vị trí subroutine Nhãn thường sử dụng kết hợp với lệnh điều khiển (lặp, rẽ nhánh) Một nhãn bao gồm tên, theo sau dấu hai chấm “:” Một nhãn có nhãn kết thúc tương ứng Nhãn kết thúc nhãn có tên trùng với tên nhãn khơng có dấu hai chấm theo sau Do nhãn thường sử dụng với lệnh điều khiển nên ví dụ nhãn giới thiệu phần câu lệnh điều khiển Các câu lệnh điều khiển Các câu lệnh điều khiển thành phần khơng thể thiếu ngơn ngữ lập trình Trong phần giới thiệu cú pháp lệnh điều khiển MySQL Các câu lệnh điều khiển tương tự với ngơn ngữ lập trình học C Java trình bày cú pháp Chi tiết lệnh tham khảo địa chỉ: https://dev.mysql.com/doc/refman/5.7/en/flow-control-statements.html Lệnh rẽ nhánh IF … ELSE: IF search_condition THEN statement_list [ELSEIF search_condition THEN statement_list] [ELSE statement_list] END IF Lệnh lựa chọn CASE: Lựa chọn khối lệnh để thực tùy giá trị biến hay biểu thức điều kiện CASE case_value WHEN when_value THEN statement_list [WHEN when_value THEN statement_list] [ELSE statement_list] END CASE Hoặc: CASE WHEN search_condition THEN statement_list [WHEN search_condition THEN statement_list] [ELSE statement_list] END CASE Lệnh ITERATE: Dùng để thực chu kỳ lặp (tương tự lệnh CONTINUE ngơn ngữ lập trình C Java) Lệnh xuất lệnh lặp LOOP, REPEAT WHILE Cú pháp: ITERATE label TS Trần Công Án - Thực hành Nguyên lý Hệ quản trị CSDL (CT237) -24- Lệnh LEAVE: Dùng để thoát khỏi vòng lặp chương trình Lệnh sử dụng lệnh lặp LOOP, REPEAT WHILE cặp lệnh BEGIN … END Lệnh tương tự lệnh BREAK ngơn ngữ lập trình C Java trường hợp sử dụng bên vòng lặp Cú pháp: LEAVE label Lệnh lặp LOOP: Đây lệnh lặp đơn giản, cho phép thực lặp lại đoạn lệnh Lệnh khơng có điều kiện lặp nên phải sử dụng với lệnh LEAVE để khỏi vòng lặp (kết hợp với lệnh IF CASE để kiểm tra điều kiện) lệnh ITERATE để lặp lại vòng lặp điểm vòng lặp Cú pháp: [begin_label:] LOOP statement_list END LOOP [end_label] Ví dụ: Thủ tục sau nhận vào số nguyên n tính tổng từ đến n CREATE PROCEDURE testLoop(INT n) BEGIN DECLARE tong INT DEFAULT 0; DECLARE i INT DEFAULT 1; count_loop: LOOP IF i > n THEN LEAVE count_loop; END IF; SET tong=tong+i; SET i=i+1; END LOOP count_loop; SELECT tong as 'Tong 1->n'; END Lệnh lặp REPEAT; [begin_label:] REPEAT statement_list UNTIL search_condition END REPEAT [end_label] TS Trần Công Án - Thực hành Nguyên lý Hệ quản trị CSDL (CT237) -25- Lệnh REPEAT thực lặp lại thân hàm đến điều kiện mệnh đề UNTIL thỏa khỏi vòng lặp Vòng lặp kết hợp với nhãn lệnh LEAVE, ITERATE để ngưng lặp lại theo điều kiện ngoại lệ khác với điều kiện mệnh đề UNTIL Ví dụ (https://dev.mysql.com/doc/refman/5.7/en/repeat.html): mysql> mysql> -> -> -> -> -> -> -> delimiter // CREATE PROCEDURE dorepeat(p1 INT) BEGIN SET @x = 0; REPEAT SET @x = @x + 1; UNTIL @x > p1 END REPEAT; END // mysql> CALL dorepeat(1000)// Query OK, rows affected (0.00 sec) mysql> SELECT @x// + + | @x | + + | 1001 | + + Lệnh lặp WHILE: Lệnh lặp khác lệnh lặp REPEAT điểm sau: 1) Điều kiện kiểm tra trước thực thân vòng lặp 2) Thân vòng lặp thực điều kiện lặp ĐÚNG (trong vòng lặp REPEAT thực thân vòng lặp điều kiện mệnh đề UNTIL sai) Cú pháp: [begin_label:] WHILE search_condition DO statement_list END WHILE [end_label] Lệnh RETURN: Lệnh sử dụng hàm, dùng để trả giá trị cho lời gọi hàm Cú pháp: RETURN expr Ví dụ, hàm sau nhận vào chuỗi họ tên trả phần tên: CREATE FUNCTION firstName(fullName VARCHAR(100)) RETURNS VARCHAR(10) BEGIN DECLARE temp VARCHAR(100); DECLARE namePosition INT; TS Trần Công Án - Thực hành Nguyên lý Hệ quản trị CSDL (CT237) -26- SET temp = TRIM(fullName); SET namePosition = LOCATE(' ', REVERSE(temp)); RETURN RIGHT(temp, namePosition - 1); END 2.1.2.4 Con trỏ (cursor) hàm thủ tục Con trỏ cấu trúc điều khiển cho phép duyệt qua mẩu tin CSDL Các trỏ thường sử dụng cho phép người lập trình CSDL xử lý mẩu tin kết trả câu truy vấn Trong hàm thủ tục, trỏ cho phép người lập trình khai báo tập result set, tập mẩu tin thực tính tốn phức tạp hàng result set Ngồi ra, thủ tục trả result set thông qua tham số đầu thủ tục Tuy nhiên, ta cập nhật liệu thông qua trỏ (read only) việc di chuyển trỏ theo chiều liên tục (nonscrollable) Các bước tạo sử dụng trỏ hàm, thủ tục sau: 1) Khai báo (declare) trỏ DECLARE cursor_name CURSOR FOR select_statement Câu lệnh select_statement câu lệnh truy vấn thực để lấy liệu cho trỏ Lệnh khai báo trỏ phải đặt sau tất lệnh khai báo biến khác hàm thủ tục 2) Mở (open) trỏ OPEN cursor_name Lệnh mở trỏ thực câu truy vấn lệnh khai báo trỏ để lấy liệu cho trỏ, sẵn sàng sử dụng 3) Lấy (fetch) dòng liệu từ trỏ vào biến để xử lý FETCH [[NEXT] FROM] cursor_name INTO var_name [, var_name] TS Trần Công Án - Thực hành Nguyên lý Hệ quản trị CSDL (CT237) -27- Thường ta phải kiểm tra lỗi NOT FOUND sử dụng trỏ để tránh trường hợp trỏ duyệt đến mẩu tin cuối tập kết quả, không liệu để xử lý lệnh DECLARE HANDLER: DECLARE handler_action HANDLER FOR condition_value [, condition_value] statement 4) Đóng (close) trỏ, giải phóng tài nguyên cấp phát cho trỏ CLOSE cursor_name Ví dụ, thủ tục sau trả danh sách email nhân viên: CREATE PROCEDURE build_email_list (INOUT email_list varchar(4000)) BEGIN DECLARE v_finished INTEGER DEFAULT 0; DECLARE v_email varchar(100) DEFAULT ""; khai báo trỏ cho employee email DEClARE email_cursor CURSOR FOR SELECT email FROM employees; khai báo NOT FOUND handler để xử lý lỗi khơng liệu DECLARE CONTINUE HANDLER FOR NOT FOUND SET v_finished = 1; OPEN email_cursor; get_email: LOOP FETCH email_cursor INTO v_email; IF v_finished = THEN LEAVE get_email; END IF; build email list SET email_list = CONCAT(v_email,";",email_list); END LOOP get_email; CLOSE email_cursor; END TS Trần Công Án - Thực hành Nguyên lý Hệ quản trị CSDL (CT237) -28- 2.2 Transaction Như giới thiệu phần lý thuyết, giao dịch đơn vị luận lý, bao gồm nhiều câu lệnh Một giao dịch thỏa tính chất ACID, giúp đảm bảo tính tồn vẹn an tồn liệu Một số lệnh xử lý giao dịch MySQL: Bắt đầu giao dịch: START TRANSACTION Kết thúc xác nhận giao dịch: COMMIT Hủy giao dịch: ROLLBACK [TO ] Tạo điểm mốc: SAVEPOINT Một số lệnh không sử dụng giao dịch: CREATE / ALTER / DROP DATABAS E CREATE /ALTER / DROP / RENAME / TRUNCATE TABLE CREATE / DROP INDEX CREATE / DROP EVENT CREATE / DROP FUNCTION CREATE / DROP PROCEDURE Một ví dụ giao dịch sau: Giả sử cơng ty bán hàng có đặt hàng cần ghi nhận đặt hàng vào CSDL Các bước cần thiết để thực tác vụ bao gồm: 1) Truy vấn Số đơn đặt hàng gần từ table Orders để tính Số đơn đặt hàng cho đơn đặt hàng 2) Chèn thông tin chung đơn đặt hàng vào table Orders 3) Chèn chi tiết đơn đặt hàng vào table OrderDetails 4) Lấy thông tin đặt hàng đơn đặt hàng từ hai bảng Orders OrderDetails để xác nhận giao dịch với khách hàng Để đảm bảo tính tồn vẹn liệu, bước phải thỏa mãn tính chất giao dịch Ví dụ, thực bước cho đặt hàng, xử lý cho đơn đặt hàng khác lại thực song song dẫn đến hai đơn đặt hàng có số đơn đặt hàng Hoặc giao dịch thực đến bước chưa hồn thành bị lỗi dẫn đến thông tin chung đơn đặt hàng cập nhật vào CSDL chi tiết đơn đặt hàng lại khơng có,… Để tạo giao dịch MySQL cho tác vụ đặt hàng nói trên, ta thực bước sau: 1) Tạo giao dịch với lệnh BEGIN TRANSACTION 2) Dùng lệnh SQL để thực tác vụ bước 1, 3) Xác nhận giao dịch lệnh COMMIT 4) Truy vấn thông tin đơn đặt hàng để xác nhận với người mua Scrip SQL sau minh họa cho bước trên: TS Trần Công Án - Thực hành Nguyên lý Hệ quản trị CSDL (CT237) -29- start a new transaction start transaction; get latest order number select @orderNumber := max(orderNUmber) from orders; set new order number set @orderNumber = @orderNumber + 1; insert a new order for customer 145 insert into orders(orderNumber, orderDate, requiredDate, shippedDate, status, customerNumber) values(@orderNumber, now(), date_add(now(), INTERVAL DAY), date_add(now(), INTERVAL DAY), 'In Process', 145); insert order line items insert into orderdetails(orderNumber, productCode, quantityOrdered, priceEach, orderLineNumber) values(@orderNumber,'S18_1749', 30, '136', 1), (@orderNumber,'S18_2248', 50, '55.09', 2); commit changes commit; get the new inserted order select * from orders a inner join orderdetails b on a.ordernumber = b.ordernumber where a.ordernumber = @ordernumber TS Trần Công Án - Thực hành Nguyên lý Hệ quản trị CSDL (CT237) -30- Các mức độ cô lập hỗ trợ MySQL: 1) READ UNCOMMITTED: cho phép dirty read 2) READ COMMITED: không cho phép dirty read cho phép nonrepeatable read phantom 3) REPEATABLE READ: không cho phép dirty read nonrepeatable read có phantom 4) SERIALIZABLE: thực thi giao dịch theo chế độ tuần tự, ngoại lệ bất thường không xảy Để thiết đặt mức độ cô lập, ta dùng lệnh sau: SET [GLOBAL | SESSION] TRANSACTION ISOLATION LEVEL < REPEATABLE READ | READ COMMITTED | READ UNCOMMITTED | SERIALIZABLE > 2.3 Thực hành Bài Tạo thủ tục hàm sau (dựa CSDL QLDIEM): 1) Thủ tục THEM_SV cho phép thêm sinh viên vào CSDL với tham số: MSSV, họ tên, giới tính (nam/nữ), ngày sinh, nơi sinh, địa chỉ, tên khoa 2) Thủ tục XOA_SV cho phép xóa sinh viên CSDL Thủ tục nhận vào MSSV, MSSV tồn xóa kết sinh viên trước xóa SV khỏi CSDL 3) Thủ tục DIEM_TB, nhận vào MSSV trả điểm trung bình sinh SV vó MSSV tương ứng thơng qua output parameter Nếu MSSV truyền vào khơng có trả -1 4) Tương tự câu 3) viết hàm 5) Thủ tục BANG_DIEM_TB nhận vào mã khoa trả bảng điểm trung bình SV thuộc khoa 6) Viết hàm TOT_NGHIEP kiểm tra sinh viên có đủ điều kiện tốt nghiệp hay không Hàm nhận vào MSSV trả TRUE (nonzero) sinh viên đủ điều kiện tốt nghiệp FALSE (zero) không đủ điều kiện 7) Viết hàm LOAI_TOT_NGHIEP nhận vào MSSV trả loại tốt nghiệp sinh viên (dựa vào qui chế học vụ Trường ĐHCT) TS Trần Công Án - Thực hành Nguyên lý Hệ quản trị CSDL (CT237) -31- 8) Viết thủ tục SV_TOT_NGHIEP nhận vào mã khoa liệt kê sinh viên đủ điều kiện tốt nghiệp khoa đó, có sử dụng hàm viết Câu 6) 7) trỏ để xử lý Các thông tin cần hiển thị MSSV, họ tên, số tín học, điểm trung bình, loại tốt nghiệp 9) Viết hàm SL_SV_KHOA nhận vào tên Khoa trả số lượng SV Khoa 10) Viết thủ tục SV_LOAI nhận vào tên loại (giỏi, khá, trung bình,…) trả danh sách sinh viên (bao gồm MSSV, họ tên) có loại tương ứng cho lời gọi thủ tục (sử dụng hàm LOAI_TOT_NGHIEP bên trên) Bài Hãy tạo nối kết đến MySQL tắt chế độ autocommit (set autocommit = 0) Thực bước sau: Tạo quan hệ Authors có trường auID (mã tác giả) auName (tên tác giả) Thiết đặt mức độ cô lập REPEATABLE READ, thực lệnh sau nối kết giải thích kết sau thực hết lệnh: # Nối kết Nối kết INSERT INTO Authors VALUES (1,‘Donald Trump’); INSERT INTO Authors VALUES (2, ‘Harry Clinton’); DELETE FROM Authors WHERE name LIKE ‘Don%’; INSERT INTO Authors VALUES (3, ‘Donald Duck’); DELETE FROM Authors WHERE name LIKE ‘Har%’; COMMIT; COMMIT; Thiết đặt mức độ cô lập SERIALIZABLE, thực lại lệnh Câu giải thích kết Thiết đặt ràng buộc khóa lên cột auID table Authors tạo script gồm lệnh chèn mẩu tin vào table Authors cho xảy trường hợp deadlock Bài Tạo table Accounts với cấu trúc liệu sau: Username (varchar(8)) Fullname (varchar(128)) Balance (int) jones Alice Jones 82 bitdiddl Ben Bitdiddle 65 mike Michael Dole 73 alyssa Alyssa P Hacker 79 TS Trần Công Án - Thực hành Nguyên lý Hệ quản trị CSDL (CT237) -32- Mở hai nối kết hai cửa sổ khác thực yêu cầu sau: # Nối kết 1 BEGIN; SELECT * FROM Accounts; BEGIN; INSERT INTO Accounts VALUES('chuck', 'Charles Robinson', 55); Hãy thực câu truy vấn tất tài khoản nối kết, quan sát giải thích kết COMMIT; Trên nối kết 1, liệt kê tất tài khoản Kết có bao gồm tài khoản ‘chuck’ khơng? Tại sao? BEGIN; UPDATE accounts SET balance=balance+5 WHERE username='mike'; 10 11 BEGIN; UPDATE accounts SET balance=balance+5 WHERE username='mike'; Điều xảy thực lệnh thứ 9? Tại sao? ROLLBACK; COMMIT; Số dư tài khoản ‘mike’ sau lệnh 11 bao nhiêu? Tại sao? 12 13 BEGIN; UPDATE Accounts SET balance=balance - 15 WHERE username='bitdiddl'; 14 15 SELECT * FROM Accounts; 16 17 18 SELECT * FROM Accounts; Nối kết UPDATE Accounts SET balance=balance + 15 WHERE username='alyssa'; COMMIT; SELECT * FROM Accounts; Quan sát giải thích kết câu lệnh 14, 16, 18 TS Trần Công Án - Thực hành Nguyên lý Hệ quản trị CSDL (CT237) -33- ... MSSV, họ tên, số tín học, điểm trung bình, loại tốt nghiệp 9) Viết hàm SL_SV _KHOA nhận vào tên Khoa trả số lượng SV Khoa 10) Viết thủ tục SV_LOAI nhận vào tên loại (giỏi, khá, trung bình,…) trả... Robinson', 55); Hãy thực câu truy vấn tất tài kho n nối kết, quan sát giải thích kết COMMIT; Trên nối kết 1, liệt kê tất tài kho n Kết có bao gồm tài kho n ‘chuck’ không? Tại sao? BEGIN; UPDATE... khơng có trả -1 4) Tương tự câu 3) viết hàm 5) Thủ tục BANG_DIEM_TB nhận vào mã khoa trả bảng điểm trung bình SV thuộc khoa 6) Viết hàm TOT_NGHIEP kiểm tra sinh viên có đủ điều kiện tốt nghiệp hay