Эффективный способ массовой вставки в файлы Dbase (.dbf) - PullRequest
5 голосов
/ 09 марта 2011

В настоящее время я использую OleDBCommand.ExecuteNonQuery (неоднократно вызывается) для вставки до 350 000 строк в файлы dbase (* .dbf) одновременно из источника DataTable. Я повторно использую объект OleDbCommand и OleDbParameters, чтобы установить значения, которые будут вставляться каждый раз, когда вызывается оператор вставки. Вставка 350 000 строк в настоящее время занимает около 45 минут.

Есть ли более эффективный способ сделать это? Существует ли что-то похожее на параметр «Массовая вставка», используемый в SQL Server, для файлов Dbase (* .dbf)?

Ответы [ 3 ]

2 голосов
/ 27 марта 2011

Исправлена ​​проблема путем изменения драйвера OleDB с Jet на vfpoledb. Это сократило общее время с 40 минут до 8 минут.

Драйвер vfpoledb и модуль слияния были загружены по ссылке ниже

http://www.microsoft.com/downloads/en/details.aspx?FamilyID=e1a87d8f-2d58-491f-a0fa-95a3289c5fd4

Спасибо за вашу помощь.

1 голос
/ 10 марта 2011

По вашим другим отзывам, являющимся SQL Server, SQL Server имеет возможности массовой загрузки.

Я бы создал хранимую процедуру, которая ожидает имя файла, который вы пытаетесь загрузить, и сделал бы все это там.Подобным образом, как я описал в случае с Foxpro, я создал бы временную таблицу (если необходимо для более быстрого предварительного заполнения данных) в SQL, которая соответствует столбцу, который должен быть импортирован, а затем импортировал в него.Попав в временную структуру, вы можете выполнить любую необходимую вам очистку данных.Когда все будет готово, вставьте его в основную таблицу в качестве выбора из таблицы временного импорта.

1 голос
/ 09 марта 2011

Если это расширения файлов .dbf и .cdx для данной таблицы, то, вероятно, это таблица Visual FoxPro, а не конкретно "dBase".

Если это так, VFP допускает "добавление из"команда выглядит примерно так ...

use (yourTable) добавляется из SomeFile.txt типа csv

, однако принимаются и другие форматы файлов импорта, такие как XLS, DELIMITED и другие.

Если это так, VFP также допускает команду ExecScript (), в которой вы можете создать строку, представляющую команды, которые должны быть выполнены, а затем запускает их как обычный PRG.Не все в библиотеке команд VFP доступно, но достаточно для того, что вам нужно.Вам нужно будет использовать провайдера VFP OleDb, установите соединение, как вы уже делаете.Затем создайте сценарий, похожий на ...

String script = "[USE YourTable SHARED] +chr(13)+chr(10)+ " 
    + "[APPEND FROM OtherTextSource TYPE CSV]";

THEN, выполните команду

YourConnection.ExecuteNonQuery( "ExecScript( " + script + " ) " );

Если структура входящего источника не совпадает с ожидаемой таблицей, вы можететакже создайте временную таблицу (курсор в VFP) со столбцами в том порядке, в котором они соответствуют источнику ввода, но имеют те же имена столбцов и типы данных, что и в таблице FINAL, в которую они будут извлечены, а затем используйте ее в качестве основы для добавления в finalтаблица ... Курсоры в VFP самоочищаются .. т.е. они являются временными файлами, которые сразу стираются при закрытии, и закрытие соединения освобождает их ... например,

String script = "[create cursor C_SomeTempArea( FinalCol1 c(20), "
              +    "FinalCol7 int, AnotherCol c(5) )] +chr(13)+chr(10)+ " 
              + "[APPEND FROM OtherTextSource TYPE CSV] +chr(13)+chr(10)+ " 
              + "[SELECT 0] +chr(13)+chr(10)+ " 
              + "[USE YourFinalTable] +chr(13)+chr(10)+ " 
              + "[Append from C_SomeTempArea]"

THEN, выдайте

YourConnection.ExecuteNonQuery( "ExecScript( " + script + " ) " );

РЕДАКТИРОВАТЬ - из обратной связи

Поскольку он основан на DBASE, я бы тогда по-прежнему рассмотрел возможность загрузки VFP OleDb Manager, выполняя соединение с этим с помощью вышеупомянутого, но вместо использованиясвою таблицу в конце и добавление к ней, измените только конечную часть ...

удалите

+ "[USE YourFinalTable] +chr(13)+chr(10)+ " 
+ "[Append from C_SomeTempArea]"

и вставьте int

   + "[COPY TO TEMPImport TYPE FOXPLUS]"

Копировать в типFOXPLUS поставит этов физическую таблицу на диске, которую DBASE распознает через провайдера OleDb.Затем, возвращаясь к соединению с вашей базой данных, я бы сделал

insert into (YourTable) select * from TempImport

Да, это связано с новым провайдером OleDb, но производительность VFP кричит при выполнении такого импорта, не нарушая пот ...

...