Pregunta

Estoy intentando cambiar algunas consultas no modificables de utilizar entradas con parámetros, pero me he encontrado con un problema: ¿Cómo se formatea la entrada para las inserciones parametrizados

En la actualidad, las miradas código como el siguiente:

$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);

Una solución potencial (modificado de Cómo insertar una matriz en una sola MySQL declaración preparada w / PHP y PDO ) parece ser:

$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);
}

¿Hay una mejor manera de lograr una inserción masiva con consultas con parámetros?

¿Fue útil?

Solución

Bueno, usted tiene tres opciones.

  1. Construir una vez - Ejecuta múltiples. Básicamente, se prepara la inserción de una vez para cada fila, luego de bucle sobre las filas de ejecutarlo. Desde la extensión SQLSERVER no soporta la re-unión de una consulta después de que ha sido preparado (que tiene que hacer cortes sucios con referencias ) que puede no ser la mejor opción.

  2. Construir una vez - ejecutar una vez. Básicamente, se construye un inserto gigante como usted ha dicho en su ejemplo, se unen una vez, y ejecutarlo. Esto es un poco sucio y poco pierde algunos de los beneficios que prepararon consultas da. Sin embargo, debido a la exigencia de las referencias de la Opción 1, lo haría éste. Creo que es más limpio para construir una consulta gigante en lugar de depender de las referencias a variables.

  3. múltiple Build - Ejecuta múltiples. Básicamente, tomar el método que está haciendo, y modificarlo para volver a preparar la consulta cada tantos registros. Esto evita excesivamente grandes consultas y "lotes" las consultas. Así que algo como esto:

    $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);
    }
    

Cualquier método será suficiente. Haz lo que creas mejor se adapte a sus necesidades ...

Otros consejos

¿Por qué no sólo tiene que utilizar "preparar una vez, ejecutar múltiples" método. Sé que quiere que falle todo o todo el trabajo, pero no es exactamente difícil de manejar que las transacciones:

http://www.php.net/manual/en/pdo. begintransaction.php

http://www.php.net/manual/en/pdo. commit.php

http://www.php.net/manual/en/pdo. rollback.php

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top