MySQL cung cấp cho chúng tôi khả năng tạo các thủ tục được lưu trữ . Các thủ tục được lưu trữ là một phần mạnh mẽ của MySQL (và các hệ thống quản lý cơ sở dữ liệu khác, chẳng hạn như SQL Server) và chúng cho phép bạn làm được nhiều việc hơn các chế độ xem.
thủ tục được lưu trữ là một tập hợp các câu lệnh SQL được lưu trữ trong cơ sở dữ liệu. Một thủ tục được lưu trữ có thể chứa logic nghiệp vụ, là một trong những khía cạnh quan trọng giúp phân biệt các thủ tục được lưu trữ với các khung nhìn. Một thủ tục được lưu trữ có thể chấp nhận các tham số và bạn có thể đặt các biến, viết IF
các câu lệnh, v.v. trong một thủ tục được lưu trữ.
Thủ tục lưu trữ hoạt động như thế nào?
Trước hết, bạn tạo thủ tục được lưu trữ. Sau đó, khi nó đã được tạo, bạn có thể chạy nó (hay chính xác hơn là bạn "gọi" nó).
Để chạy một thủ tục được lưu trữ, bạn "gọi" nó. Khi bạn gọi nó, bạn cũng cung cấp bất kỳ thông số nào mà nó có thể yêu cầu. Sau đó, thủ tục được lưu trữ sẽ thực thi, sử dụng các tham số của bạn theo bất kỳ cách nào mà mã chỉ định.
Ví dụ:bạn có thể viết một thủ tục được lưu trữ chấp nhận một FruitId
tham số. Sau đó, quy trình được lưu trữ có thể lấy tham số đó và sử dụng nó để kiểm tra kho cho loại trái cây cụ thể đó. Do đó, bạn có thể gọi quy trình đã lưu trữ, mỗi lần với một ID trái cây khác nhau và nó sẽ trả về một giá trị cho bạn biết lượng trái cây đó còn trong kho.
Tạo một thủ tục được lưu trữ
Các thủ tục đã lưu trữ được tạo bằng cách sử dụng CREATE PROCEDURE
tuyên bố.
Cú pháp
Đây là cú pháp để tạo một thủ tục được lưu trữ:
CREATE PROCEDURE sp_name(p_1 INT) BEGIN ...code goes here... END;
Thay thế sp_name với bất kỳ tên nào bạn muốn sử dụng cho quy trình được lưu trữ. Dấu ngoặc đơn là bắt buộc - chúng bao gồm bất kỳ tham số nào. Nếu không có tham số nào được yêu cầu, dấu ngoặc đơn có thể để trống.
Nội dung chính của thủ tục được lưu trữ nằm giữa BEGIN
và END
từ khóa. Những từ khóa này được sử dụng để viết câu lệnh ghép. Một câu lệnh ghép có thể chứa nhiều câu lệnh và những câu lệnh này có thể được lồng vào nhau nếu được yêu cầu. Do đó, bạn có thể lồng BEGIN
và END
khối.
Trong hầu hết các trường hợp, bạn cũng sẽ cần tuân thủ CREATE PROCEDURE
câu lệnh với DELIMITER
lệnh và thay đổi END;
đến END //
. Như thế này:
DELIMITER // CREATE PROCEDURE sp_name(p_1 INT) BEGIN ...code goes here... END // DELIMITER ;
Tôi sẽ giải thích lý do ngay sau đây, nhưng bây giờ, hãy xem một ví dụ.
Ví dụ
Đây là một ví dụ đơn giản về việc tạo một thủ tục được lưu trữ. Chạy mã sau với FruitShop của chúng tôi cơ sở dữ liệu sẽ tạo một thủ tục được lưu trữ có tên là spCheckFruitStock :
DELIMITER // CREATE PROCEDURE spCheckFruitStock(thisFruit SMALLINT) BEGIN SELECT Fruit.FruitName, Fruit.Inventory, Units.UnitName FROM Fruit INNER JOIN Units ON Fruit.UnitId = Units.UnitId WHERE Fruit.FruitId = thisFruit; END // DELIMITER ;
Bây giờ chúng ta có thể gọi thủ tục được lưu trữ đó như sau:
CALL spCheckFruitStock(1);
Ở đây, chúng tôi chuyển một tham số là 1
là ID cho
Apple
.
Đây là kết quả:
Chúng ta có thể làm tương tự đối với bất kỳ loại quả nào trong cơ sở dữ liệu của mình, đơn giản bằng cách thay đổi tham số được truyền vào thủ tục được lưu trữ.
Giới thiệu về DELIMITER
Lệnh
Trong ví dụ trên, chúng tôi đã thêm một vài DELIMITER
và chúng tôi đã thay thế một dấu chấm phẩy bằng hai dấu gạch chéo về phía trước. Chuyện gì đang xảy ra ở đây?
Chúng tôi đã làm điều này để yêu cầu MySQL sử dụng một dấu phân cách khác trong khi nó tạo thủ tục được lưu trữ của chúng tôi.
Lý do cho điều này là, MySQL đã nhận ra dấu chấm phẩy như một dấu phân cách để đánh dấu phần cuối của mỗi câu lệnh SQL. Do đó, ngay khi MySQL nhìn thấy dấu chấm phẩy đầu tiên, nó sẽ diễn giải dấu phân cách như vậy và thủ tục được lưu trữ của chúng ta sẽ bị hỏng.
DELIMITER
lệnh cho phép chúng tôi yêu cầu MySQL sử dụng một dấu phân cách khác. Trong ví dụ trên, chúng tôi đặt giá trị này thành hai dấu gạch chéo về phía trước (//
) nhưng điều này có thể là bất cứ điều gì (mặc dù, tránh sử dụng dấu gạch chéo ngược (\
) vì đó là ký tự thoát cho MySQL). Bằng cách thay đổi dấu phân cách, MySQL sẽ không cố gắng diễn giải dấu chấm phẩy của chúng ta là phần cuối của câu lệnh - nó sẽ đợi cho đến khi thấy hai dấu gạch chéo về phía trước.
Khi chúng tôi đã tạo quy trình được lưu trữ, chúng tôi có thể sử dụng DELIMITER ;
để đặt lại dấu phân cách về dấu chấm phẩy.
Bỏ qua một quy trình đã lưu trữ
Bạn có thể bỏ một quy trình đã lưu trữ bằng cách sử dụng DROP PROCEDURE
tuyên bố. Như thế này:
DROP PROCEDURE spCheckFruitStock;
Thay đổi quy trình đã lưu trữ
Bạn có thể thay đổi một số các khía cạnh của một thủ tục được lưu trữ bằng cách sử dụng ALTER PROCEDURE
tuyên bố.
Tuy nhiên, để thay đổi nội dung của thủ tục đã lưu trữ hoặc bất kỳ tham số nào của nó, bạn cần phải bỏ thủ tục và tạo lại. Như thế này:
DROP PROCEDURE IF EXISTS spCheckFruitStock; DELIMITER // CREATE PROCEDURE spCheckFruitStock(thisFruit SMALLINT) BEGIN SELECT Fruit.FruitId, Fruit.FruitName, Fruit.Inventory, Units.UnitName FROM Fruit INNER JOIN Units ON Fruit.UnitId = Units.UnitId WHERE Fruit.FruitId = thisFruit; END // DELIMITER ;
Ở đây, chúng tôi đã thêm Fruit.FruitId
vào danh sách các cột để trả về.
Kết quả:
Thủ tục được lưu trữ nâng cao hơn
Ví dụ trên là một ví dụ đơn giản để chứng minh cú pháp của việc tạo và gọi các thủ tục được lưu trữ. Hãy xem xét một thủ tục được lưu trữ phức tạp hơn một chút:
DROP PROCEDURE IF EXISTS spCheckFruitStockLevel; DELIMITER // CREATE PROCEDURE spCheckFruitStockLevel( IN pFruitId SMALLINT(5), OUT pStockLevel VARCHAR(6)) BEGIN DECLARE stockNumber SMALLINT; SELECT Fruit.Inventory into stockNumber FROM Fruit INNER JOIN Units ON Fruit.UnitId = Units.UnitId WHERE Fruit.FruitId = pFruitId; IF stockNumber > 10 THEN SET pStockLevel = 'High'; ELSEIF (stockNumber <= 10 AND stockNumber >= 5) THEN SET pStockLevel = 'Medium'; ELSEIF (stockNumber < 5) THEN SET pStockLevel = 'Low - Please Replace Now!'; END IF; END // DELIMITER ;
Ví dụ trên chấp nhận hai chế độ tham số khác nhau (IN
và OUT
). IN
là mặc định, vì vậy đây là lý do tại sao ví dụ trước không bao gồm chế độ này.
Ở đây, chúng tôi cũng đặt một biến. Chúng tôi sử dụng DECLARE stockNumber SMALLINT
để khai báo một biến có tên là stockNumber
với một loại SMALLINT
(số nguyên nhỏ).
Chúng tôi sử dụng SELECT
câu lệnh để tra cứu khoảng không quảng cáo cho ID trái cây đã cho và gán ID đó vào stockNumber
của chúng tôi biến.
Cuối cùng, chúng tôi sử dụng IF
trong SQL để xác định mức tồn kho, đặt giá trị này vào pStockLevel
(tất nhiên là tham số OUT
tham số - đây là giá trị mà chúng ta sẽ thấy khi gọi thủ tục được lưu trữ).
Gọi một thủ tục đã lưu trữ với OUT
hoặc INOUT
Tham số
Trong ví dụ cuối cùng của chúng tôi, chúng tôi đã chỉ định hai tham số, một IN
và một OUT
tham số.
Khi chúng tôi gọi thủ tục được lưu trữ này, chúng tôi vẫn cần bao gồm OUT
tham số. Tuy nhiên, vì chúng ta sẽ không biết giá trị của nó (sau cùng, đó là lý do tại sao chúng ta gọi nó - để tìm ra giá trị của nó!), Chúng ta sẽ cần sử dụng một biến. Sau đó, chúng ta có thể sử dụng SELECT
để tìm ra giá trị của nó.
Như thế này:
CALL spCheckFruitStockLevel(1, @stockLevel); select @stockLevel;
Kết quả:
Chế độ tham số
Chúng tôi vừa sử dụng hai chế độ tham số (IN
và OUT
). Trong MySQL, có ba chế độ tham số có thể được sử dụng với các thủ tục được lưu trữ.
- TRONG
- Khi bạn sử dụng chế độ tham số này, bạn (hoặc ứng dụng của bạn) phải chuyển giá trị của tham số khi bạn gọi thủ tục được lưu trữ. Các thông số này được bảo vệ. Do đó, giá trị ban đầu của nó được giữ lại sau khi thủ tục được lưu trữ đã được thực thi. Nếu thủ tục được lưu trữ thay đổi giá trị, nó chỉ làm như vậy trên bản sao của tham số.
Chế độ này là chế độ mặc định. Nếu bạn không cung cấp chế độ tham số, nó sẽ là
IN
. - HẾT
- Giá trị của
OUT
tham số có thể thay đổi trong thủ tục được lưu trữ và giá trị của nó được trả về ứng dụng gọi. - GIỚI THIỆU
- Chế độ này là sự kết hợp của
IN
vàOUT
các chế độ. Bạn có thể chuyển giá trị ban đầu, thủ tục được lưu trữ có thể thay đổi nó và nó sẽ trả về giá trị mới cho ứng dụng gọi.