Domanda

Sto cercando di cambiare alcune query hard-coded per utilizzare gli ingressi con parametri, ma ho incontrato un problema:? Come si formatta l'ingresso per gli inserimenti di massa con parametri

Al momento, gli sguardi codice come questo:

$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 possibile soluzione (modificato da Come inserire un array in un unico MySQL dichiarazione preparata w / PHP e DOP ) sembra essere:

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

C'è un modo migliore per realizzare un inserimento di massa con le query con parametri?

È stato utile?

Soluzione

Bene, avete tre opzioni.

  1. Costruire una volta - esecuzione multipla. In sostanza, si prepara l'inserto volta per ogni riga, quindi ciclo sulle righe eseguirlo. Dal momento che l'estensione SQLSERVER non supporta ri-binding di una query dopo che è stato preparato (è necessario fare hack sporco con riferimenti ) che potrebbe non essere l'opzione migliore.

  2. Costruire una volta - eseguire una sola volta. In sostanza, si costruisce un inserto gigante come hai detto nel tuo esempio, si legano una volta, ed eseguirlo. Questo è un po 'sporca e manca alcuni dei vantaggi che hanno preparato le query dà. Tuttavia, a causa del requisito di riferimenti da Opzione 1, farei questo. Penso che sia più pulita di costruire una query gigante piuttosto che dipendono da riferimenti alle variabili.

  3. costruire più - eseguire più. In sostanza, prendere il metodo che si sta facendo, e modificarlo per ri-preparare la query ogni tanti record. Questo impedisce eccessivamente grande query e "lotti" le domande. Quindi, qualcosa di simile a questo:

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

Entrambi i metodi sufficiente. Fai quello che pensi che si adatta alle vostre esigenze meglio ...

Altri suggerimenti

Perché non basta usare "preparare una volta, eseguire più" metodo. So che vuoi che sia tutto fallire o tutto il lavoro, ma non è esattamente difficile da gestire che, con le operazioni:

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

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top