13.5 被準備SQL語句的語法
05-18
13.5 被準備SQL語句的語法
預處理語句的SQL語法不能以嵌套方式使用。 也就是說,傳遞給PREPARE的語句本身不能是PREPARE,EXECUTE或DEALLOCATE PREPARE語句。預處理語句的SQL語法與使用預處理語句API調用截然不同。 例如,不能使用mysql_stmt_prepare()C API函數來準備PREPARE,EXECUTE或DEALLOCATE PREPARE語句。預編譯語句的SQL語法可以在存儲過程中使用,但不能在存儲函數或觸發器中使用。 但是,游標不能用於使用PREPARE和EXECUTE準備並執行的動態語句。 游標創建時檢查游標的語句,因此語句不能是動態的。預準備語句的SQL語法不支持多語句(即,由單個字元串中的多個語句分隔;字元)。要編寫使用CALL SQL語句執行包含預處理語句的存儲過程的C程序,必須啟用CLIENT_MULTI_RESULTS標誌。 這是因為除了過程中執行的語句可能返回的任何結果集外,每個CALL都會返回一個結果來指示調用狀態。在調用mysql_real_connect()時,可以啟用CLIENT_MULTI_RESULTS,或者顯式地通過傳遞CLIENT_MULTI_RESULTS標誌本身,或者通過傳遞CLIENT_MULTI_STATEMENTS(它也啟用CLIENT_MULTI_RESULTS)來隱式調用。13.5.1 PREPARE 語法PREPARE stmt_name FROM preparable_stmtPREPARE語句準備一條SQL語句並為其指定一個名稱stmt_name,稍後通過該名稱來引用該語句。 準備好的語句使用EXECUTE執行和DEALLOCATE PREPARE釋放。語句名稱不區分大小寫。 preparable_stmt是一個字元串文字或包含用戶變數的SQL語句文本。 文本必須代表單一語句,而不是多個語句。 在語句中,? 字元可以用作參數標記來指示稍後在執行時將數據值綁定到查詢的位置。 這個? 字元不應包含在引號內,即使您打算將它們綁定到字元串值。 參數標記只能用於出現數據值的地方,而不能用於SQL關鍵字,標識符等等。如果具有給定名稱的準備好的語句已經存在,則在準備新語句之前隱式地釋放它。 這意味著如果新語句包含錯誤並且無法準備,並會返回錯誤,並且不存在具有給定名稱的語句。準備好的語句的範圍是創建它的會話,其中包含以下幾個含義:
推薦閱讀:
來自專欄 mysql 官方文檔翻譯
參考官方文檔:
https://dev.mysql.com/doc/refman/5.7/en/sql-syntax-prepared-statements.htmlMySQL 5.7提供了對伺服器端預處理語句的支持。 此支持利用高效的客戶端/伺服器二進位協議。 使用準備好的語句和佔位符來獲取參數值具有以下好處:- 每次執行時解析語句的開銷都較小。 通常情況下,資料庫應用程序處理大量幾乎相同的語句,只對WHERE查詢和刪除,SET更新和VALUES等子句中的文字或變數值進行更改。
- 防止SQL注入攻擊。 參數值可以包含未轉義的SQL引號和分隔符字元。
- 當沒有可用的編程介面時,您可以使用它。
- 您可以從任何可以將SQL語句發送到要執行的伺服器的程序中使用它,例如mysql客戶端程序。
- 即使客戶端使用舊版本的客戶端庫,只要連接到運行MySQL 4.1或更高版本的伺服器即可使用它。
準備好的語句的SQL語法旨在用於以下情況:
- 在編寫代碼之前,測試預準備語句在應用程序中的工作方式
- 當您無法訪問支持它們的編程API時使用預準備語句。
- 使用預準備語句互動式解決應用程序問題。
- 創建一個測試用例,用準備好的語句重現問題,以便您可以提交錯誤報告。
- PREPARE準備一份執行語句
- EXECUTE執行一個準備好的語句
- DEALLOCATE PREPARE發布一個準備好的語句
mysql> SET @b = 4;
mysql> EXECUTE stmt1 USING @a, @b;+------------+ | hypotenuse | +------------+ | 5 |+------------+mysql> DEALLOCATE PREPARE stmt1;第二個例子是類似的,但將語句的文本作為用戶變數提供:mysql> SET @s =SELECT SQRT(POW(?,2) + POW(?,2)) AS hypotenuse;
mysql> PREPARE stmt2 FROM @s; mysql> SET @a = 6; mysql> SET @b = 8; mysql> EXECUTE stmt2 USING @a, @b;+------------+| hypotenuse |+------------+ | 10 | +------------+mysql> DEALLOCATE PREPARE stmt2;
下面是一個附加示例,演示如何選擇要在運行時執行查詢的表,方法是將表的名稱存儲為用戶變數:mysql> USE test; mysql> CREATE TABLE t1 (a INT NOT NULL); mysql> INSERT INTO t1 VALUES (4), (8), (11), (32), (80); mysql> SET @table = t1; mysql> SET @s = CONCAT(SELECT * FROM , @table); mysql> PREPARE stmt3 FROM @s;mysql> EXECUTE stmt3;
+----+| a | +----+ | 4 | | 8 | | 11 || 32 | | 80 |+----+mysql> DEALLOCATE PREPARE stmt3;
準備好的聲明特定於創建它的會話。 如果您在不取消分配先前準備好的語句的情況下終止會話,則伺服器會自動解除分配它。準備好的聲明也是全球會議。 如果您在已存儲的常式中創建預準備語句,則在存儲的常式結束時不會釋放它。為了防止同時創建的準備語句過多,請設置max_prepared_stmt_count系統變數。 要防止使用預準備語句,請將該值設置為0。準備好的語句中允許的SQL語法從MySQL 5.7.2開始,為了遵守聲明診斷語句不可預備的SQL標準,MySQL不支持以下為預處理語句:
- SHOW WARNINGS, SHOW COUNT(*) WARNINGS
- SHOW ERRORS, SHOW COUNT(*) ERRORS
- 包含對warning_count或error_count系統變數的任何引用的語句。
- 在一個會話中創建的預備語句不適用於其他會話。
- 當會話結束時,無論是正常還是異常,其已準備好的語句都不再存在。 如果啟用自動重新連接,則不會通知客戶端連接丟失。 出於這個原因,客戶可能希望禁用自動重新連接。
- 在存儲程序中創建的預備語句在程序執行完成後繼續存在,並且可以稍後在程序之外執行。
- 在存儲的程序上下文中準備的語句不能引用存儲過程或函數參數或局部變數,因為它們在程序結束時超出範圍,並且將在程序之後稍後執行的語句不可用。 作為一種解決方法,請參閱用戶定義的變數,該變數也具有會話範圍;
推薦閱讀:
※SequoiaDB擴容介紹與最佳實踐
※MySQL資料庫應用總結(十)—MySQL資料庫數據的插入、更新和刪除操作
※sql中插入中文問題
※學習SQL【4】-聚合與排序
※Linux安裝MySQL資料庫操作手冊