MySQL 區分伺服器系統變數、區域常式變數與工作階段使用者變數。它們的範圍與評估規則不同,因此不應互換使用。
系統與使用者變數 #
系統變數使用 @@,可能具有全域、工作階段或兩者範圍:
SELECT @@GLOBAL.transaction_isolation, @@SESSION.sql_mode;
SET SESSION sql_safe_updates = 1;變更全域變數會影響新的工作階段(當該變數也具有工作階段範圍時);它不是變更現有連線交易原則的方法。動態變數可在執行時變更,而唯讀變數需要啟動設定。SET PERSIST 會變更執行期全域值並寫入 mysqld-auto.cnf;SET PERSIST_ONLY 會寫入持久化值,但不變更執行期狀態。使用任一形式前,請確認變數可以持久化,並讓檔案擁有權由伺服器維持,不要編輯該產生的檔案。
使用者變數使用 @name,以連線為區域,且沒有宣告型別:
SET @minimum_total = 100;
SELECT id FROM orders WHERE total >= @minimum_total;不要在同一運算式或查詢中指派並讀取相同的使用者變數,以模擬程序式評估。MySQL 不保證能使這類查詢可靠的評估順序。請改用視窗函數、通用表運算式、儲存程式區域變數或應用程式程式碼。值的型別會在指派時衍生,而預備陳述式參照會保留陳述式首次預備時建立的變數型別。需要的 SQL 型別屬於契約時,請明確使用 CAST。
預備陳述式 #
用戶端函式庫預備陳述式會將資料與 SQL 語法分開繫結,應是應用程式查詢的預設方式。它們能防止值被解讀為注入的 SQL,並讓伺服器分開剖析陳述式結構。
伺服器端 SQL 預備陳述式遵循以連線為範圍的生命週期:PREPARE 會剖析一個陳述式,EXECUTE 會重複執行它,而 DEALLOCATE PREPARE 會釋放它。同名的第二次 PREPARE 會先解除配置舊陳述式。工作階段結束時,預備陳述式也會被捨棄。當識別碼必須組合時,它們適合用於管理用途的動態 SQL。參數標記會繫結資料值,而不是識別碼、關鍵字或 SQL 片段:
SET @sql = 'SELECT id FROM orders WHERE customer_id = ?';
PREPARE stmt FROM @sql;
SET @customer_id = 42;
EXECUTE stmt USING @customer_id;
DEALLOCATE PREPARE stmt;將任何動態識別碼串接至 SQL 前,請先驗證或使用允許清單。參數標記不能在每個文法位置代表任意運算式,而預備陳述式數量受 max_prepared_stmt_count 限制。釋放短生命週期的管理陳述式,並讓應用程式驅動程式管理自己的預備陳述式控制代碼。
評論
在 GitHub 上閱讀或評論(發表評論需要登入)