Пакетные вставки и ошибка подготовленного запроса

Хорошо, поэтому мне нужно заполнить таблицу базы данных MS Access результатами запроса MySQL. Это совсем не сложно. У меня есть программа, написанная туда, где она копирует файл шаблона .mdb с временным именем и открывает его через odbc. Пока проблем нет.

Я заметил, что Access не поддерживает пакетную вставку (VALUES (foo, bar), (second, query), (third query)). Это означает, что мне нужно выполнять один запрос для каждой строки (потенциально есть сотни тысяч строк). Первоначальные тесты производительности показывают скорость около 900 вставок в секунду в Access. С нашими самыми большими наборами данных это может означать время выполнения в несколько минут (что не конец света, но, очевидно, чем быстрее, тем лучше).

Итак, я попробовал протестировать подготовленное заявление. Но я все время получаю ошибку (Warning: odbc_execute() [function.odbc-execute]: SQL error: [Microsoft][ODBC Microsoft Access Driver]COUNT field incorrect , SQL state 07001 in SQLExecute in D:\....php on line 30).

Вот код, который я использую (строка 30 - odbc_execute):

$sql = 'INSERT INTO table 
    ([field0], [field1], [field2], [field3], [field4], [field5]) 
    VALUES (?, ?, ?, ?, ?, ?)';
$stmt = odbc_prepare($conn, $sql);
for ($i = 200001; $i < 300001; $i++) {
    $a = array($i, "Field1 $", "Field2 $i", "Field3 $i", "Field4 $i", $i);
    odbc_execute($stmt, $a);
}

Итак, у меня двоякий вопрос. Во-первых, есть ли какое-нибудь представление о том, почему я получаю эту ошибку (я проверил, и число в массиве соответствует списку полей, который соответствует количеству маркеров параметра ?)? И во-вторых, стоит ли мне вообще возиться с этим или просто использовать прямые инструкции INSERT? Как я уже сказал, время не критично, но, если это возможно, я хотел бы сделать это время как можно меньше (опять же, я могу быть ограничен пропускной способностью диска, так как 900 операций в секунду уже высоки). .

Спасибо


person ircmaxell    schedule 18.06.2010    source источник


Ответы (2)


Вам нужно делать это строка за строкой? Почему бы не вставить сразу все данные?

Что такое лучший способ синхронизировать данные между MS Access и MySQL?

person Fionnuala    schedule 18.06.2010
comment
Вау! Вы можете сделать это? Теперь мой запрос MySQL довольно сложен. Нужно ли мне писать это в синтаксисе Access? Или мне написать его в синтаксисе MySQL, но выполнить через Access? Я определенно не хочу делать это строка за строкой (если нужно, хорошо), но запрос, который генерирует результаты, имеет от 2 до 8 объединений и различное количество предложений where (и группирование по предложению ) обман ... Даже все равно это выглядит интересным маршрутом ... - person ircmaxell; 19.06.2010
comment
Вы должны иметь возможность выполнять сквозной запрос в Access или использовать ADO и строку подключения MySQL, и в этом случае вы можете обратиться к Access с IN. Я не уверен, с чего вы хотите начать, поэтому немного сложно дать более подробную информацию. - person Fionnuala; 19.06.2010
comment
Я немного поиграюсь с этим в понедельник, и если у меня возникнут проблемы, задайте новый вопрос ... Спасибо! - person ircmaxell; 19.06.2010
comment
Насколько я помню, MySQL не может получить доступ к данным ODBC, кроме как в другой базе данных MySQL, поэтому вам нужно будет создать связанную таблицу ODBC (с целевой таблицей MySQL) в Access и указать Access, чтобы он запускал SQL через ODBC. - person David-W-Fenton; 19.06.2010
comment
Это сложный запрос, поэтому я не думаю, что Access - лучшее место для его выполнения, однако работать со строками подключения MySQL в Access несложно. - person Fionnuala; 19.06.2010
comment
Я смотрел на тег PHP и предполагал, что языком программирования является PHP, и поэтому у вас будет источник данных MySQL, где вы будете делать все напрямую с MySQL, а затем у вас будет источник данных Jet / ACE с связанная таблица ODBC, указывающая на целевую таблицу MySQL, и вы должны использовать ODBC в источнике данных Jet / ACE для выполнения вставки, которая берет данные из связанной таблицы (из MySQL) и вставляет их в Jet / ACE стол. Разве это не правильный сценарий? - person David-W-Fenton; 20.06.2010

Предоставляет ли PHP возможность просмотреть инструкцию INSERT, которую вы выполняете после замены параметра? Я думаю, что вы можете не получать кавычки вокруг текстовых значений в вашем списке VALUES. Без кавычек ядро ​​базы данных Jet будет интерпретировать «Поле1 200001» как два значения, а не как одно.

Кроме того, я не знаю PHP, но должен ли второй член вашего массива быть «Field1 $ i» вместо «Field1 $»?

Можете ли вы выполнить этот оператор из PHP? А это работает?

INSERT INTO table 
    ([field0], [field1], [field2], [field3], [field4], [field5]) 
VALUES (
    200001,
    'Field1 200001',
    'Field2 200001',
    'Field3 200001',
    'Field4 200001',
    200001);

Как насчет этого?

$sql = 'INSERT INTO table 
    ([field0], [field1], [field2], [field3], [field4], [field5]) 
    VALUES (?, "?", "?", "?", "?", ?)';
person HansUp    schedule 18.06.2010
comment
Не то, чтобы я нашел. Поскольку он записывается в локальный файл, я даже не могу его сделать (что я знаю) ... - person ircmaxell; 18.06.2010
comment
В этом случае я подозреваю, что операторы INSERT проблемы отправляются в Jet без текстовых значений в кавычках. К сожалению, я понятия не имел, как исправить это с помощью PHP. - person HansUp; 18.06.2010
comment
Добавление кавычек вокруг ? в операторе значений показывает ту же ошибку, что и раньше ... Я не уверен, что происходит. Есть какие-нибудь советы по другому вопросу (стоит ли мне беспокоиться, или ставки вставки будут такими же)? - person ircmaxell; 18.06.2010
comment
Нет, я просто сосредоточился на том, чтобы все заработало. Боюсь, что я застрял. Жаль, что вы не можете сделать это из Access; было бы просто связать вашу таблицу MySql и использовать ее для выполнения вставки в таблицу Jet. - person HansUp; 18.06.2010
comment
Я посмотрел документацию PHP для odbc_prepare. В нем говорится об использовании с хранимыми процедурами. Поскольку Jet не поддерживает то, что мы обычно называем хранимыми процедурами, я сомневаюсь, что odbc_prepare здесь может быть полезен. Поскольку это одно предложение, которое я предложил, сработало, создайте свой оператор и выполняйте его для каждой строки. Я предполагаю, что время, необходимое для вставки Jet, а не время, необходимое PHP для создания каждой строки оператора INSERT, будет вашим узким местом. - person HansUp; 18.06.2010
comment
Ну, я пришел из MySQL фона. А в MySQL время синтаксического анализа TCP и SQL обычно является вашим узким местом. Таким образом, если вы можете сгруппировать 10 вставок в 1 оператор SQL, он обычно завершается примерно в 10% случаев. Итак, поскольку подготовленные запросы могут убрать этап синтаксического анализа, я решил, что кое-что получу. Но я думаю, что нет ... - person ircmaxell; 19.06.2010
comment
Что ж, я собираюсь в понедельник поиграть с еще несколькими вариантами (включая Remou) и посмотреть, к чему это приведет. Возможно, я также попробую RAM-диск (я мог бы сделать это и в производственной среде ... Просто создайте файл в RAM, а затем скопируйте на диск, когда он закончится ... интересно ...) - person ircmaxell; 19.06.2010