PDO之繫結變數

2021-07-24 19:57:42 字數 1721 閱讀 4316

用繫結變數 sql時,客戶端向伺服器傳送了乙個 sql語句的原型,伺服器端收到了這個 sql語句「框架」後,經過解析、預處理、生成並儲存該部分的執行計畫,然後返回給客戶端乙個控制代碼,之後每次執行這類查詢,都應使用這個控制代碼,之後的每次查詢,只需要傳送某些變數的值就可以了。

這樣看來,當一次會話中要執行多次類似的sql時,使用繫結變數 sql是更高效的,因為在 mysql伺服器端,只需要解析一次 sql語句了,也能省去部分執行計畫的生成。同時,每次查詢都只需要傳送某些變數的值,相比於每次使用完整的 sql語句,減少了網路開銷。

同時,繫結變數 sql也更加安全,無需在應用程式中對使用者輸入進行轉義了,mysql伺服器將每次傳過來的值進行轉義,這也比在應用程式轉義更加安全。

注意,使用pdo的繫結變數時,一定要將pdo::attr_emulate_prepares設定為 false,否則只是在客戶端中模擬繫結變數,一系列操作包括轉義,都是在客戶端完成的,每次傳送給 mysql伺服器的都只是乙個普通的查詢。

$dsn = 'mysql:host=localhost;dbname=sakila';

$username = 'root';

$passwd = 'root';

$pdo = new pdo( $dsn, $username, $passwd, [

pdo::attr_emulate_prepares => false,

pdo::mysql_attr_init_command => 'set names utf8'

]);$sql = "select * from address where city_id = :city_id ";

$stmt = $pdo->prepare($sql);

$stmt->bindvalue(":city_id", 300);

$stmt->execute();

$stmt->bindvalue(":city_id", "' or 1 = 1#");

$stmt->execute();

// 未展示 bindparam 用法

在mysql命令列中輸入 set global general_log = 『on』 ,就可以在日誌中記錄所有執行過的 sql了。執行上述**,myssql 執行過程為:

connect root@localhost on sakila using tcp/ip

prepare select * from address where city_id = ?

execute

select * from address where city_id = '300'

execute

select * from address where city_id = '\' or 1 = 1#'

close stmt

quit

如果不將設為false,那麼 mysql伺服器執行過程將是:

connect root@localhost on sakila using tcp/ip

query select * from address where city_id = '300'

query select * from address where city_id = '\'

or1 = 1#'

quit

完全沒有用到 prepare 和 execute。

資料庫開發之繫結變數

對於每個程式開發人員來說,資料庫的知識都是或多或少的了解些,都能編寫一些sql語句,即使不會也可以使用一些工具來生成sql語句,因此資料庫在很多時候被認為是沒有必要研究的。隨著系統使用人數增加,系統也遇到了瓶頸,於是開發人員高呼 給我記憶體與cpu,系統將會faster 可是作為盈利性企業,投入與回...

pl sql 繫結變數

在oracle 中,對於乙個提交的sql語句,存在兩種可選的解析過程,一種叫做硬解析,一種叫做軟解析.乙個硬解析需要經解析,制定執行路徑,優化訪問計畫等許多的步驟.硬解析不僅僅耗費大量的cpu,更重要的是會佔據重要的們閂 latch 資源,嚴重的影響系統的規模的擴大 即限制了系統的並發行 而且引起的...

繫結變數窺測

事物都存在兩面性,繫結變數對大多數oltp處理是適用的,但是也有例外。比如在where條件中的字段是 傾斜字段 的時候。傾斜字段 指該列中的絕大多數的值都是相同的,比如一張人口調查表,其中 民族 這列,90 以上都是漢族。那麼如果乙個sql語句要查詢30歲的漢族人口有多少,那 民族 這列必然要被放在...