Вопрос

Я пытаюсь переключить некоторые жесткие запросы на использование параметризованных входов, но я столкнулся с проблемой: Как вы отформатируете вход для параметризованных насыпных вложений?

В настоящее время код выглядит так:

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

Потенциальное решение (модифицировано из Как вставить массив в одно подготовленное оператор MySQL W / PHP и 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. Построить один раз - выполнить несколько. По сути, вы приготовите вставку один раз для одной строки, а затем петля по ряду, выполняющими его. Поскольку расширение 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);
    }
    

Любой способ будет достаточно. Делайте то, что вы думаете, подходит для ваших требований лучше всего ...

Другие советы

Почему бы не просто использовать «Подготовьте один раз, выполнить несколько» метод. Я знаю, что вы хотите, чтобы все могли либо все терпеть неудачу, либо все работать, но не совсем трудно справиться с транзакциями:

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.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top