![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
загрузка из файла xml [D6, IB6.x, firebird]
galexis © (2003-03-04 19:13:00)Уважаемые мастера!
Копирую данные из файла .xml в БД. Есть набор полей типа Integer, все бы хорошо, да не во всех записях имеются поля, т.е. если значение в поле есть, то есть и поле в файле xml, если нет, то и поля в xml нет и тогла запрос выглядит так: insert into table (int1, int2) values (123,) И соответственно ошибка. Где здесь моя ошибка?
galexis (2003-03-06 16:43:00) [1]>Vinni
Чесно говоря с xml столкнулся впервые. В DataSet загружаю используя XMLTransformProvider. Поэтому какой у меня парсер сказать не могу. Где это посмотреть? ОС у меня XP, IE 6. IE открывает эти файлы xml еще медленнее (или так кажется). Где можно прочитать про MS-XML?
Vinni (2003-03-05 20:02:00) [2]Забыл... прошу прошения
Почему медленно справляется компьютер? Надо выяснить ЧТО тормозит. Один из вариантов - тормозит xml парсер.
Если использется Microsoft"овский парсер как сервер автоматизации (с поздним связванием через Dispatch) - замедление неизбежно. Ранее связывание, если склероз мне не изменяет, выигрывает в разы (кажется раз в 10?).
Решение: имортировать библиотеку типов в Delphi, получить *_TLB.pas (скорее всего будет MSXML_TLB.pas), ну и подключить его к нужным модулям. Правда в этом случае API будет несколько неудобным. Лично я написал просто более удомоваримую "обертку" к нему. А может Вы используете чей-то другой парсер или, даже, самописный? Я такие чудеса видел. Пробовал, как-то, скачанный парсер. Открыл файл ~3MB - устал ждать когда он его "разберет" и просто "снял" задачу. При этом он съел неимоверное количество памяти. А должен открывать за миллисекунды (MS-XML). Еще ускорить можно написав свой. По опыту говорю - скорость можно удвоить (против MS-XML).
Vinni (2003-03-05 19:42:00) [3]1. Запрос действительно надо составлять не конкатенацией, а параметризованным - я давно взял это за правило, и проблем стало меньше. Например: если в строковом пареметре встретится кавычка, а вы используете конкатенацию - "кирдык" вашему запросу, на сервер пойдет обрубленный на кавычке запрос. В случае же с параметрами, он никогда не "сломается".
2. Чтобы инициализировать запрос [TQuery] значением NULL, перед его выполнением сделать так:
обязательно !!!
theQuery.ParamByName("IDVID").DataType := ftInteger; //<-в случае Integer типа.
и
theQuery.ParamByName("IDVID").Clear;
galexis (2003-03-05 15:11:00) [4]Этот вопрос закрыт. На параметры посмотрю, давно хотел. Спасибо.
А вообще мне надо данные из 12 таблиц скопировать. Файл xml очень большой, мой неплохой компьютер справляется с загрузкой данных в TClientDataSet за 10 минут. Нельзя ли убыстрить как нибудь?
Val (2003-03-05 14:55:00) [5]>galexis ©
т.е. вопрос закрыт?
совет: приглядитесь к использованию параметров в запросах вместо конкатенации - качественно улучшит код и позволит избежать путаницы при их формировании.
galexis (2003-03-05 14:45:00) [6]Извините, налажал. Там в реальных данных как раз и идет 0. А там где нет полей - ничего не заносится этим запросом, т.е. все правильно.
galexis (2003-03-05 14:08:00) [7]if LoadDS.FieldByName("IDVID").AsString<>"" then
IDVID:=LoadDS.FieldByName("IDVID").AsString
else
IDVID:="NULL";
q1:="INSERT INTO UL (IDOPF,IDVID) values ("+
LoadDS.FieldByName("IDOPF").AsString+","+
IDVID+")";
LoadQr.SQL.Add(q1);
Реально запрос выглядит точно так:
insert into table (int1, int2) values (123,NULL)
Val (2003-03-05 11:14:00) [8]хм. может все-таки текст покажите, вместо игры в угадайку?
Mike_Goblin (2003-03-05 11:00:00) [9]insert into table (int1, int2) values (123,ID1)
это не то же самое, что
insert into table (int1, int2) values (123,NULL)
Перед выполнением запроса (на Query.ExecSQL)поставь точку останова - посмотри какой запрос выполяется реально.
zacho (2003-03-05 10:58:00) [10]
> insert into table (int1, int2) values (123,ID1)
Наверно :ID1 ? Т.е. ID1 - параметр ? Тогда нужно что-то типа ParamByName("ID1").Clear
galexis (2003-03-05 10:49:00) [11]Вставляется сразу около 3000 записей по 30 полей, но число полей в каждой записи разное. До того как формируется запрос, я проверяю поле на наличие значения и если его нет то переменной типа String присваиваю значение ID1:="NULL". Затем запрос, который для всех записей однаков insert into table (int1, int2) values (123,ID1)
Вот и все отличие от IBConsole, где пишу напрямую insert into table (int1, int2) values (123,NULL)
Mike_Goblin (2003-03-05 10:41:00) [12]Это значит, что ты делаешь не тоже самое
galexis (2003-03-05 10:39:00) [13]Из IBConsole делаю insert into table (int1, int2) values (123,NULL) Все хорошо, записывается NULL. Из TQuery делаю тоже самое - в поле записывается 0. Что бы это значило?
zacho (2003-03-05 10:29:00) [14]
> Если записывать NULL, то в поле типа Integer появится значение
> 0
С чего бы это ? NULL и запишется.
galexis (2003-03-05 10:23:00) [15]Файл xml дает другая организация. Его менять они не будут, да и не могут.
Если записывать NULL, то в поле типа Integer появится значение 0. А нужно чтобы отсутствало значение. В этом поле хранятся значения 0,1,2,3,4,5 (всего 6 значений) + это поле может быть пустым.
Mike_Goblin (2003-03-04 19:32:00) [16]>insert into table (int1, int2) values (123,)
insert into table (int1, int2) values (123,NULL)
лучше в xml при отсутсвии значения записывать слово NULL, чем просто убирать поле
galexis (2003-03-04 19:21:00) [17]Что нужно вставлять в поле обозначающее отсутствие значения?