2011-01-11 82 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); 
    } 
    

两种方法就足够了。做你认为最适合你的要求...