Top.Mail.Ru
Мастера DELPHI, Delphi programming community Титульная страница Поиск, карта сайта Написать письмо 
| Новости | Поиск | FAQ | Статьи | Книги | Новости VCL |
| Форумы ЧАТ | Орешник | KOL и MCK |
Форумы -» Основная («Начинающим»)/ Базы / WinAPI / Компоненты / Сети / Media / Игры / Corba и COM / KOL / FreePascal / .Net / Прочее / RSDN.ORG

« предыдущая ветвь | форум | следующая ветвь »

Null в строке


Страницы:   1 2 3

AndreyAR ©   (2006-01-18 09:03:00) 

Всем доброго времени суток.

Проблема в следующем: в строковом поле забиты строчки с символом #0. При попытке взять значение AsString возвращается пустая строка (размер 0), если же брать AsVariant, размер ненулевой. Как преобразовать Variant в String, заменив #0, например, пробелами, сохранив остальные символы?

Заранее спасибо всем, кто ответит.


sniknik   (2006-01-18 11:44:00) [21]

AndreyAR   (18.01.06 11:35) [23]
понятно...
действительно понятно, операторы TOP xxx, ограничения по WHERE xxx автору пожоже неизвестны... и пишет он похоже используя рабочую базу...

чтож, не будем мешать, флаг тебе в руки.


Плохиш   (2006-01-18 11:41:00) [22]


> AndreyAR   (18.01.06 11:35) [23]

Пора бы про строки нулём заканчивающиеся почитать.
У тебё в поле хранится не строкаа набор байт(символов) (в терминах делфи это называется динамический массив, про них то же пора бы почитать), вот и обрабатывай как массив символов.
За определённую оплату я готов сделать эту работу за тебя, но учти, что час моей работы стоит 30 Евро + налоги + непредвиденные расходы.


AndreyAR   (2006-01-18 11:35:00) [23]

Уважаемый, "табличка" весит 4 Гб. И грузится она частями специальным конвертером. Т.е. ночью выгружаются проводки, которые были добавлены днем. Дата, за которую грузить, выбирается из другой таблицы (закрытых опер. дней) и т.д. Задача не самая простая и "в лоб" одним запросом её не решить.

А на самом деле быстро будет (DTS и рядом не стоял), когда выгрузка будет переписана на использование Pervasive API, поскольку Merant ODBC Driver - тормоз по определению.


sniknik   (2006-01-18 11:24:00) [24]

> К сожалению, не прокатит - таблицы не совпадают по структуре:...
ну так ты хотябы раз проверь, закачай табличку то... правильно перенес? а тип поля какой создал?...

> По совокупности причин проще написать свой маленький конвертер.
пока приведены не причины, а отмазки, и конвертацию и преобразования можно/и лучше в самом запросе и сделать. а то что это будет работать быстрее любого твоего самописного конвертера как раз веский аргумент за запрос... тем более  "выгрузка должна происходить ежедневно".


AndreyAR   (2006-01-18 11:13:00) [25]


> DTS
> гетерогенные запросы в самом MSSQL


К сожалению, не прокатит - таблицы не совпадают по структуре: например, есть пустые поля, которые нафиг не нужно выгружать. Кроме того, нужно конвертировать дату/время (Btrieve хранит дату в формату клариона).
Ну и последний момент - выгрузка должна происходить ежедневно, для обеспечения актуальности данных. По совокупности причин проще написать свой маленький конвертер.


evvcom   (2006-01-18 11:05:00) [26]


> а что потом?

1. Сбросить позицию. ss.Position := 0;
2. TStream + F1, например, ss.ReadBuffer


sniknik   (2006-01-18 11:00:00) [27]

AndreyAR   (18.01.06 09:46) [6]
> Вообще, смысл моей программы в следующем: выгрузить таблицу из Btrieve в MS SQL.
DTS
гетерогенные запросы в самом MSSQL

evvcom ©   (18.01.06 10:19) [14]
> поэтому нестыковки между ними скорее всего сведены к минимуму :)
я бы сказал больше. там вообше один и тот же код там где это позволяется... т.е. пишут в OLEDB (ADO), а в драйвере ODBC "пустышки" с вызовами OLEDB аналогов...
имхо естественно. (я бы так сделал, если бы "тянул" 2 драйвера сразу)

p.s. varbinary представленный строкой может и не такие "чудеса" выдать... ;о)


Johnmen   (2006-01-18 10:56:00) [28]

var s : string;
...
SetLength(s,ss.Size);

Move(ss.Memory,s[1],ss.Size);
или
ss.Position:=0;
ss.ReadBuffer(s[1],ss.Size);


AndreyAR   (2006-01-18 10:52:00) [29]


> А в поле действительно что-то есть ?

Есть, есть, не сомневайтесь :)).
Null в смысле символ с ASCII-кодом 0. СУБД писалась задолго до появления винды, а там такое возможно.


Виталий Панасенко   (2006-01-18 10:49:00) [30]

Чего-то я не догняю.. Null он же и в Африке Null... Похоже, автор сам себе(и остальным) придумал заморочку на голом месте.. Либо ODBC драйвер глюкавит...А в поле действительно что-то есть ?


AndreyAR   (2006-01-18 10:44:00) [31]


> Ты уверен, что там действительно есть эти данные? Родные
> инструменты работы с СУБД это подтверждают?


Данные из этого поля - назначение платежа из балансовых проводок АБС "Диасофт Кард", кто знает.
Если бы их там не было, нам бы всем головы снесли давно :)). Ну и выгрузка FoxPro-шной прогой в MySQL это подтверждает. Драйвер, кстати, может быть не рассчитан на работу с ADO, хотя х.з., сейчас проверю вариант Joinmen-a.

А как, кстати, взять потом данные из Stream-a? Я например сделаю

var ss: tmemorystream;
...
TBlobField(FieldByName('yourfield')).SaveToStream(ss);

а что потом?


evvcom   (2006-01-18 10:19:00) [32]


> Всего поле в Btrieve занимает 240 байт, то бишь 240 символов.
> Тип поля - Variable length note (240).

Я, конечно, с Btrieve не знаком, но "Variable length note (240)" мне говорит о том, что поле это переменной длины и 240 - это максимумсимволов, которые может хранить это поле.

> Тут пришла в голову мысль, что, может быть, ODBC возвращает
> значение с нулями, а вот ADO уже может и обрезать его?  
> Как полагаете?

ODBC и ADO писаны одним разработчиком (компанией, насколько мне известно :)), поэтому нестыковки между ними скорее всего сведены к минимуму :) (хотя, конечно, всякое бывает). Главное здесь делает провайдер, он знает все особенности и тонкости работы с сервером. Если провайдер установлен верно, и у Btrieve действительно есть такая особенность хранения строк, то провайдер это должен учесть и пустить строку далее в стандартном, понимаемом его клиентами виде.
Ты уверен, что там действительно есть эти данные? Родные инструменты работы с СУБД это подтверждают?


Johnmen   (2006-01-18 10:12:00) [33]

http://www.delphimaster.ru/cgi-bin/forum.pl?id=1137401302&n=1


AndreyAR   (2006-01-18 10:08:00) [34]


> Попробуй так
> TBlobField(FieldByName('yourfield')).SaveTo....


Сейчас попробую. Кстати, если SaveToStream, то какой Stream создавать? И как из него потом вытащить данные? Я со stream-ами просто не работал, а рыться в справке некогда.


Johnmen   (2006-01-18 09:59:00) [35]

Попробуй так
TBlobField(FieldByName('yourfield')).SaveTo....


AndreyAR   (2006-01-18 09:57:00) [36]

Тут пришла в голову мысль, что, может быть, ODBC возвращает значение с нулями, а вот ADO уже может и обрезать его?  Как полагаете?

Если так, то придется переписывать все вообще без sql через Pervasive API, а это такой геморрой...


AndreyAR   (2006-01-18 09:54:00) [37]


> Ну и? Что не нравится? Строка пустая. А после первого нуля
> (или 2, наверное, если unicode) дальше мусор. Тебе мусор
> что ли нужен?


Не мусор, а значение поля. Всего поле в Btrieve занимает 240 байт, то бишь 240 символов. Первые символы забиты нулями, а дальше идет текст - это такое внутреннее представление данных в этой долбаной СУБД - она же древняя, старше и Windows и меня наверно. Вот этот текст (после нулей) и нужен, это и есть значение поля.


Johnmen   (2006-01-18 09:53:00) [38]

A variant occupies 16 bytes of memory and consists of a type code and a value, or pointer to a value, of the type specified by the code. (с) Variant+F1

Преобразование из варианта в строку у тебя правильно, VarToStr.


evvcom   (2006-01-18 09:49:00) [39]


> Как видите, первые символы - нули :(

Ну и? Что не нравится? Строка пустая. А после первого нуля (или 2, наверное, если unicode) дальше мусор. Тебе мусор что ли нужен?


AndreyAR   (2006-01-18 09:46:00) [40]


> А кто тебе сказал, что SizeOf - это длина строки в варианте?
>  Правильно, это размер, который занимает сама переменная
> типа Variant, но не строка.


Я уже догадался, но тем не менее факт остается фактом. Вообще, смысл моей программы в следующем: выгрузить таблицу из Btrieve в MS SQL. Сейчас работает подобная выгрузка в My Sql (там крутится FoxPro-шная прога). И значения этого самого поля в MySql выглядят так:

00 00 00 00 00 СF C5 D0 C5 C2 CE C4 (Hex-редактор)
|||||Перевод (а это сам текст).
Как видите, первые символы - нули :(


Страницы:   1 2 3

Наверх

Титульная страница Поиск, карта сайта Написать письмо