Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Базы";
Текущий архив: 2005.07.18;
Скачать: [xml.tar.bz2];

Вниз

Программная перекачка из 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;
Скачать: [xml.tar.bz2];

Наверх




Память: 0.56 MB
Время: 0.043 c
14-1119606881
хм
2005-06-24 13:54
2005.07.18
486 корпус


3-1117716092
andrey__
2005-06-02 16:41
2005.07.18
Компонент TADODataSet добавление пользовательского поля


14-1119612774
rOOse
2005-06-24 15:32
2005.07.18
телефоны Сенао


10-1096551187
AntonSh
2004-09-30 17:33
2005.07.18
COM Server


11-1103210800
boodilnik
2004-12-16 18:26
2005.07.18
иконки в Delphi7





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский