相關文件 下載本手冊
PDF (美式信紙) - 39.9Mb
PDF (A4) - 40.0Mb
Man Pages (TGZ) - 258.5Kb
Man Pages (Zip) - 365.5Kb
Info (Gzip) - 4.0Mb
Info (Zip) - 4.0Mb


MySQL 8.4 參考手冊  /  MySQL 8.4 常見問題  /  MySQL 8.4 常見問題:預存程序與函數

A.4 MySQL 8.4 常見問題:預存程序與函數

A.4.1. MySQL 是否支援預存程序與函數?
A.4.2. 我可以在哪裡找到 MySQL 預存程序與預存函數的文件?
A.4.3. 是否有 MySQL 預存程序的討論論壇?
A.4.4. 我可以在哪裡找到預存程序的 ANSI SQL 2003 規範?
A.4.5. 如何管理預存常式?
A.4.6. 是否有方法可以檢視指定資料庫中的所有預存程序與預存函數?
A.4.7. 預存程序儲存在哪裡?
A.4.8. 是否有可能將預存程序或預存函數分組到套件中?
A.4.9. 預存程序可以呼叫另一個預存程序嗎?
A.4.10. 預存程序可以呼叫觸發程序嗎?
A.4.11. 預存程序可以存取資料表嗎?
A.4.12. 預存程序是否有陳述式可以引發應用程式錯誤?
A.4.13. 預存程序是否提供例外處理?
A.4.14. MySQL 預存常式可以傳回結果集嗎?
A.4.15. 預存程序是否支援 WITH RECOMPILE?
A.4.16. 是否有與使用 mod_plsql 作為 Apache 上的閘道直接與資料庫中的預存程序通訊的 MySQL 等效項?
A.4.17. 我可以將陣列作為輸入傳遞給預存程序嗎?
A.4.18. 我可以將游標作為 IN 參數傳遞給預存程序嗎?
A.4.19. 我可以將游標作為 OUT 參數從預存程序傳回嗎?
A.4.20. 我可以在預存常式中列印變數的值以進行偵錯嗎?
A.4.21. 我可以在預存程序內認可或回滾交易嗎?
A.4.22. MySQL 預存程序與函數是否可與複製搭配使用?
A.4.23. 在複製來源伺服器上建立的預存程序與函數是否會複製到複本?
A.4.24. 預存程序與函數內發生的動作是如何複製的?
A.4.25. 將預存程序與函數與複製搭配使用是否有特殊的安全性需求?
A.4.26. 複製預存程序與函數動作有哪些限制?
A.4.27. 先前的限制是否會影響 MySQL 執行時間點復原的能力?
A.4.28. 正在採取哪些措施來更正上述限制?

A.4.1.

MySQL 是否支援預存程序與函數?

是。MySQL 支援兩種預存常式類型,預存程序與預存函數。

A.4.2.

我可以在哪裡找到 MySQL 預存程序與預存函數的文件?

請參閱 第 27.2 節「使用預存常式」

A.4.3.

是否有 MySQL 預存程序的討論論壇?

是。請參閱 https://forums.mysql.com/list.php?98

A.4.4.

我可以在哪裡找到預存程序的 ANSI SQL 2003 規範?

很遺憾,官方規範並非免費提供 (ANSI 提供付費購買)。不過,有一些書籍,例如 Peter Gulutzan 和 Trudy Pelzer 的 SQL-99 Complete, Really,提供了標準的全面概述,包括預存程序的涵蓋範圍。

A.4.5.

如何管理預存常式?

為您的預存常式使用清晰的命名方案始終是一個好習慣。您可以使用 CREATE [FUNCTION|PROCEDURE]ALTER [FUNCTION|PROCEDURE]DROP [FUNCTION|PROCEDURE]SHOW CREATE [FUNCTION|PROCEDURE] 管理預存程序。您可以使用 INFORMATION_SCHEMA 資料庫中的 ROUTINES 資料表取得有關現有預存程序的資訊 (請參閱 第 28.3.30 節「INFORMATION_SCHEMA ROUTINES 資料表」)。

A.4.6.

是否有方法可以檢視指定資料庫中的所有預存程序與預存函數?

是。對於名為 dbname 的資料庫,請對 INFORMATION_SCHEMA.ROUTINES 資料表使用此查詢

SELECT ROUTINE_TYPE, ROUTINE_NAME
    FROM INFORMATION_SCHEMA.ROUTINES
    WHERE ROUTINE_SCHEMA='dbname';

如需詳細資訊,請參閱 第 28.3.30 節「INFORMATION_SCHEMA ROUTINES 資料表」

預存常式的主體可以使用 SHOW CREATE FUNCTION (用於預存函數) 或 SHOW CREATE PROCEDURE (用於預存程序) 檢視。如需詳細資訊,請參閱 第 15.7.7.10 節「SHOW CREATE PROCEDURE 陳述式」

A.4.7.

預存程序儲存在哪裡?

預存程序儲存在 mysql.routinesmysql.parameters 資料表中,這些資料表是資料字典的一部分。您無法直接存取這些資料表。相反地,請查詢 INFORMATION_SCHEMA ROUTINESPARAMETERS 資料表。請參閱 第 28.3.30 節「INFORMATION_SCHEMA ROUTINES 資料表」第 28.3.20 節「INFORMATION_SCHEMA PARAMETERS 資料表」

您也可以使用 SHOW CREATE FUNCTION 來取得關於儲存函數的資訊,並使用 SHOW CREATE PROCEDURE 來取得關於儲存程序的資訊。請參閱第 15.7.7.10 節,「SHOW CREATE PROCEDURE Statement」

A.4.8.

是否可以將儲存程序或儲存函數分組到套件中?

否。MySQL 不支援此功能。

A.4.9.

一個儲存程序可以呼叫另一個儲存程序嗎?

可以。

A.4.10.

一個儲存程序可以呼叫觸發器嗎?

儲存程序可以執行 SQL 陳述式,例如 UPDATE,這會導致觸發器啟動。

A.4.11.

儲存程序可以存取資料表嗎?

可以。儲存程序可以根據需要存取一個或多個資料表。

A.4.12.

儲存程序是否有陳述式可以引發應用程式錯誤?

有。MySQL 實作 SQL 標準的 SIGNALRESIGNAL 陳述式。請參閱第 15.6.7 節,「條件處理」

A.4.13.

儲存程序是否提供例外處理?

MySQL 根據 SQL 標準實作 HANDLER 定義。詳細資訊請參閱第 15.6.7.2 節,「DECLARE ... HANDLER Statement」

A.4.14.

MySQL 儲存常式可以傳回結果集嗎?

儲存程序可以,但儲存函數不行。如果您在儲存程序內部執行一般的 SELECT,結果集會直接傳回給用戶端。您需要使用 MySQL 4.1 (或更高版本) 的用戶端/伺服器協定才能使其正常運作。這表示,例如,在 PHP 中,您需要使用 mysqli 擴充功能,而不是舊的 mysql 擴充功能。

A.4.15.

儲存程序是否支援 WITH RECOMPILE

否。

A.4.16.

是否有 MySQL 等效的功能,可以使用 Apache 上的 mod_plsql 作為閘道直接與資料庫中的儲存程序通訊?

MySQL 中沒有等效的功能。

A.4.17.

我可以將陣列作為輸入傳遞給儲存程序嗎?

否。

A.4.18.

我可以將游標作為 IN 參數傳遞給儲存程序嗎?

游標僅在儲存程序內部可用。

A.4.19.

我可以從儲存程序傳回游標作為 OUT 參數嗎?

游標僅在儲存程序內部可用。但是,如果您沒有在 SELECT 上開啟游標,則結果會直接傳送到用戶端。您也可以使用 SELECT INTO 變數。請參閱第 15.2.13 節,「SELECT Statement」

A.4.20.

我可以在儲存常式中印出變數的值以進行偵錯嗎?

可以,您可以在儲存程序中執行此操作,但不能在儲存函數中執行。如果您在儲存程序內部執行一般的 SELECT,結果集會直接傳回給用戶端。您必須使用 MySQL 4.1 (或更高版本) 的用戶端/伺服器協定才能使其正常運作。這表示,例如,在 PHP 中,您需要使用 mysqli 擴充功能,而不是舊的 mysql 擴充功能。

A.4.21.

我可以在儲存程序內提交或回滾交易嗎?

可以。但是,您無法在儲存函數內執行交易操作。

A.4.22.

MySQL 儲存程序和函數是否適用於複製?

可以,在儲存程序和函數中執行的標準操作會從複製來源伺服器複製到副本。在第 27.7 節,「儲存程式二進位日誌」中詳細說明了一些限制。

A.4.23.

在複製來源伺服器上建立的儲存程序和函數是否會複製到副本?

可以,通過在複製來源伺服器上透過正常的 DDL 陳述式執行的儲存程序和函數建立會複製到副本,以便物件同時存在於兩個伺服器上。ALTERDROP 儲存程序和函數的陳述式也會被複製。

A.4.24.

如何在儲存程序和函數內發生的操作進行複製?

MySQL 記錄儲存程序中發生的每個 DML 事件,並將這些個別操作複製到副本。實際對執行儲存程序的呼叫不會被複製。

會變更資料的儲存函數會記錄為函數調用,而不是記錄為每個函數內部發生的 DML 事件。

A.4.25.

將儲存程序和函數與複製一起使用是否有特殊的安全性要求?

是。因為副本有權限執行從來源的二進位日誌讀取的任何陳述式,所以將儲存函數與複製一起使用時存在特殊的安全性限制。如果複製或一般二進位日誌 (用於時間點還原) 處於啟用狀態,則 MySQL DBA 有兩種安全性選項可供選擇

  1. 任何希望建立儲存函數的使用者都必須被授予 SUPER 權限。

  2. 或者,DBA 可以將 log_bin_trust_function_creators 系統變數設定為 1,這會啟用任何具有標準 CREATE ROUTINE 權限的人來建立儲存函數。

A.4.26.

複製儲存程序和函數操作有哪些限制?

嵌入在儲存程序中的不確定性 (隨機) 或基於時間的操作可能無法正確複製。就其本質而言,隨機產生的結果是不可預測的,並且無法精確重現;因此,複製到副本的隨機操作無法反映在來源上執行的操作。將儲存函數宣告為 DETERMINISTIC 或將 log_bin_trust_function_creators 系統變數設定為 0 會阻止調用產生隨機值的隨機操作。

此外,基於時間的操作無法在副本上重現,因為在儲存程序中這些操作的時機無法透過用於複製的二進位日誌重現。它僅記錄 DML 事件,並且不會考慮時機限制。

最後,在大型 DML 操作 (例如大量插入) 期間發生錯誤的非交易式資料表可能會遇到複製問題,因為來源可能會因 DML 活動而部分更新,但是由於發生的錯誤,不會對副本進行任何更新。一種解決方法是使用 IGNORE 關鍵字執行函數的 DML 操作,以便忽略來源上導致錯誤的更新,並將不會導致錯誤的更新複製到副本。

A.4.27.

上述限制是否會影響 MySQL 執行時間點還原的能力?

影響複製的相同限制也會影響時間點還原。

A.4.28.

正在採取哪些措施來修正上述限制?

您可以選擇基於陳述式的複製或基於列的複製。原始複製實作是基於基於陳述式的二進位日誌記錄。基於列的二進位日誌記錄解決了前面提到的限制。

還可以使用混合複製 (透過以 --binlog-format=mixed 啟動伺服器)。這種混合形式的複製知道是否可以安全地使用陳述式級複製,或者是否需要列級複製。

如需其他資訊,請參閱第 19.2.1 節,「複製格式」