批量参数化插入

Zac*_*and 10 php sql bulkinsert parameterized-query

我正在尝试切换一些硬编码查询以使用参数化输入,但我遇到了一个问题:如何格式化参数化批量插入的输入?

目前,代码如下所示:

$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);
Run Code Online (Sandbox Code Playgroud)

一个潜在的解决方案(从如何将数组插入到PHP和PDO的单个MySQL Prepared语句中修改)似乎是:

$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);
}
Run Code Online (Sandbox Code Playgroud)

有没有更好的方法来完成带参数化查询的批量插入?

irc*_*ell 6

嗯,你有三个选择.

  1. 构建一次 - 执行多次.基本上,您为一行准备插入一次,然后遍历执行它的行.由于SQLSERVER扩展在准备后不支持重新绑定查询(您需要使用引用进行脏攻击),这可能不是最佳选择.

  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);
    }
    
    Run Code Online (Sandbox Code Playgroud)

任何一种方法都足够了.做你认为最符合你要求的......