Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Базы";
Текущий архив: 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
1-1087888025
koala
2004-06-22 11:07
2004.07.04
[Fatal Error] Internal error: L2498


1-1087405140
Хазей
2004-06-16 20:59
2004.07.04
Запись числа в файл


4-1081365522
cerber1
2004-04-07 23:18
2004.07.04
Поиск каретки в системе


1-1087723329
akvilon
2004-06-20 13:22
2004.07.04
Мои шрифты и Canvas.Font


11-1076271391
ecm
2004-02-08 23:16
2004.07.04
Menu и изменение DefaultItem





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский