Форум: "Базы";
Текущий архив: 2004.07.04;
Скачать: [xml.tar.bz2];
ВнизСкопировать массив из MSAccess в вариантный массив Найти похожие ветки
← →
apollo © (2004-06-04 14:41) [0]Возможно-ли скопировать целиком базу MSAccess (не по записям, а целиком как таблицу) в вариантный массив в Delphi (в переменную типа OLEVariant), по аналогии как это можно сделать с диапазоном ячеек MS Excel? Есть мысль, что возможно это можно сделать через буфер, но как именно - не знаю, еще лучше если есть другой способ сделать это напрямую.
← →
Курдль (2004-06-04 14:53) [1]А зачем, если не секрет? Чем вызвана такая любовь к вариантным массивам?
(Про любовь к MSAccess я уже даже не спрашиваю)
← →
apollo © (2004-06-04 15:17) [2]Мне с регионов (более 40) присылают ежемесячные отчеты в виде файликов mdb количество полей около 250, записей от нескольких тысяч до нескольких десятков. Я это все собираю в одну базу (не Access"овскую уже разумеется). Так вот переносить по обычной технологии (перебирая по одной записи в исходной таблице вставляя в итоговую) - уходит полдня и более (при переносе еще кое-какая логика задействована, поэтому внешние программы быстрого переноса на подходят). Быстрее будет засунуть в вариантный массив (оперативка позволяет) обработать там (обращения к таким массивам все равно быстрее чем в базу данных) и засунуть уже обработанные данные в итоговую таблицу. Почему вспомнил буфер - по аналогии: открываем таблицу в Access, выделяем все записи, говорим копировать, а потом великолепно можем их вставить куда-нибудь, например, в Excell. А вот как программно мне выделить и скопировать все записи и делается это гораздо быстрее чем построчный перенос данных.
← →
Курдль (2004-06-04 15:21) [3]Плохо представляю, что значит
> перебирая по одной записи в исходной таблице вставляя в
> итоговую
Т.е. Вы получаете набор данных из Access-а, а потом проходя по его (НД) записям формируете записи в централизованной таблице?
← →
apollo © (2004-06-04 15:39) [4]В общих чертах примерно так:
VAR
N: Integer;
...
SrcTable.Open;
DestTable.Open;
while not SrcTable.eof
do begin
DestTable.Insert;
for N:=0 to 240 do
DestTable.Fileds[N].AsVariant:=
DestTable.Fileds[N].AsVariant;
DestTable.Post;
SrcTable.next;
end;
SrcTable.Close;
DestTable.Close;
Хочется в общих чертах примерно так:
VAR
N, NR: Integer;
DataArr:OLEVariant;
...
<получение данных из SrcTable в DataArr>
...
NR:= VarArrayHighBound(DataArr,1);
DestTable.Open;
For N:=0 to NR do
DestTable.InsertRecords(DataArr[N]);
DestTable.Close;
← →
Danilka © (2004-06-04 15:42) [5][4] apollo © (04.06.04 15:39)
1. а где тут обещаная: "при переносе еще кое-какая логика задействована"?
2. перепиши на sql запрос: "insert into.." с параметрами, будет шустрее.
← →
apollo © (2004-06-04 15:51) [6]Я же говорю, что в общих чертах.
В первом примере:
...
for N:=0 to 240 do
DestTable.Fileds[N].AsVariant:=
DestTable.Fileds[N].AsVariant;
<дополнительная логика>
DestTable.Post;
Во втором:
NR:= VarArrayHighBound(DataArr,1);
For N:=0 to NR
do begin
<дополнительная логика>
end;
DestTable.Open;
For N:=0 to NR do
............................
И как я напишу запрос, если итоговая СУБД не дружит с Access"ом и не сможет подключить его файл как внешнюю базу данных?
← →
Danilka © (2004-06-04 16:03) [7][6] apollo © (04.06.04 15:51)
> И как я напишу запрос
уфф.
пусть DestTable у тебя не Table а Query, уж не знаю какая там у тебя СУБД, и какие компоненты доступа, но какой-нибудь квери точно есть.
Пишешь ему в тексте запроса:insert into TABLE_NAME (при желании тут в скобках перечисляешь все 240 полей через запятую) VALUES :PARAM1, :PARAM2 ... :PARAM240
Далее, первый вариант переписываешь на что-то типа:
...
while not SrcTable.eof
do begin
for N:=0 to 240 do
DestTable.Parameters[N].Value:=
SrcTable.Fileds[N].AsVariant;
DestTable.ExecSQL;
SrcTable.next;
end;
...
Выделеные жирным методы и свойства могут названия немного отличатся для разных компонент доступа.
Если все это оформить в одной транзакции, или в пачке транзакций, то все пролетит очень шустро.
← →
sniknik © (2004-06-04 16:04) [8]> если итоговая СУБД не дружит с Access"ом и не сможет подключить его файл как внешнюю базу данных?
тогда попытайся наоборот, наоборот (Access) "дружит" со многими, нужно только ODBC драйвер иметь.
← →
apollo © (2004-06-04 16:18) [9]Чем приведенный пример отличается от:
...
while not SrcTable.eof
do begin
DestTable.InsertRecords(
[
SrcTable.Fileds[0].AsVariant,
SrcTable.Fileds[1].AsVariant,
SrcTable.Fileds[2].AsVariant,
...
SrcTable.Fileds[240].AsVariant
]
SrcTable.next;
end;
...
Суть - таже insert into, только без лишнего шага - записи в параметры запроса. Если уж так, то мне не влом было бы написать вообще без параметров, генерировать самому строку запроса, простым сложением строк. Это даст прирост производительности всего процесса на 5%.
Суть в том, что вставляет записи в СУБД программа быстро,
я, в частности, кэширую запись.
Долго читать из Access"а по одной строчке. Весь массив (всю базу данных) в буфер системы Access считывает примерно в 10-20 раз быстрее, чем считывает построчно.
← →
sniknik © (2004-06-04 16:24) [10]> Долго читать из Access"а по одной строчке.
смотря как читать. по одной действительно долго (только похоже мы по разному понимаем, одна это в моем понятии после запроса с ... WHERE ID=1/2/3... в общем одна ;о))
> в буфер системы Access считывает примерно в 10-20 раз быстрее,
работает с ADO, можеш повторить и у тебя будет в 10-20 раз быстрее. (с чем сравнивал?)
← →
apollo © (2004-06-04 16:27) [11]to: sniknik
база IB6.5
Ну предположим свяжу я их между собой, все равно чтение из Access"а для вставки будет построчным. А Access умеет читать всю базу целиком.
← →
apollo © (2004-06-04 16:32) [12]Сравнивал просто:
1. читал в цикле через компонент ADO построчно
2. открыл базу в Access"е, выделил все записи, контекстное меню <копировать>, открыл Excell, контекстное меню <вставить>, сумма времени операций копирования-вставки в сравнении с временем прогона цикла
← →
sniknik © (2004-06-04 17:34) [13]> Ну предположим свяжу я их между собой, все равно чтение из Access"а для вставки будет построчным. А Access умеет читать всю
> базу целиком.
если свяжеш и добавиш к аксесовской базе ib таблицу как связаную, то все обновление выльется в простой insert into xxxib select * from xxxacs
(теоретически ;о), нет ODBS провайдера чтобы проверить, вернее был когдато но уже "срок годности" истек)
> сумма времени операций копирования-вставки в сравнении с временем прогона цикла
ну так, там наверное не выполнялась "<дополнительная логика>", и кстати через буфер ты вряд ли большие обьемы прогониш, выдели к примеру 5-10 тыс. записей и попробуй.
а вообще "долго" это не предметный разговор, может то что тебе долгим кажется есть самое что ни на есть нормальная скорость.
Страницы: 1 вся ветка
Форум: "Базы";
Текущий архив: 2004.07.04;
Скачать: [xml.tar.bz2];
Память: 0.49 MB
Время: 0.035 c