Проблем с ADO & MSSQL

8 отговора 144 прегледа
#1

Проблем с ADO & MSSQL

Имам проблем с извличането на BLOB поле от MSSQL база. Полето е дифинирано нато TEXT. Използвам TADOConnection и TADOQuery. Проблема се появява когато данните в това BLOB поле са двоични (имат произволни символи, включително и #0). Когато в полето има обикновен текст, всичко работи. Когато данните са двоични, извлечените данни са срязани, може би до символ #0. Опитвах всякакви варианти:

S := ADOQuery.FieldByName('MyField').AsString;

или

S := ADOQuery.FieldByName('MyField').Value;

или

(ADOQuery.FieldByName('MyField') as TBlobField).LoadFromStream(MyStream);

но резултата все е същия. Когато тествах същото нещо с BDE и ODBC, всичко се извлича правилно (по този начин проверих дали данните са в базата), но в случая трябва да използвам ADO

Отговор
в отговор на Питaщ #2

Re: Проблем с ADO & MSSQL

мдам, незнам какво прави BDE/ODBC с текстове съдържащи #0, но можеш да тръгнеш от една такава проба:

var
S : String; //предполагам?
j : Integer;
....
S := ADOQuery.FieldByName('MyField').Value; //Value е Variant
// ако не го реже ADO-то S ще съдържа всичко, включително и #0
for j := 1 to Length(S) do begin
if ord(S[j] = 0) then S[j] := #255;
end;

ако в S тук-там се срещат смахнати символи, значи ADO-то пуска всичко, а Delphi-то реже стринга т.е. можеш да се бориш да обработваш #0 до удобен за логаритмуване вид

Am I evil?
Yes I am.
Отговор
в отговор на Hateras #3

Re: Проблем с ADO & MSSQL

Със стринг при всички случаи няма да стане. Първата #0 ще го отреже. Пробвай това ShowMessage('1234567890'#0'abcdef'); например. Трябва да се извлече в някакъв буфер или поток. Но за ADO-то аз не мога да ти помогна

Животът не се мери с броя вдишвания, а с моментите, които спират дъха ни!
Отговор
в отговор на andrew_nikoloff #4

Re: Проблем с ADO & MSSQL

Андрю, ти пробва ли го това дето го предлагам, или по принцип?

начи почни един нов проект, турни едно копче и закачи тоя код за клика:

procedure TForm1.Button1Click(Sender: TObject);
var
v : variant;
s : string;
j : integer;
begin
v := #$31#$32#$00#$34#$35; //same as ADOQuery.FieldByname('...').value
s := v;
showmessage(s);
for j := 1 to length(s) do begin
if ord(s[j]) = 0 then s[j] := '_';
end;
showmessage(s);
end;

Am I evil?
Yes I am.
Отговор
в отговор на Hateras #5

Length(s)...

Всъщност важното е, че Length(s) си връща правилният резултат. Това не го знаех...Значи ще стане

Животът не се мери с броя вдишвания, а с моментите, които спират дъха ни!
Отговор
в отговор на andrew_nikoloff #6

Re: Length(s)...


и аз не го знаех - преди време (когто го научих) бях издивял с едно едит-че - аз ги броя 10, лена казва 15...

сега остава да се провери дали ADO-то пуска всички байтове, или реже при първи 0x00

Am I evil?
Yes I am.
Отговор
в отговор на Hateras #7

Re: Length(s)...

Проблемът с ShowMessage и TEdit е, че ползват TControl .GetText .SetText, с параметър PChar, коeто естествено води до рязане при първия #0.
При обикновените String-ове няма такива проблеми.

Заблуждаващото е
type
TCaption = type String;
...
property Caption: TCaption ...

Отговор
в отговор на Питaщ #8

Re: Проблем с ADO & MSSQL

Проблема не е в променливата от тип String. В такава променлива може да се запише и прочете символен низ, съдържащ всякакви символи, включително и #0. Проблема е в самото извличане от MSSQL базата чрез ADO. Същите тези данни са вкарани в базата също с TADOQuery с Insert в него и ADOQuery.Parameters.ParamByName('Param').Value := S, където S е String.
Данните са правилни. Проблема е само при извличането.

Отговор
в отговор на Питaщ #9

Re: Проблем с ADO & MSSQL

Това, най-вероятно е бъг в TCustomADODataSet.

Виж тук:
[линк]

HTH

Отговор