![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Работа с полем BLOB, очень жду [D7, MySQL]
Romul © (2006-05-30 17:31:00)Связка слудующая:
D7 + ADO + MyODBC3.51 + MySQL5,0
Есть таблица в которой есть поле BLOB.
Когда в датасете стоит ftBlob и есть данные то делфи ругается на то что в реально передается varbyte, а ожидается blob,
Когда тип поля ставиш varbyte то у делфи начинается кризис с размерностью данных, типа того размер установлен 10000, а на самом деле 980...
А если нет данных то ругается на то, что стоит VarByte, а на самом деле возвращается Blob...
Подскажите может кто уже решал подобную проблему?
Blob используется для храниния FastReport отчетов.
Romul (2006-06-02 01:33:00) [1]Сейчас проверил, первые 2 байта определяют длину записи.
Romul (2006-06-02 01:18:00) [2]У меня возникло такое странное ощущение, что тип поля blob определяется не от реально указанного Datatype в таблице, а от максимального размера поля которое возвращается в датасет.
Короче, получается удаление гланд через задний проход :(
И надо делать как минимум 2 реакции на то, что возвращается...
Если размер в байтах не влезает в 2 байта, то тогда опознается как blob иначе опазнается varchar, и в данных возвращаемых в GetData первые 2 байта лишние. При чем, это касается только полей типа blob (определенных в таблице). По крайней мере, для полей типа VarChar не надо удалять первые 2 байта, там все происходит норамльно.
У меня даже почти возникло желание написать что нить наподобии How to для такой связки D7 - ADO - MySQL ODBC3.51 - MySql, но вот по версиям сервара, что-то нет особого желания проверять.
sniknik (2006-06-01 18:22:00) [3]> а если оно longblob то и ни каких ухищерений не надо все понимается как блоб.......
значит тип longblob в mysql этот блоб, а blob это чтото другое. перечитай [20], а TypeCast не трогай он определил уже милиарды раз разные типы, и все правильно, думаеш это был отвлекающий маневр специально тебя запутать?
Romul (2006-06-01 18:08:00) [4]Я сейчас по поводу этого нехорошешего TypeCast буду говорить много нехороших слов.....
если поле является blob то делфя его понимает как VarByte....
а если оно longblob то и ни каких ухищерений не надо все понимается как блоб.......
Romul (2006-06-01 18:03:00) [5]ни фига, если GetData натравливать на array of byte то вылетает с ошибкой...
при этом еще надо первые 2 байта выкинуть, они там однозначно лишнии
Johnmen (2006-06-01 17:58:00) [6]
> но вот точно там не должно быть DBNavigator-а иначе вылетает
> Accsecc Vialation,
Да ну перестань.
sniknik (2006-06-01 17:57:00) [7]> К датасету не должно быть ничего привязано.....
ну если у тебя привязано чтото у чего есть написаная тобой обработка событий... то не удивительно.
Romul (2006-06-01 17:56:00) [8]хотя нет, погорячился DataSource может быть но вот точно там не должно быть DBNavigator-а иначе вылетает Accsecc Vialation,
sniknik (2006-06-01 17:55:00) [9]> А разве GetMem не выделяет область памяти?
она то выделяет, но пишеш то ты, и пишеш в переменную, а не в выделенную память, а в переменной только указатель. все что за ним стирается.
замени PByteArray на array of byte, а GetMem на SetLength. не умееш с
указателями работать.
Johnmen (2006-06-01 17:50:00) [10]
> К датасету не должно быть ничего привязано.....
Да ну перестань.
Romul (2006-06-01 17:47:00) [11]Поэксперементировал с полями других типов...
Короче для полей отличных от blob, которые распознаются как VarByte, все работает великолепно... и не возникает ни каких ошибок
У меня уже просто едет крыша над решением вопроса "что такое вечный кайф и как с ним бороться"....
УРАААААААА
НАШЕЛЛЛЛЛЛЛЛ
К датасету не должно быть ничего привязано.....и тогда такая конструкция позволяет записать все из поля блоб в файл
Romul (2006-06-01 17:27:00) [12]Вот полный текст процедуры
procedure TForm1.Button4Click(Sender: TObject);
var buf: PByteArray;
buf1: array of byte;
ds: integer;
i: integer;
FS: TFileStream;
begin
ADODataSet1.Open;
with ADODataSet1.Fields[0] do
begin
if not IsBlob then
begin
ds:=DataSize;
SetLength(Buf1, ds);
GetMem(Buf, ds);
try
if not GetData(Buf) then
MessageDlg(DisplayName + ' is NULL', mtInformation, [mbOK], 0)
else
begin
for i:=0 to ds-1 do Buf1[i]:=Buf[i+2];
FS:= TFileStream.Create('c:\1.bmp', fmCreate or fmShareCompat);
FS.Position:=0;
for i:=0 to ds-3 do FS.Write(Buf1[i],1);
end;
finally
SetLength(Buf1,0);
FS.Free;
FreeMem(Buf, ds);
end;
end;
end;
ADODataSet1.Close;
end;
при таком обращении с буфером данные сохраняются,
вся память выделяется, все за собой чистится.
Но Accsess Valation все равно вылазиет....
Romul (2006-06-01 16:39:00) [13]А разве GetMem не выделяет область памяти?
sniknik (2006-06-01 16:02:00) [14]потому, что параметр Buf неверного типа/неправильно передается. вместо записи по нему в выделенную бласть памяти, записывается в него и дальше перетирая все что лежит следом за ним (код например).
Romul (2006-06-01 15:00:00) [15]Тогда у меня возник еще один вопрос
есть следующий код
ADODataSet1.Open;
with ADODataSet1.Fields[0] do
begin
if not IsBlob then
begin
{ Allocate space }
ds:=DataSize;
GetMem(Buf, ds);
try
if not GetData(Buf) then
MessageDlg(DisplayName + ' is NULL', mtInformation, [mbOK], 0)
else
begin
FS:= TFileStream.Create('c:\1.bmp', fmCreate or fmShareCompat);
FS.Position:=0;
FS.WriteBuffer(Buf,ds);
end;
finally
FreeAndNil(fs);
FreeMem(Buf, ds);
Image1.Picture.LoadFromFile('c:\1.bmp');
end;
end;
end;
почему может вылетать ошибка Accsess Violation на любом операторе после FS.WriteBuffer(Buf,ds);
sniknik (2006-06-01 13:50:00) [16]> Примерная проблема обсуждалась на форуме MySQL
> ...
эта "проблема" рядом с твоей "и близко не лежала", там обсуждают как сохранить jpg минуя dbimage т.к. не поддерживает. никаких проблем с сами сохранением... у тебя же именно само сохранение и никакого jpg.
(эдак все пересакаюшееся по единому общему термину можно назвать "примерно та же"...)
Romul (2006-06-01 13:40:00) [17]Пардон, нашел
Romul (2006-06-01 13:38:00) [18]Хорошо, может тогда сможете объяснить такой трюк хелпа:
Находим TCustomADODataSet -> Properties -> Parameters -> TParameters->Methods
и тут мы не видим ни одной ссылки на методы типа LoadFrom....
Romul (2006-06-01 13:27:00) [19]Примерная проблема обсуждалась на форуме MySQL
http://forums.mysql.com/read.php?49,79243,84633#msg-84633
Но вот только у меня возникли вопросы как это можно сделать в реалии?
sniknik (2006-06-01 13:25:00) [20]> ADO параметры не поддерживают LoadFromStream
что значит не поддерживают??? знаеш если ты любое своенезнание, неспосбность найти (в очевидном надо сказать месте), будеш "обьяснять" подобным образом... далеко не "уедеш".
> как сделать свой элемент класса TParameters?
ну отбросив то что на самом деле это не нужно, отвечая буквально, то также как все остальные элементы классов TParameters.Create(...);