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

Вниз

Проблема вытаскиваниея информации   Найти похожие ветки 

 
Separator   (2002-10-21 11:32) [0]

Я использую zeos компоненты.
У меня в базе есть поля под название Par1..ParX типа char(18). В них хранятся числовые данные, т.е. просто набор чисел. Как мне их вытащить???
Вот кусок кода:

var
Ar: array [1..18] of byte;
begin
ZMySqlQuery1.Sql.Clear;
ZMySqlQuery1.Sql("select Par1 from ArcRecv1 where NZap=1"); //NZap - номер записи
ZMySqlQuery1.Open;
Ar:= //Как вытащить???
ZMySqlQuery1.Close
end;


 
ЮЮ   (2002-10-21 11:49) [1]

ar: Integer;

ar:=StrToInt(ZMySqlQuery1.Fields[0].value);


 
Separator   (2002-10-21 11:51) [2]

Проситай внимательно! В одной ячеке хранятся 18 различных чисел типа byte. Мне это все надо вытащить в массив. Или хотябы узнать pointer, где лежат эти данные.


 
ЮЮ   (2002-10-21 12:10) [3]

>Или хотябы узнать pointer, где лежат эти данные
ZMySqlQuery1.Fields[0].AsString[1]


 
Separator   (2002-10-21 12:22) [4]

Вылетает с ошибкой AccessViolation.
Пишу так:

var
Ar: array [1..18] of byte;
i: integer;
begin
ZMySqlDatabase1.Connect;
ZMySqlQuery1.Open;
for i:= 1 to 18 do
Ar[i]:= Integer(ZMySqlQuery1.Fields.Fields[0].AsString[i]);
ZMySqlQuery1.Close;
ZMySqlDatabase1.Disconnect;
end


 
ЮЮ   (2002-10-21 12:39) [5]

Char в Integer нада преобразовывать, а не приводить
Ar[i] := Ord(ZMySqlQuery1.Fields.Fields[0].AsString[i]));
Да и в цикле вызывать метод AsString не расточительно?


 
passm   (2002-10-21 12:41) [6]

Separator © (21.10.02 12:22)> Если в середине #0, то это воспринимается как конец строки, и дальнейшие значения прочитать проблематично.
Попробуй привести это поле в тип CAST( (?... для Paradox"а Bytes, для DB2 CHARACTER(N) FOR BIT DATA, для MySQL - ???), чтобы в Delphi появилось поле типа ftBytes длиной в 18 байт, а далее читай по циклу.


 
ЮЮ   (2002-10-21 12:47) [7]

C Ord я, конечно, перегнул палку :-)

str := ZMySqlQuery1.Fields.Fields[0].AsString;
for i:= 0 to Length(str) - 1 do
Ar[i] := StrToInt( Copy(str,i,1) );


 
ЮЮ   (2002-10-21 12:55) [8]

Хотя, можно и с Ord:

str := ZMySqlQuery1.Fields.Fields[0].AsString;
for i:= 0 to Length(str) - 1 do
Ar[i] := Ord(str[i+1]) - Ord("0");


 
Separator   (2002-10-21 12:57) [9]

#0 в самом начале и дальше тоже появляется. Вообще в ячейках хранятся структуры такого типа:

type
PPar= ^TPar;
TPar= packed record
flgTS: byte;
Ckv: single;
Vmin: single;
Vkv: byte;
TimeRecv: cardinal;
TimeUpd: cardinal
end;

Я в дальнейшем буду делать так:
move(Ar, Par, 18);
Кстати база так и заполнялась, тока в обратном порядке и на C++


 
ЮЮ   (2002-10-21 13:05) [10]

А в Ar загнать удалось ?
Тогда может сразу
move(ZMySqlQuery1.Fields.Fields[0].Value, Par, 18);


 
Separator   (2002-10-21 13:18) [11]

Неа не корректные данные или AccessViolitate
В Ar тоже не удалось.
Прикол в том, что Value типа variant, а он тока 16 байт.


 
ЮЮ   (2002-10-21 13:22) [12]

"не корректные данные или AccessViolitate" - это, похоже, от ADO provider-а. Запрос-то сам выполняется?


 
ЮЮ   (2002-10-21 13:25) [13]

Value типа variant.
A какой VarType ?


 
Separator   (2002-10-21 13:32) [14]

Запрос выполняется.
VarType выдает 256. Я никогда не работал с вариантами и не заню как.


 
ЮЮ   (2002-10-21 13:50) [15]

VarType выдает 256.
это varString.
Тогда возвращаемся к
move(ZMySqlQuery1.Fields.Fields[0].asString[1], Par, 18);



 
Separator   (2002-10-21 13:58) [16]

Не получается. если делать:
St: ZMySqlQuery1.Fields.Fields[0].asString[1];
move(St, par, 18);
то получается, но с некоректными данными. А если так как ты пишешь, то AccessViolitate


 
ЮЮ   (2002-10-22 04:17) [17]

St: ZMySqlQuery1.Fields.Fields[0].asString[1];
move(St, par, 18);
то получается, но с некоректными данными

Естественно, т.к. в St считан только первый символ из БД, а остальное - мусор. Тогда уж
St:= ZMySqlQuery1.Fields.Fields[0].asString;
Кстати, какой длины полуится при этом St, принимая во внимание наличие #0 ?
Если обрезает, то попробуй метод GetCurrentRecord


 
Separator   (2002-10-22 06:38) [18]

Length(St) = 0
Сейчас попробую


 
Separator   (2002-10-22 07:09) [19]

не получается.

var
Par: PPar;
P: pChar;
Ar: array [1..18] of byte;
i: integer;
begin
ZMySqlDatabase1.Connect;
ZMySqlQuery1.Open;
P:= StrAlloc(255);
GetMem(Par, 18);
ZMySqlQuery1.GetCurrentRecord(P);

Memo1.Lines.Clear;

for i:= 0 to 255 do
Memo1.Lines.Add("P["+IntToStr(i)+"] = "+IntToStr(Ord(P[i])));

move(P^, Par^, 18);

Memo1.Lines.Add("flgTS: "+IntToStr(Par^.flgTS));
Memo1.Lines.Add("Ckv: "+FloatToStr(Par^.Ckv));
Memo1.Lines.Add("Vmin: "+FloatToStr(Par^.Vmin));
Memo1.Lines.Add("Vkv: "+IntToStr(Par^.Vkv));
Memo1.Lines.Add("TimeRecv: "+IntToStr(Par^.TimeRecv));
Memo1.Lines.Add("TimeUpd: "+IntToStr(Par^.TimeUpd));

FreeMem(Par, 18);

ZMySqlQuery1.Close;
ZMySqlDatabase1.Disconnect;
end;


 
Separator   (2002-10-22 07:18) [20]


> GetCurrentRecord(P);

Почемуто забивает только 2 байта (0 и 1) остальное 0


 
Separator   (2002-10-22 14:27) [21]

проблема так и не решена. У кого еще есть какие-либо версии?


 
ЮЮ   (2002-10-23 03:46) [22]

>Почемуто забивает только 2 байта (0 и 1) остальное 0
А откуда уверенность, что заполнено более 2 байтов из 18 ?


 
Separator   (2002-10-23 08:13) [23]

Во первых:
move(P^, Par^, 18);
изменяются только первые две переменные, остальные нули.
Во вторых:
for i:= 0 to 255 do
Memo1.Lines.Add("P["+IntToStr(i)+"] = "+IntToStr(Ord(P[i])));
Кроме первых двух, все остальные нули


 
ЮЮ   (2002-10-23 08:28) [24]

Это понятно. А почему ты думаешь, что в БД есть ещё что-то ???


 
Separator   (2002-10-23 08:49) [25]

Другими прогами все нормально вытаскивается, все уже на 10 раз проверено, даже на c++ под Linux писали тестовую прогу, все везде есть. Да и я сам уже на дельфях проверял только другим методом, с помощью другой библиотеки.


 
ЮЮ   (2002-10-23 09:10) [26]

а пробовал, что говорит passm © (21.10.02 12:41) ?


 
Andriano   (2002-10-23 09:12) [27]

Может я чего не догоняю.

Но в самом первом вопросе текст SQL "select Par1 from ArcRecv1 where NZap=1".
Выбирается в набор данных только одно поле "Par1" и обращаетесь к нему, но хотите из него (типа CHAR) вытащить AsString[1], AsString[2], AsString[3]... В нём только AsString[1], а дальше
AccessViolation - всё правильно.

Может вам надо так:
ZMySqlQuery1.Sql.Clear;
ZMySqlQuery1.Sql("select * from ArcRecv1 where NZap=1"); ZMySqlDatabase1.Connect;
ZMySqlQuery1.Open;
for i:= 0 to 17 do //нумеруются данные в наборе с нуля
Ar[i+1]:=Ord(ZMySqlQuery1.Fields.Fields[i].AsString);
ZMySqlQuery1.Close;
ZMySqlDatabase1.Disconnect;
end


 
Separator   (2002-10-23 09:25) [28]


> Andriano © (23.10.02 09:12)
Поле Par1 (..13) имеет тип char на 18 байт длиной.


 
Andriano   (2002-10-23 12:08) [29]

Я тут недавно натыкался на подводные камни со string.
В Delphi (в отличие от Pascal 7.0) string это тот же PChar (просто Delphi следит за string сам).

Т.е. когда переменной типа string не присвоено ни одного значения. Она ссылается на nil (это незаметно, если не разбираться). Когда присвоить значение, то старая память освобождается (если не nil), выделяется новая и туда записывается новое значение. Представляете, что происходит когда выполняется цикл
типа такого

var s:string;
for i:=1 to 100 do s:=s+" ";

Теперь, как это может относиться к вашему вопросу.
Delphi смотрит на значение ParN, как на PCHar, т.е. до ближайшего #0 (если Par1=#0#8#6#8..., то длина pchar-значения = 0). Освобождает память размером в 1 байт (для случая когда Par1=#0...), куда записывает только #0. Т.е. записывает значение "". потом вы обращаетесь AsString[1] (когда к string с 1, а к PChar с 0, здесь вмешивается Delphi для совместимости со старыми pas), получаете значение 0 (за байтом #0 и сам байт #0 смотреть можно - это не проверяется ). А вот когда AsString[2], то скорее всего AccessViolation, т.к. там уже участок памяти, блокированный не вашим процессом.

Всю эту теорию можно проверить так: Считай запись из таблицы, где Par1,Par2,...,ParN<>0 и твой первоначальный способ должен работать.

Кстати к 6 сообщению, Ord(...AsString[i]) - вообщем правильно тоже, т.к. можно читать данные за концом строки (как в widestring, pchar, так и в string), можете проверить. Просто это может вызвать ошибку AccessViolation.


 
Separator   (2002-10-23 12:28) [30]

Это и так вызывает ошибку AccessViolation. Мнеб получить указатель на памфть, где лежат значения получаемые при запросе. Конкретно, если мой запрос такого типа "select Par1 from ArcRecv1 where NZap=1", то реально в результате получается одна ячейка, в ней лежат 18 байт данных, так вот как получить указатель на первый байт?


 
Andriano   (2002-10-23 13:01) [31]

Так вот я и говорю, что не получается 18 байт, а получается 0 байт, т.к. CHAR в базе начинается с #0 (кстати #0 или "0"). Delphi получается вообще не сохраняет данные из ячейки.
Это теория - повторяю ещё раз. Можешь проверить.

Ладно, сам проверю...Проверил:


Записать в поле типа CHAR символ #0 нельзя. Точнее можно, но всё что после него и он сам игнорируется (как я и говорил).
Нельзя по крайней мере с помощью .AsString:=...
А если и записал, то опять же с помощью AsString получить нельзя (то что после #0). Всё это из-за того, что приложения (IB и Приложение или BDE и Приложение) обмениваются PCHar-ами.
А вообще, всё логично, CHAR предназначен для хранения строк формата ANSI.


Я проверял на IB.


 
Separator   (2002-10-23 13:04) [32]

А как это получить??? мне не обязательно как char, мне хоть как, мне нужны все 18 байт или указатель на 1 байт из этих 18


 
passm   (2002-10-23 13:10) [33]

И я тебе об этом... См. <passm © (21.10.02 12:41)>
Уже сталкивался с этим, но в DB2.


 
Separator   (2002-10-23 13:17) [34]

А как это сделать ну хоть в DB2, я немного не понял что там написано <passm © (21.10.02 12:41>


 
Andriano   (2002-10-23 13:25) [35]

Никак нельзя получить.
Эти 18 байт вообще не читаются из базы (если с #0).
Сохраняй их в допустим формате, тогда и получить сможешь.
Например .AsString:="012345678901234567". А получаешь Ord(.AsString[i]).
Чем тебя это не устраивает?


 
Andriano   (2002-10-23 13:29) [36]

Ой я ляпнул...
Чуть выше не "получаешь Ord(.AsString[i]).", а "StrToInt(.AsString[i])."


 
Separator   (2002-10-23 13:32) [37]

В другом формате нельзя сохранять, это уже давно работающая база, и вытаскивать данные получается без проблем на c++, а вот на дельфях не получается, а мне надо обязательно на дельфях


 
Separator   (2002-10-23 13:35) [38]


> Andriano © (23.10.02 13:29)

тоже фигня не работает


 
Andriano   (2002-10-23 13:54) [39]

После s:=.AsString в s записываются уже неверные данные.
А получить адрес свойства .AsString нельзя - это не переменная.

Слушай, у тебя DBF? Читай её сам напрямую, строго её формат? Так можно переконвертировать её, все #0#9... перевести "09...".


 
passm   (2002-10-23 14:07) [40]

Separator © (23.10.02 13:17)> Для хранения информации подобного типа в DB2 есть CHARACTER(N) FOR BIT DATA и BDE возвращает это поле как TBytesField.
Но, если это поле преобразовать в другой строковый тип, например, CAST(T1.FIELD1 AS VARCHAR(13)), то BDE все равно возвращает его как TBytesField.
В связи с этим, попробуй проверить какое поле будет у TQuery - воспользуйся Fields Editor"ом. Если TStringField, то попробуй сделать в запросе CAST, чтобы было TBinaryField или TBytesField. Далее рассматривай TBinaryField.Value: Variant как вариантный массив с числами Byte.



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

Форум: "Базы";
Текущий архив: 2002.11.14;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.54 MB
Время: 0.016 c
14-46049
iNew
2002-10-25 05:32
2002.11.14
В Win2000 есть такая штука как net send (можно посылать


1-45971
Тундра
2002-11-04 15:21
2002.11.14
Вызов контекстной помощи


3-45711
vladimir_12
2002-10-24 10:17
2002.11.14
DBase запись не добавляется...


4-46210
Stealth13
2002-09-11 11:53
2002.11.14
как


1-45949
prorok2
2002-11-04 12:34
2002.11.14
Вызов внешней программы и работа с ней





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