Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2005.07.18;
Скачать: CL | DM;

Вниз

Программная перекачка из DBF в MSSQL   Найти похожие ветки 

 
kivadim   (2005-05-18 09:44) [0]

Есть таблички DBF-ки, которые имеют одинаковые структуры и данные из которых нужно перекачивать в таблицу на MSSQL сервере.
Перекачку в проге делаю следующим образом:

procedure TForm1.TransferData(TName: string);
var i: integer;
begin
flDM.DBF_Query.Close;
flDM.DBF_Query.SQL.Clear;
flDM.DBF_Query.SQL.Text:="select * FROM "+TName+" ";
flDM.DBF_Query.Open;

flDM.MSSQL_Query.Close;
flDM.MSSQL_Query.SQL.Clear;
flDM.MSSQL_Query.SQL.Text:="insert into MSTable values("+
                             ":FL000, :FL00_1_1, :FL00_1_2, :FL01, :FL01_A, :FL02_1, :FL02_2, "+
                             ":FL03, :FL04, :FL05, :FL11, :FL12, :FL13, :FL15, :FL16, :FL17, :FL30, :FL31, "+
                             ":FL32_1, :FL32_2, :FL33, :FL34, :FL35_1, :FL35_2, :FL35_3, :FL35_4, :FL41_1, "+
                             ":FL41_2, :FL45_1, :FL45_2, :FL45_3, :FL45_4, :FL42, :FL50, :FL51, :FL52_1, "+
                             ":FL52_2, :FL52_3, :FL53, :FL61, :FL61_1, :FL61_2, :FL62, :FL63_1, :FL63_2, "+
                             ":FL71_1, :FL71_2, :FL00_3, :FL00_4, :FL00_5, :FL00_6, :FL00_7, :FL00_8) ";

while not flDM.DBF_Query.Eof do
 begin
  for i:=0 to 52 do
   begin
    flDM.MSSQL_Query.Parameters[i].Value:=flDM.DBF_Query.Fields[i].AsVariant;
   end;
  flDM.MSSQL_Query.ExecSQL;
  flDM.DBF_Query.Next;
 end;
flDM.DBF_Query.Close;
end;


но работает довольно медленно, так например ~35000 записей перекачиваются порядка 5-7 минут.
Можно ли записать гетерогенный запрос в котром участвовали бы таблица .dbf и таблица mssql?
Ну или хотябы как увеличить быстродействие существующего решения?


 
Anatoly Podgoretsky ©   (2005-05-18 09:46) [1]

INSERT INRO SELECT FROM


 
ANB ©   (2005-05-18 09:48) [2]


> kivadim   (18.05.05 09:44) ~35000 записей перекачиваются порядка 5-7 минут
- нормально по времени. Сервак пошустрее используй и DBF качай на нем локально.


 
Lexer ©   (2005-05-18 09:56) [3]


> [1] Anatoly Podgoretsky ©   (18.05.05 09:46)
> INSERT INRO SELECT FROM


Ему надо перекачать из одной БД в другую, неужели MSSQL проглотит скрипт типа:
INSERT INTO WARE SELECT FROM "......ware.db"?


 
Nikolay M. ©   (2005-05-18 09:57) [4]

http://delphimaster.net/view/3-1116325991/
Ы?


> как увеличить быстродействие существующего решения?

Использовать BULK INSERT - быстрее по-любому не получится.


 
Виталий Панасенко   (2005-05-18 09:58) [5]

Вообще-то у MS SQL есть свой механизм импорта данных... Зачем изобретать велосипед ?


 
Nikolay M. ©   (2005-05-18 09:58) [6]


> Можно ли записать гетерогенный запрос в котром участвовали
> бы таблица .dbf и таблица mssql?

BOL: OPENROWSET, OPENDATASOURCE, linked servers.


 
Max Zyuzin ©   (2005-05-18 10:01) [7]

>kivadim   (18.05.05 09:44)  
Не стоит использовать TADOQuery для выполнения запросов, которые ничего не возвращают. TADOCommand попробуй вместо этого.
Вообще я так заметил что работа через АДО с dBase довольно медленна... по этому время перекачки кажется мне нормальным, по поводу гетерогенного запроса думаю что ничего не получится, хотя фиг знает.


 
sniknik ©   (2005-05-18 10:06) [8]

> - нормально по времени.
ненормально, пакетная команда [1] отработает гдето сек 3-10 (может больше от многого зависит, но ненамного)
и основное время уйдет не на перекачку а на подключение к движку... (это если по минимальному времени сравнивать)

> Можно ли записать гетерогенный запрос в котром участвовали бы таблица .dbf и таблица mssql?
openrowset, opendatasource, linked server, dts + BOL ко всем темам
и + microsoft jet для обьекта "с другой стороны" от MSSQL.

повнимательнее с путями, считаются от того кто выполняет а это будет у тебя MSSQL сервер. (если откудато с рабочей станции таблица, сервер ее должен видеть, и пути писать от него)


 
Anatoly Podgoretsky ©   (2005-05-18 10:08) [9]

Lexer ©   (18.05.05 09:56) [3]
MS SQL достаточно серьезная система, что бы не справиться с такой мелочью. В вопросе нет ни какой детализации, чтобы можно было предложить другое оптимальное решение, данное решение самое быстродействующее.


 
sniknik ©   (2005-05-18 10:10) [10]

> хотя фиг знает
знаю, знаю. точно получится. (возможность есть)
                                           фиг.

;о))


 
Max Zyuzin ©   (2005-05-18 11:27) [11]

>sniknik ©   (18.05.05 10:10) [10]
Ну раз сам Фиг знает :o) значит точно получится :o)


 
ANB ©   (2005-05-18 11:31) [12]

Есть у меня пример закачки dbf в MS SQL. Но я там через ADO коннектился только к MS SQL. Из dbf напрямую данные читал. Скорость - ну 35000 за 3-5 сек точно не качала, но быстрее 3 минут.


 
kivadim   (2005-05-18 13:44) [13]

Спасибо всем за ответы.

>> Виталий Панасенко   (18.05.05 09:58) [5]
Надо будет разобраться, просто не подозревал что можно автоматизировать перекачку через DTS.

Еще вопросик:
Я закачивал данные в MS, а потом удалял и заметил, что удаление данных не уменьшает размер БД в MSSQL, а также сильно увельчивается размер лог-файла базы в MSSQL. Как можно заблокировать размер лог-файла, сохраняя при этом работоспособность самой БД либо вообще удалить лог-файл и как все-же уменьшить размер БД после удаления данных?


 
MOA ©   (2005-05-18 14:22) [14]

>Как можно заблокировать размер лог-файла, сохраняя при этом работоспособность самой БД либо вообще удалить лог-файл
Никак. Ибо это и есть основной механизм, благодаря которому MSSQL является SQL сервером ;).
Лог очишается только при бэкаппах - это есть механизм "дуракоустойчивости" ;). Если для базы установлен флаг "Auto shrink" - после бэкапа она уменьшится автоматом. Или см. в BOL команду
DBCC SHRINKDATABASE
И ещё - посмотрите в EM свойства Вашей базы - будет любопытно ;).
Удачи!


 
kivadim   (2005-05-18 15:48) [15]

наткнулся на решение обратной проблемы


procedure TExportADOTable.ExportToDbase(FieldNames: string; FileName: string;
 IsamFormat: string);
begin
 {IsamFormat values
 dBase III
 dBase IV
 dBase 5.0
 }
 if not Active then
   Exit;

 FADOCommand.Connection := Connection;
 FADOCommand.CommandText := "Select " + FieldNames + " INTO " + "[" +
   ExtractFileName(FileName) + "]" +
   " IN " + """ + ExtractFilePath(FileName) + """ + "[" + IsamFormat +
   ";]" + " From " + TableName;
 FADOCommand.Execute;
end;


где сводится к сосставлению подобного запроса:
Select * INTO [small.dbf] IN "D:\" [dBase IV;] From My_Table
но возникает ошибка

Project TransferData.exe raised exception class EOleException with message "Incorrect syntax near the keyword "IN"". Process stopped. Use Step or Run to continue.


Подскажите в чем проблема...


 
sniknik ©   (2005-05-18 16:00) [16]

ты нашол запрос для access, для mssql см. BOL по называемым ранее темам.


 
kivadim   (2005-05-25 10:40) [17]

Еще вопросик.
Почему MSSQL сервер (процесс sqlserver.exe) после отработки запроса не освобождает занятую им память?
Запустив пару запросов на перекачку больших объемов данных sqlserver.exe занимает по нарастающей объем памяти, а по окончанию работы не освобождает ее.
Это норамально?


 
Nikolay M. ©   (2005-05-25 10:43) [18]


> Это норамально?

Да.


 
Anatoly Podgoretsky ©   (2005-05-25 12:18) [19]

kivadim   (25.05.05 10:40) [17]
По окончанию работы освобождает


 
kivadim   (2005-05-30 15:21) [20]

Надо же возникла какая-то непонятная ошибка.

На локальном MSSQL сервере все работает нормально, а на удаленном MSSQL выдает ошибку, хотя до выходных все тоже прекрасно работало (сам файл dbf находится на удаленной машине).

запускаю такой запрос, где 749_050320_050418 - это имя ДБФ-ки

select * from OPENROWSET("Microsoft.Jet.OLEDB.4.0",
           "dBase 5.0;DATABASE=D:\dbf_folder",
           "Select * from [749_050320_050418]")

и выдается сообщение об ошибке:

Server: Msg 7399, Level 16, State 1, Line 1
OLE DB provider "Microsoft.Jet.OLEDB.4.0" reported an error.  
[OLE/DB provider returned message: The Microsoft Jet database engine could not find the object "749_050320_050418".  Make sure the object exists and that you spell its name and the path name correctly.]
OLE DB error trace [OLE/DB Provider "Microsoft.Jet.OLEDB.4.0" IColumnsInfo::GetColumnsInfo returned 0x80004005:   ].


Иногда , если переименовать имя ДБФ-ки в нормальное используя алфавитные символы, то запрос проходит, а иногда не проходит.

Пожайлуста проясните такое поведение сервера.


 
Nikolay M. ©   (2005-05-30 15:35) [21]

http://www.sql.ru/forum/actualthread.aspx?tid=180672#1524673


 
sniknik ©   (2005-05-30 15:36) [22]

переименовывать надо по правилам наименования DOS файлов (не более 8 символов, и без всяких недопустимых в именах файлов/директорий знаков), либо можно получить короткое имя файла от системы (там уже все по "правильному") и давать в запрос уже эти имена базы/таблици. (получить с помощью GetShortPathName)


 
kivadim   (2005-05-30 16:02) [23]

to Nikolay M. ©   (30.05.05 15:35) [21]

нет такое же поведение, на локальном сервере работает, а на удаленном на запрос

SELECT * FROM
OPENROWSET("MSDASQL",
          "Driver={Microsoft dBase Driver (*.dbf)};DBQ=D:\dbf_folder\",
          "Select * from [730_050320_050418]")


выдает ошибку

Server: Msg 7399, Level 16, State 1, Line 1
OLE DB provider "MSDASQL" reported an error.  
[OLE/DB provider returned message: [Microsoft][ODBC dBase Driver] The Microsoft Jet database engine could not find the object "730_050320_050418".  Make sure the object exists and that you spell its name and the path name correctly.]
OLE DB error trace [OLE/DB Provider "MSDASQL" IColumnsInfo::GetColumnsInfo returned 0x80004005:   ].



 
Anatoly Podgoretsky ©   (2005-05-30 16:08) [24]

Ну говорит же, что не может найти указаную таблицу и предлагает проверить правильность пути.


 
kivadim   (2005-05-30 16:21) [25]

>> Anatoly Podgoretsky ©   (30.05.05 16:08) [24]

:)) Да я понимаю что он пишет. В том то и дело что таблица находиться в каталоге и путь прописан правильно, т.к. если для проверки переименовать ее, то все работает. На локальном же сервере все работает с любым именем, так что это проблема сервера и как ее искоренить я не понимаю. Буквально в пятницу все работало без проблем, а сегодня на тебе...


 
sniknik ©   (2005-05-30 16:35) [26]

> Буквально в пятницу все работало без проблем, а сегодня на тебе...
с такими именами? не верю! (© Станиславский)
должны быть короче. используются DOS соглашения имен, в твоем случае ищется такое путь D:\DBF_FO~1\ имя файла 730_05~1 dbf. при условии что файл один в папке либо первый в списке (!!!!!) если не первый не поможет (в конце будет 2/3/и т.д.), даже если после удалить остальные. (точную информацию об коротком имени дает уже приводившаяся процедура)
либо переименовывать в то что совпадает с полным именем (длинное = короткое). опять уже говорилось. (игнор? я у тебя в черном списке? скажи, я отстану)


 
MOA ©   (2005-05-30 16:42) [27]

D - это с точки зрения удалённого сервера - его локальный диск?


 
kivadim   (2005-05-30 16:58) [28]

>> с такими именами? не верю! (© Станиславский)

действительно работало с такими именами. попробовал имена до 8 символов и работает. и теперь остается вопрос почему раньше удаленный сервак работал с длинными именами, а локальный до сих пор без проблем работает?

Хотя возможно причина в том что серверная машина работает под управлением Windows Server 2003, а моя локальная под XP?

>> MOA ©   (30.05.05 16:42) [27]
если запрос выполняет удаленный сервер то соответственно БДФ-ка находится на локальном диске серверной машины.


 
sniknik ©   (2005-05-30 17:07) [29]

> и теперь остается вопрос почему раньше удаленный сервак работал с длинными именами, а локальный до сих пор без проблем работает?
возможно версия jet разная.


 
sniknik ©   (2005-05-30 17:11) [30]

или BDE в одном месте стоит а на севере нет. вот режимы и различаются. проще делай так, как будто нигде не работает...


 
kivadim   (2005-05-30 17:20) [31]

>> возможно версия jet разная.
Думаю это не причина, т.к. и через ODBC dBase Driver таже фишка

SELECT * FROM
OPENROWSET("MSDASQL",
          "Driver={Microsoft dBase Driver (*.dbf)};DBQ=D:\Users\DAO\mid",
          "Select * from 703_050320_050418.DBF")

BDE стоит на обоих машинах, хотя причем тут он...?


 
sniknik ©   (2005-05-30 17:56) [32]

> Думаю это не причина, т.к. и через ODBC dBase Driver таже фишка
а ты внимательнее прочитай что тебе ошибку выдает, с ODBC.

> BDE стоит на обоих машинах, хотя причем тут он...?
при том же, jet в свою очередь тоже передает управление дальше, в некоторых случаях.


 
Anatoly Podgoretsky ©   (2005-05-30 19:14) [33]

kivadim   (30.05.05 17:20) [31]
OLE/DB provider returned message: [Microsoft][ODBC dBase Driver] The Microsoft Jet database engine could not find the object

Вот это ты же привел? А Jet работает через БДЕ, у тебя очень длинная цепочка драйверов, с ограничениями на каждом звене.


 
kivadim   (2005-06-01 15:50) [34]

Благодарю всех за помощь.
Но заметил еще один неприятный эффект от использования такого рода запроса:

insert into MS_table select
select * from OPENROWSET("Microsoft.Jet.OLEDB.4.0",
          "dBase 5.0;DATABASE=D:\dbf_folder",
          "Select * from [749_050320_050418]")


а именно после отработки такого запроса не могу ни программно, ни вручную удалить например каталог D:\dbf_folder, участвовавший в запросе. Т.к. получается что он занят в работе MSSQL сервера, хотя запрос отработал. Удалить каталог удается лишь перезапустив MSSQL сервер.

Как все же удалить папку не перезапуская сервер?


 
Anatoly Podgoretsky ©   (2005-06-01 15:57) [35]

Каталог является текущим и не пуст. Пытать предварительно сделать другую папку текущей


 
kivadim   (2005-06-01 16:11) [36]

>> Anatoly Podgoretsky ©   (01.06.05 15:57) [35]

Каталог пуст на 100%.

> Пытать предварительно сделать другую папку текущей

это как? другой запрос c др. каталогом?


 
sniknik ©   (2005-06-01 16:35) [37]

не получится, это с BDE тянется, том тоже пока сессию не закроеш/из программы не выйдеш каталог не удаляется. а тут не ты сессию открываеш а jet, а он не выгружается сразу на случай следующих обрашений (так быстрее). попробуй обойтись без временного каталога, который надо после удалять... (можно системный tmp использовать например)


 
kivadim   (2005-06-02 11:20) [38]

Надеюсь последний вопрос с моей стороны на эту тему.. :))

До сих пор таблицы dbf состояли из одного файла, например:325_050214_050214.dbf
Теперь же приходят таблицы dbf, состоящие из двух файлов, например: 703_050412_050412.DBF и 703_050412_050412.FPT, т.е. файл с полем МЕМО.
Так вот при исполнении запроса, используя короткое имя

select count(*) from OPENROWSET("Microsoft.Jet.OLEDB.4.0",
           "dBase 5.0;DATABASE=D:\dbf_folder",
           "Select * from [703_05~1.DBF]")

выдается ошибка:

Server: Msg 7357, Level 16, State 2, Line 1
Could not process object "Select * from [703_05~1.DBF]". The OLE DB provider "Microsoft.Jet.OLEDB.4.0" indicates that the object has no columns.
OLE DB error trace [Non-interface error:  OLE DB provider unable to process object, since the object has no columnsProviderName="Microsoft.Jet.OLEDB.4.0", Query=Select * from [703_05~1.DBF]"].

Т.е. я предполагаю что, используя короткое имя файла DBF, сервер не находит файл 703_050412_050412.FPT

Как можно разрулить и эту ситуацию?


 
kivadim   (2005-06-02 11:24) [39]

забыл сказать что структура всех DBF таблиц одинакова, просто в некоторых одно поле типа МЕМО а в других типа CHARACTER


 
Anatoly Podgoretsky ©   (2005-06-02 11:52) [40]

kivadim   (02.06.05 11:20) [38]
Надеюсь последний вопрос с моей стороны на эту тему.. :))

До сих пор таблицы dbf состояли из одного файла, например:325_050214_050214.dbf
Теперь же приходят таблицы dbf, состоящие из двух файлов, например: 703_050412_050412.DBF и 703_050412_050412.FPT, т.е. файл с полем МЕМО.
Так вот при исполнении запроса, используя короткое имя

select count(*) from OPENROWSET("Microsoft.Jet.OLEDB.4.0",
          "dBase 5.0;DATABASE=D:\dbf_folder",
          "Select * from [703_05~1.DBF]")

Короткое имя одного файла нельзя применять для короткого имени другого файла. Я думаю, что когда тебе говорили про короткое имя, то имели в виду формат 8.3, а не двойственность природы FAT

Т.е. я предполагаю что, используя короткое имя файла DBF, сервер не находит файл 703_050412_050412.FPT

Ему не зачем искать это имя, когда ты явно сказал искать 703_05~1.FPT, а такого файла или нет или система не намерена искать по короткому имени FAT, что монопенисно.



Страницы: 1 2 вся ветка

Текущий архив: 2005.07.18;
Скачать: CL | DM;

Наверх




Память: 0.58 MB
Время: 0.052 c
1-1119695069
TW
2005-06-25 14:24
2005.07.18
Работа с TObjectList


1-1120124715
PIF
2005-06-30 13:45
2005.07.18
оператор case


1-1120149189
Бу
2005-06-30 20:33
2005.07.18
Графика


14-1119351318
Vikarij
2005-06-21 14:55
2005.07.18
Printer, нет бумаги


1-1120214242
Тучудище
2005-07-01 14:37
2005.07.18
Перекодирование из GSM(7 битной кодировки) в ASCII например