簡體   English   中英

對不同的查詢使用相同的 mysqli 准備語句?

[英]Use same mysqli prepared statement for different queries?

在一些測試中; 一個小問題突然出現。 當我通常編碼數據庫更新時; 我通常通過我在 PHP 中編碼的回調來做到這一點; 我只是將給定的mysqli 連接 object作為 function 參數傳遞給它。 在同一個連接上執行例如三個查詢的所有查詢被證明比為給定查詢序列的每個查詢關閉和重新打開數據庫連接要快得多。 這也很容易與 SQL 事務一起使用,連接可以毫無問題地傳遞給回調。

我的問題是; 你也可以用准備好的語句對象來做到這一點嗎? 我的意思是,考慮到我們成功建立了一個$conn object,代表 mysqli 連接,這樣的東西合法嗎?

function select_users( $users_id, $stmt ) {

  $sql = "SELECT username FROM users where ID = ?";

  mysqli_stmt_prepare( $stmt, $sql );
  mysqli_stmt_bind_param( $stmt, "i", $users_id );
  mysqli_stmt_execute( $stmt );

  return mysqli_stmt_get_result( $stmt );

}

function select_labels( $artist, $stmt ) {

  $sql = "SELECT label FROM labels where artist = ?";

  mysqli_stmt_prepare( $stmt, $sql );
  mysqli_stmt_bind_param( $stmt, "s", $artist );
  mysqli_stmt_execute( $stmt );

  return mysqli_stmt_get_result( $stmt );

}

$stmt = mysqli_stmt_init( $conn );

$users = select_users( 1, $stmt );
$rappers = select_labels( "rapperxyz", $stmt );

或者這是不好的做法; 你應該使用:

$stmt_users = mysqli_stmt_init( $conn );
$stmt_rappers = mysqli_stmt_init( $conn );

$users = select_users( 1, $stmt_users );
$rappers = select_labels( "rapperxyz", $stmt_rappers );

測試期間; 我注意到通過使用單個語句 object 傳遞回調的方法適用於服務器調用,我通過連續 4 個相應的回調調用 4 個不太復雜的數據庫查詢。

然而,當我使用類似 10 個不同的查詢進行服務器調用時,有時(是的,只是有時;對於在不同執行中使用的幾乎相同的數據;所以這對我來說似乎是奇怪的行為)我收到錯誤"Commands out of sync; you can't run this command now"以及我從未遇到過的其他一些奇怪的錯誤,例如變量數量與參數數量不匹配; 盡管他們在檢查完所有內容后都做得很好。 經過一番研究,我發現解決這個問題的唯一方法確實是為每個回調使用不同的語句對象。 所以,我只是想知道; 您實際上是否應該始終使用一個准備好的語句 object 進行一個查詢,然后您可以連續執行 N 次?

是的。

“命令不同步”錯誤是因為 MySQL 協議不像 http。 您無法隨時發送請求。 在服務器端(即 mysqld)有 state ,它期待一定的請求序列。 這就是所謂的有狀態協議。

與 ftp 之類的協議進行比較。 您可以在 ftp 客戶端中執行ls ,但您返回的文件列表取決於當前工作目錄。 如果您在應用程序中的多個功能之間共享 ftp 客戶端連接,您不知道另一個 function 沒有更改工作目錄。 所以你不能確定你從ls得到的文件列表代表你認為你所在的目錄。

在 MySQL 中,服務器端也有 state。 您一次只能打開一項交易。 您一次只能執行一個查詢。 MySQL 客戶端不允許您執行新查詢,其中仍有要從正在進行的查詢中獲取的行。 請參閱 MySQL 文檔中有關常見錯誤的命令不同步

因此,如果您將語句句柄傳遞給某些回調函數,那么 function 怎么知道執行該語句是安全的?

IMO,使用語句的唯一安全方法是立即使用它。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM