2011-01-11 117 views
10

我試圖切換一些硬編碼查詢以使用參數化輸入,但我遇到了一個問題:如何格式化參數化批量插入的輸入?批量參數化插入

目前,代碼如下:

$data_insert = "INSERT INTO my_table (field1, field2, field3) "; 
$multiple_inserts = false; 
while ($my_condition) 
{ 
    if ($multiple_inserts) 
    { 
     $data_insert .= " UNION ALL "; 
    } 

    $data_insert .= " SELECT myvalue1, myvalue2, myvalue3 "; 
} 

$recordset = sqlsrv_query($my_connection, $data_insert); 

的潛在解決方案(從How to insert an array into a single MySQL Prepared statement w/ PHP and PDO修改)似乎是:

$sql = 'INSERT INTO my_table (field1, field2, field3) VALUES '; 
$parameters = array(); 
$data = array(); 
while ($my_condition) 
{ 
    $parameters[] = '(?, ?, ?)'; 
    $data[] = value1; 
    $data[] = value2; 
    $data[] = value3; 
} 

if (!empty($parameters)) 
{ 
    $sql .= implode(', ', $parameters); 
    $stmt = sqlsrv_prepare($my_connection, $sql, $data); 
    sqlsrv_execute($stmt); 
} 

有沒有更好的方式來完成與參數化批量插入疑問?

+1

一個潛在的解決方案,具體到預處理語句,是「單獨準備,多次執行」 – 2011-01-11 15:38:01

+0

我試圖避免這樣做,以限制事務處理的需要。如果任何一個插入失敗,整個操作將失敗。 – 2011-01-11 15:50:09

+0

什麼交易? – 2011-01-11 15:59:29

回答

5

那麼,你有三個選擇。

  1. 構建一次 - 執行多次。基本上,你爲一行準備插入一次,然後遍歷執行它的行。由於SQLSERVER擴展在準備完成後不支持重新綁定查詢(您需要執行dirty hacks with references),這可能不是最佳選擇。

  2. 構建一次 - 執行一次。基本上,您可以像在示例中所說的那樣構建一個巨大的插入,然後綁定一次,然後執行它。這有點髒,錯過了準備好的查詢給出的一些好處。但是,由於要求引用選項1,我會做這一個。我認爲建立一個巨大的查詢比取決於變量引用更清晰。

  3. 構建多個 - 執行多個。基本上,採取你正在做的方法,並調整它重新準備查詢每一個這麼多的記錄。這可以防止過大的查詢和「批量」查詢。因此,像這樣:

    $sql = 'INSERT INTO my_table (field1, field2, field3) VALUES '; 
    $parameters = array(); 
    $data = array(); 
    
    $execute = function($params, $data) use ($my_connection, $sql) { 
        $query = $sql . implode(', ', $parameters); 
        $stmt = sqlsrv_prepare($my_connection, $query, $data); 
        sqlsrv_execute($stmt); 
    } 
    
    while ($my_condition) { 
        $parameters[] = '(?, ?, ?)'; 
        $data[] = value1; 
        $data[] = value2; 
        $data[] = value3; 
        if (count($parameters) % 25 == 0) { 
         //Flush every 25 records 
         $execute($parameters, $data); 
         $parameters = array(); 
         $data = array(); 
        } 
    } 
    if (!empty($parameters)) { 
        $execute($sql, $parameters, $data); 
    } 
    

兩種方法就足夠了。做你認爲最適合你的要求...