![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Null в строке
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-редактор)
|||||Перевод (а это сам текст).
Как видите, первые символы - нули :(