1. Trang chủ
  2. » Giáo Dục - Đào Tạo

thuc hanh dbms ct237 part2of3 kho tài liệu bách khoa

14 73 0

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

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

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

Hàm được sử dụng trong các câu lệnh truy vấn còn thủ tục thì không thể.. [ELSE statement_list] END IF  Lệnh lựa chọn CASE: Lựa chọn 1 trong các khối lệnh để thực hiện tùy và giá trị của

Trang 1

TS Trần Công Án - Thực hành Nguyên lý Hệ quản trị CSDL (CT237) -20-

BUỔI 2 - MYSQL NÂNG CAO

Nội dung:

- Tạo thủ tục và hàm

- Tạo giao dịch

2.1 Stored procedure (thủ tục) và funtion (hàm)

Stored procedure (thủ tục) và function (hàm) trong MySQL, về bản chất là một tập hợp các câu lệnh SQL được lưu trữ sẵn trên server Một thủ tục hay hàm bao gồm 1 tên, danh sách các đối số và các câu lệnh (được gọi là thân hàm hay thân thủ tục) Sự khác nhau cơ bản của hàm và thủ tục là hàm luôn trả về 1 giá trị kiểu scalar còn thủ tục thì chỉ có thể trả về giá trị thông qua đối số ra (output parameter) của thủ tục Do đó, một thủ tục có thể được sử dụng (gọi) trong một câu lệnh SQL còn thủ tục thì không được

Hàm và thủ tục trong MySQL còn được gọi chung là chương trình con (subroutine) 2.1.1 Ưu nhược điểm của hàm, thủ tục

2.1.1.1 Ưu điểm

Các ưu điểm chính của hàm và thủ tục:

1) Bảo mật và an ninh Thể hiện ở 3 điểm chính là: i) thân hàm được che dấu, ii)

các thủ tục kiểm tra an ninh có thể được thực thi trước khi thực hiện tác vụ, và iii) người gọi hàm/thủ tục chỉ cần quyền thực thi thủ tục/hàm mà không cần quyền trên các đối tượng CSDL có liên quan trong câu hàm/thủ tục

2) Hiệu năng Các câu lệnh trong thủ tục/hàm sẽ được biên dịch và tối ưu sẵn nên

việc thực thi các thủ tục/hàm sẽ nhanh hơn Ngoài ra, hàm/thủ tục còn giúp giảm thông lượng trao đổi giữa client và server do thay vì 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 hơn Một

tác vụ hay đoạn mã có thể được sử dụng nhiều vị trí trong ứng dụng hay nhiều ứng dụng trên CSDL Do đó, việc tổ chức các đoạn mã đó thành một hàm/thủ tục giúp việc bảo trì, cập nhật đoạn mã dễ dàng hơn Sự thay đổi nếu có, chỉ cần thực hiện một lần tại thủ tục/hàm tương ứng thay vì phải thực hiện tại tất cả các vị trí xuất hiện đoạn mã đó

2.1.1.2 Nhược điểm

Song song với các ưu điểm, hàm và thủ tục cũng có các nhược điểm sau:

1) Tải của server bị tăng Nếu đặt nhiều xử lý trên hệ quản trị CSDL quá sẽ 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 hơn Chức năng của ứng dụng bị phân rã trong nhiều lớp làm cho việc gỡ rối khó khăn hơn

3) Việc hỗ trợ hàm/thủ tục của các DBMS là khác nhau Do đó, nếu sử dụng hàm hay thủ tục sẽ làm cho ứng dụng phụ thuộc vào hệ quản trị CSDL

Trang 2

TS Trần Công Án - Thực hành Nguyên lý Hệ quản trị CSDL (CT237) -21-

2.1.2 Tạo và sử dụng hàm và thủ tục

2.1.2.1 Tạo hàm và 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ó 3 loại tham số:

IN: là chế độ mặc định, không bị thay đổi nếu như trong thủ tục có tác động đến

OUT: biến bên ngoài hàm truyền vào cho tham số sẽ bị thay đổi nếu như trong thủ

tục có tác động thay đổi thì nó sẽ thay đổi theo Tham số OUT luôn có dấu “@” trước tên tham số (xem phần ”Biến” trong phần 2.1.2.2 để biết ý nghĩa của dấu “@”)

INOUT: đây là sự kết hợp giữa kiểu IN và OUT, có thể gán giá trị trước và có thể bị

thay đổi nếu trong thủ tục có tác động tới

Tham số OUT và INOUT cho phép thủ tục truyền giá trị cho bên ngoài thông qua các biến

được truyền vào cho các tham số này Ngoài ra, một thủ tục có thể truyền về giá trị cho lời gọi thủ tục thông qua các lệnh SELECT bên trong 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 trong thân hàm, thủ tục kết thúc bằng dấu “;”

 Khi tạo hàm/thủ tục từ dòng lệnh, do mỗi lệnh SQL kết thúc bằng dấu “;”, trùng với ký hiệu kết thúc 1 lệnh trong chế độ dòng lệnh nên ta cần phải thay đổi ký hiệu kết thúc lệnh của chế độ dòng lệnh để tránh trùng nhau giữa hai ký hiệu này bằng lệnh:

DELIMITER “chuổi/ký tự kết thúc lệnh”

Trang 3

TS Trần Công Án - Thực hành Nguyên lý Hệ quản trị CSDL (CT237) -22-

Ví dụ:

Lệnh dấu “;” sau SELECT ở dòng thứ 3 sẽ làm cho MySQL hiểu nhầm là kết thúc lệnh tạo thủ tục nên sẽ gây ra lỗi Ta phải khắc phục như sau:

2.1.2.2 Gọi thủ tục và hàm

 Để gọi thủ tục, ta dùng lệnh CALL có cú pháp như sau:

CALL sp_name([parameter[, ]])

CALL sp_name[()]

 Hàm được gọi bằng cách dùng trực tiếp tên hàm Hàm được sử dụng trong các câu lệnh truy vấn còn thủ tục thì không thể

Ví dụ về gọi hàm và thủ tục sẽ được giới thiệu trong phần 2.1.2.3

2.1.2.3 Cú pháp căn bản của MySQL Subroutine

Subroutine về cô cơ bản cũng là một chương trình máy tính nên để viết một subroutine cũng cần có các thành phần cơ bản của một ngôn ngữ lập trình Trong phần này sẽ giới thiệu một số thành phần cơ bản của ngôn ngữ dùng để viết các subroutine trong MySQL

Cặp lệnh BEGIN … END:

Lệnh này được sử dụng để tạo một khối lệnh Tất cả các lệnh trong cặp lệnh này tương đương với 1 lệnh đơn Cặp lệnh này tương tự cặp ký hiệu “{“ và “}” trong các ngôn ngữ lập trình C hoặc Java

Biến: được khai báo bởi 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ị mặc nhiên là NULL Ngoài ra, biến cũng

có phạm vi (scope) như trong các ngôn ngữ lập trình khác Phạm vi của một biến là

từ lệnh khai báo biến đến lệnh END của khối lệnh chứa khai báo biến

Để thiết đặt giá trị của biến ta dùng lệnh SET var_name = expr | value

Trang 4

TS Trần Công Án - Thực hành Nguyên lý Hệ quản trị CSDL (CT237) -23-

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, 5

END$$

Trong MySQL còn có 1 loại biến được gọi là user-defined variable Đây có thể được xem như là 1 biến toàn cục của phiên làm việc (session) Biến này tồn tại từ khi khai báo cho đến hết phiên làm việc và có thể truy xuất mọi nơi trong phiên làm việc đó Một user-defined variable được 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

- -

2 3

CALL prc_test();

var2 @var2

-2 3

Trang 5

TS Trần Công Án - Thực hành Nguyên lý Hệ quản trị CSDL (CT237) -24-

Nhãn (label):

Nhãn dùng để đánh dấu (bookmark) 1 vị trí trong subroutine Nhãn thường được

sử dụng kết hợp với các lệnh điều khiển (lặp, rẽ nhánh) Một nhãn bao gồm 1 tên, theo sau bởi dấu hai chấm “:”

Một nhãn có thể có nhãn kết thúc tương ứng Nhãn kết thúc của một nhãn có tên trùng với tên nhãn nhưng không có dấu hai chấm theo sau Do nhãn thường được

sử dụng với các lệnh điều khiển nên ví dụ về nhãn sẽ được giới thiệu trong phần các 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 là một thành phần không thể thiếu của bất kỳ ngôn ngữ lập trình nào Trong phần này sẽ giới thiệu cú pháp của các lệnh điều khiển trong MySQL Các câu lệnh điều khiển tương tự với các ngôn ngữ lập trình đã học như C và Java chỉ được trình bày cú pháp Chi tiết về các lệnh này có thể được tham khảo tại đị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 1 trong các khối lệnh để thực hiện tùy và giá trị của một biến hay một 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 hiện chu kỳ lặp mới (tương tự lệnh CONTINUE trong các ngôn ngữ lập trình C hoặc Java) Lệnh này chỉ có thể xuất hiện trong các lệnh lặp LOOP, REPEAT và WHILE

Cú pháp: ITERATE label

Trang 6

TS Trần Công Án - Thực hành Nguyên lý Hệ quản trị CSDL (CT237) -25-

 Lệnh LEAVE:

Dùng để thoát ra khỏi 1 vòng lặp hoặc cả chương trình Lệnh này có thể sử dụng trong các lệnh lặp LOOP, REPEAT và WHILE hoặc cặp lệnh BEGIN … END Lệnh này tương tự như lệnh BREAK trong ngôn ngữ lập trình C và Java trong trường hợp

sử dụng bên trong vòng lặp

Cú pháp:LEAVE label

 Lệnh lặp LOOP:

Đây là một lệnh lặp đơn giản, cho phép thực hiện lặp lại một đoạn lệnh Lệnh này không có điều kiện lặp nên phải sử dụng cùng với các lệnh LEAVE để thoát khỏi vòng lặp (kết hợp với lệnh IF hoặc CASE để kiểm tra điều kiện) và lệnh ITERATE

để lặp lại vòng lặp tại 1 điểm nào đó trong 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 1 số nguyên n và tính tổng từ 1 đế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]

Trang 7

TS Trần Công Án - Thực hành Nguyên lý Hệ quản trị CSDL (CT237) -26-

Lệnh REPEAT thực hiện lặp lại thân hàm cho đến khi đến khi điều kiện trong mệnh

đề UNTIL thỏa thì thoát ra khỏi vòng lặp Vòng lặp này có thể kết hợp với nhãn

và các lệnh LEAVE, ITERATE để ngưng hoặc lặp lại theo một điều kiện ngoại lệ nào

đó khác với điều kiện trong mệnh đề UNTIL

Ví dụ (https://dev.mysql.com/doc/refman/5.7/en/repeat.html):

mysql> delimiter //

mysql> 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, 0 rows affected (0.00 sec)

mysql> SELECT @x//

+ -+

| @x | + -+

| 1001 | + -+

 Lệnh lặp WHILE:

Lệnh lặp này khác lệnh lặp REPEAT ở 2 điểm sau:

1) Điều kiện được kiểm tra trước khi thực hiện thân vòng lặp

2) Thân vòng lặp sẽ được thực hiện trong khi điều kiện lặp ĐÚNG (trong khi

vòng lặp REPEAT thì thực hiện thân vòng lặp khi điều kiện trong mệnh đề

UNTIL sai)

Cú pháp:

[begin_label:] WHILE search_condition DO

statement_list

END WHILE [end_label]

 Lệnh RETURN:

Lệnh này được sử dụng trong hàm, dùng để trả về giá trị cho lời gọi hàm

Cú pháp: RETURN expr

Ví dụ, hàm sau đây nhận vào 1 chuỗi là họ và tên và trả về phần tên:

CREATE FUNCTION firstName(fullName VARCHAR(100))

RETURNS VARCHAR(10)

BEGIN

DECLARE temp VARCHAR(100);

DECLARE namePosition INT;

Trang 8

TS Trần Công Án - Thực hành Nguyên lý Hệ quản trị CSDL (CT237) -27-

SET temp = TRIM(fullName);

SET namePosition = LOCATE(' ', REVERSE(temp));

RETURN RIGHT(temp, namePosition - 1);

END

2.1.2.4 Con trỏ (cursor) trong hàm và thủ tục

Con trỏ là một cấu trúc điều khiển cho phép duyệt qua các mẩu tin trong một CSDL Các con trỏ thường được sử dụng cho phép người lập trình CSDL xử lý từng mẩu tin trong kết quả trả về của một câu truy vấn

Trong hàm và thủ tục, con trỏ cho phép người lập trình khai báo một tập result set, là một tập các mẩu tin và thực hiện các tính toán phức tạp trên từng hàng trong result set đó Ngoài ra, các thủ tục còn có thể trả về một result set thông qua các tham

số đầu ra của thủ tục

Tuy nhiên, ta không thể cập nhật dữ liệu thông qua con trỏ (read only) và việc di chuyển con trỏ chỉ theo 1 chiều và liên tục (nonscrollable)

Các bước tạo và sử dụng con trỏ trong hàm, thủ tục như sau:

1) Khai báo (declare) con trỏ

DECLARE cursor_name CURSOR FOR select_statement

Câu lệnh select_statement là câu lệnh truy vấn sẽ được thực hiện để lấy dữ

liệu cho con trỏ Lệnh khai báo con trỏ phải đặt sau tất cả các lệnh khai báo biến khác trong hàm hoặc thủ tục

2) Mở (open) con trỏ

OPEN cursor_name

Lệnh mở con trỏ sẽ thực hiện câu truy vấn trong lệnh khai báo con trỏ để lấy dữ liệu cho con trỏ, sẵn sàng được sử dụng

3) Lấy (fetch) từng dòng dữ liệu từ con trỏ vào biến để xử lý

FETCH [[NEXT] FROM] cursor_name INTO var_name [, var_name]

Trang 9

TS Trần Công Án - Thực hành Nguyên lý Hệ quản trị CSDL (CT237) -28-

Thường là ta phải kiểm tra lỗi NOT FOUND khi sử dụng con trỏ để tránh trường hợp con trỏ đã duyệt đến mẩu tin cuối cùng trong tập kết quả, không còn dữ liệu

để xử lý bằng lệnh DECLARE HANDLER:

DECLARE handler_action HANDLER

FOR condition_value [, condition_value]

statement

4) Đóng (close) con trỏ, giải phóng tài nguyên cấp phát cho con trỏ

CLOSE cursor_name

Ví dụ, thủ tục sau đây trả về danh sách các email của các 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 con 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 còn dữ 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 = 1 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

Trang 10

TS Trần Công Án - Thực hành Nguyên lý Hệ quản trị CSDL (CT237) -29-

2.2 Transaction

Như đã được giới thiệu trong phần lý thuyết, một giao dịch là một đơn vị luận lý, bao gồm nhiều câu lệnh Một giao dịch sẽ thỏa các tính chất ACID, giúp đảm bảo tính toàn vẹn và an toàn của dữ liệu

Một số lệnh xử lý giao dịch trong MySQL:

 Bắt đầu một giao dịch: START TRANSACTION

 Kết thúc và xác nhận giao dịch: COMMIT

 Hủy một giao dịch: ROLLBACK [TO <savepoint_name>]

 Tạo 1 điểm mốc: SAVEPOINT <savepoint_name>

Một số lệnh không được sử dụng trong 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ụ về giao dịch như sau: Giả sử một công ty bán hàng có một đặt hàng mới

và cần ghi nhận đặt hàng vào CSDL Các bước cần thiết để thực hiện tác vụ này bao gồm:

1) Truy vấn Số đơn đặt hàng gần nhất từ table Orders để tính được Số đơn đặt

hàng cho đơn đặt hàng mới

2) Chèn các thông tin chung của đơn đặt hàng mới vào table Orders

3) Chèn các chi tiết của đơn đặt hàng mới vào table OrderDetails

4) Lấy các thông tin đặt hàng của đơn đặt hàng mới từ cả hai bảng Orders và OrderDetails để xác nhận giao dịch với khách hàng

Để đảm bảo tính toàn vẹn của dữ liệu, các bước trên phải thỏa mãn các tính chất của một giao dịch Ví dụ, trong khi thực hiện bước 1 cho một đặt hàng, nếu một xử lý cho đơn đặt hàng khác lại thực hiện song song thì sẽ dẫn đến hai đơn đặt hàng có cùng số đơn đặt hàng Hoặc nếu một giao dịch đang thực hiện đến bước 3 chưa hoàn thành thì

bị lỗi có thể dẫn đến thông tin chung của đơn đặt hàng đã được cập nhật vào CSDL nhưng chi tiết của đơn đặt hàng lại không có,…

Để tạo 1 giao dịch trong MySQL cho tác vụ đặt hàng nói trên, ta thực hiện các bước sau:

1) Tạo 1 giao dịch mới với lệnh BEGIN TRANSACTION

2) Dùng các lệnh SQL để thực hiện các tác vụ trong bước 1, 2 và 3

3) Xác nhận giao dịch bằng lệnh COMMIT

4) Truy vấn thông tin của đơn đặt hàng mới để xác nhận với người mua

Scrip SQL sau sẽ minh họa cho các bước trên:

Ngày đăng: 08/11/2019, 17:17

TỪ KHÓA LIÊN QUAN