1. 程式人生 > >mysql儲存過程語法大全

mysql儲存過程語法大全

20.2.1CREATE PROCEDURECREATE FUNCTION

CREATE PROCEDURE sp_name ([proc_parameter[,...]])
[characteristic ...] routine_body
CREATE FUNCTION sp_name ([func_parameter[,...]])
RETURNS type
[characteristic ...] routine_body
proc_parameter:
[ IN | OUT | INOUT ] param_name type
func_parameter
:
param_name type
type:
Any valid MySQL data type
characteristic:
LANGUAGE SQL
| [NOT] DETERMINISTIC
| { CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA }
| SQL SECURITY { DEFINER | INVOKER }
| COMMENT 'string'
routine_body:
Valid SQL procedure statement or statements

這些語句建立儲存子程式。要在MySQL 5.1中建立子程式,必須具有CREATE ROUTINE許可權,並且ALTER ROUTINE和EXECUTE許可權被自動授予它的建立者。如果二進位制日誌功能被允許,你也可能需要SUPER許可權,請參閱20.4節“儲存子程式和觸發程式的二進位制日誌功能”

預設地,子程式與當前資料庫關聯。要明確地把子程式與一個給定資料庫關聯起來,可以在建立子程式的時候指定其名字為db_name.sp_name

如果子程式名和內建的SQL函式名一樣,定義子程式時,你需要在這個名字和隨後括號中間插入一個空格,否則發生語法錯誤。當你隨後呼叫子程式的時候也要插入。為此,即使有可能出現這種情況,我們還是建議最好避免給你自己的 儲存子程式取與存在的SQL函式一樣的名字。

由括號包圍的引數列必須總是存在。如果沒有引數,也該使用一個空引數列()。每個引數 預設都是一個IN引數。要指定為其它引數,可在引數名之前使用關鍵詞 OUT或INOUT

注意: 指定引數為IN, OUT, 或INOUT 只對PROCEDURE是合法的。(FUNCTION引數總是被認為是IN引數)

RETURNS字句只能對FUNCTION指定,對函式而言這是強制的。它用來指定函式的返回型別,而且函式體必須包含一個RETURN value語句。

CREATE FUNCTION語句被用在更早的MySQL版本上支援UDF (自定義函式)。請參閱27.2節,“給MySQL新增新函式”。 UDF繼續被支援,即使現在 有了儲存函式。UDF會被認為一個外部儲存函式。然而,不要讓儲存函式與UDF函式共享名字空間。

外部儲存程式的框架將在不久的將來引入。這將允許你用SQL之外的語言編寫儲存程式。最可能的是,第一個被支援語言是PHP,因為核心PHP引擎很小,執行緒安全,且可以被方便地嵌入。因為框架是公開的,它希望許多其它語言也能被支援。

如果程式或執行緒總是對同樣的輸入引數產生同樣的結果,則被認為它是“確定的”,否則就是“非確定”的。如果既沒有給定DETERMINISTIC也沒有給定NOT DETERMINISTIC,預設的就是NOT DETERMINISTIC。

為進行復制,使用NOW()函式(或它的同義詞)或RAND()函式會不必要地使得一個子程式非確定。對NOW()而言,二進位制日誌包括時間戳並被正確複製。RAND() 只要在一個子程式被內應用一次也會被正確複製。(你可以把子程式執行時間戳和隨機數種子認為強制輸入,它們在主從上是同樣的。)

當前來講,DETERMINISTIC特徵被接受,但還沒有被優化程式所使用。然而如果二進位制日誌功能被允許了,這個特徵影響到MySQL是否會接受子程式定義。請參閱20.4,“儲存子程式和觸發程式的二進位制日誌功能”

一些特徵提供子程式使用資料的內在資訊。CONTAINS SQL表示子程式不包含讀或寫資料的語句。NO SQL表示子程式不包含SQL語句。READS SQL DATA表示子程式包含讀資料的語句,但不包含寫資料的語句。MODIFIES SQL DATA表示子程式包含寫資料的語句。如果這些特徵沒有明確給定,預設的是CONTAINS SQL。

SQL SECURITY特徵可以用來指定 子程式該用建立子程式者的許可來執行,還是使用呼叫者的許可來執行。預設值是DEFINER。在SQL:2003中者是一個新特性。建立者或呼叫者必須由訪問 子程式關聯的資料庫的許可。在MySQL 5.1中,必須有EXECUTE許可權才能執行子程式。必須擁有這個許可權的使用者要麼是定義者,要麼是呼叫者,這取決於SQL SECURITY特徵是如何設定的。

MySQL儲存sql_mode系統變數設定,這個設定在子程式被建立的時候起作用,MySQL總是強制使用這個設定來執行 子程式。

COMMENT子句是一個MySQL的擴充套件,它可以被用來描述 儲存程式。這個資訊被SHOW CREATE PROCEDURE和 SHOW CREATE FUNCTION語句來顯示。

MySQL允許子程式包含DDL語句,如CREATE和DROP。MySQL也允許儲存程式(但不是 儲存函式)包含SQL 互動語句,如COMMIT。儲存函式不可以包含那些做明確的和絕對的提交或者做回滾的語。SQL標準不要求對這些語句的支援,SQL標準宣告每個DBMS提供商可以決定是否允許支援這些語句。

儲存子程式不能使用LOAD DATA INFILE。

返回結果包的語句不能被用在儲存函式種。這包括不使用INTO給變數讀取 列值的SELECT語句,SHOW 語句,及其它諸如EXPLAIN這樣的語句。對於可在函式定義時間被決定要返回一個結果包的語句,發生一個允許從函式錯誤返回結果包的Not(ER_SP_NO_RETSET_IN_FUNC)。對於只可在執行時決定要返回一個結果包的語句, 發生一個不能在給定上下文錯誤返回結果包的PROCEDURE %s (ER_SP_BADSELECT)。

下面是一個使用OUT引數的簡單的儲存程式的例子。例子為,在 程式被定義的時候,用mysql客戶端delimiter命令來把語句定界符從 ;變為//。這就允許用在 程式體中的;定界符被傳遞到伺服器而不是被mysql自己來解釋。

mysql> delimiter //
mysql> CREATE PROCEDURE simpleproc (OUT param1 INT)
-> BEGIN
->SELECT COUNT(*) INTO param1 FROM t;
-> END
-> //
Query OK, 0 rows affected (0.00 sec)
mysql> delimiter ;
mysql> CALL simpleproc(@a);
Query OK, 0 rows affected (0.00 sec)
mysql> SELECT @a;
+------+
| @a|
+------+
| 3|
+------+
1 row in set (0.00 sec)

當使用delimiter命令時,你應該避免使用反斜槓(\)字元,因為那是MySQL的 轉義字元。

下列是一個例子,一個採用引數的函式使用一個SQL函式執行一個操作,並返回結果:

mysql> delimiter //
mysql> CREATE FUNCTION hello (s CHAR(20)) RETURNS CHAR(50)
-> RETURN CONCAT('Hello, ',s,'!');
-> //
Query OK, 0 rows affected (0.00 sec)
mysql> delimiter ;
mysql> SELECT hello('world');
+----------------+
| hello('world') |
+----------------+
| Hello, world!|
+----------------+
1 row in set (0.00 sec)

如果在儲存函式中的RETURN語句返回一個型別不同於在函式的RETURNS子句中指定型別的值,返回值被強制為恰當的型別。比如,如果一個函式返回一個ENUM或SET值,但是RETURN語句返回一個整數,對於SET成員集的相應的ENUM成員,從函式返回的值是字串。