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

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

Работа с полем BLOB, очень жду [D7, MySQL]


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

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-01 13:16:00) [21]

Решил попробовать добавлять значения через Insert и возник очередной вопрос:
Как можно параметру в запросе передать БЛОБ.
ADO параметры не поддерживают LoadFromStream, но за то им можно присвоить уже установленные данные из другого TParameters вот тут возникает еще один вопрос как сделать свой элемент класса TParameters?


sniknik   (2006-06-01 11:21:00) [22]

> если они есть то возникает InvalidArgument
значит поле в базе не блоб, других вариантов нет. может в MySql под типом blob чтото другое понимается... или есть различия у самого типа.

хотя нет, есть еще вариант, "чудит" провайдер данных (MyODBC3.51), "заточен" под чтото другое, а данных для ADO полностью не предоставляет.


Romul   (2006-06-01 10:32:00) [23]

Чтение происходит нормально только в том случе если данных в блоб поле нет, если они есть то возникает InvalidArgument


sniknik   (2006-06-01 09:10:00) [24]

> оно становится VarByte....
это козни дьявола, не иначе... пригласи священника на крестный ход, пусть по квартире походит, монитор святой водой окропит, бесовская сила из него и уйдет...

p.s. я так понял чтение уже нормально проходит? т.е. первоначальная "проблема" устранена? ну и с этим теперь тоже разбирайся...


Romul   (2006-06-01 01:22:00) [25]


procedure TForm1.Button1Click(Sender: TObject);
var BField: TBlobField;
begin
BField:=TBlobField(ADODataSet1.FieldByName('RepData'));
Stream := TADOBlobStream.Create(BField, bmRead);
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
 FileStream:= TFileStream.Create('c:\test.dat', fmCreate or fmShareDenyRead);
 try
   if Stream.Size <> 0 then
   begin
     Stream.Position:= 0;
     FileStream.CopyFrom(Stream, Stream.Size);
   end;
 finally
   Stream.Free;
 end;
end;

procedure TForm1.Button3Click(Sender: TObject);
begin
 ADODataSet1.Open;
 ADODataSet1.Edit;
 if ADODataSet1.FieldByName('RepData').IsBlob then
 Label1.Caption:='blob';
end;

procedure TForm1.Button4Click(Sender: TObject);
var  FileStream1: TFileStream;
begin
 FileStream1:= TFileStream.Create('c:\up.sql', fmOpenRead or fmShareDenyRead);
 Stream.CopyFrom(FileStream1, FileStream1.Size);
 FileStream1.Free;
end;

procedure TForm1.Button5Click(Sender: TObject);
begin
 ADODataSet1.Post;
end;


После первого сохранения любых данных поле перестает опознаваться как blob оно становится VarByte....


sniknik   (2006-05-31 21:09:00) [26]

+
> Кидаю qry на форму, заполняю SQL, двойной щелчек, Add all fields. и все.
какого типа определяется/создается поле RepData? TBlobField надеюсь? т.е. что после этого записалось в описание класса формы.


sniknik   (2006-05-31 20:34:00) [27]

> Stream := TADOBlobStream.Create(TBlobField(DMMain.qryGetReports.FieldByName('RepData')), bmRead);
вот это правильно, можно так, даже перепроверил... (правда на access, MySQL-я счас не стоит, но должно быть не важно)
совершенно непонятно почему неверный аргумент(InvalidArgument)... может у тебя используется модуль какой нибудь в котором TADOBlobStream или TBlobField перекрыт? в том же модуле репорта который я просил убрать (вообще ничего лишнего!)

> потом
> InvalidVariantType
а вот это скорее всего на чтении происходит, ну вообщето непонятно создался поток или нет от предыдущей ошибки... но если создался то еще глюк, чтение из NULL поля, надо проверять.
try
 if Stream.Size <> 0 then begin
   Stream.Position := 0;
   frReport.LoadFromStream(Stream);
 end;
finally
  Stream.Free;
end;

и вообще убери все, все лишнее, вообще. оставь минимум и только стандартное, новый проект, форму, пару ADO компонент (кстати я не пользуюсь ADOQuery (и не буду!), а только ADODataSet-ом, проверял на нем (1й абзац)), копируй не в репорт, а в файловый поток к примеру (он стандартный)...

FileStream:= TFileStream.Create('путь и файл какой нибудь', fmCreate or fmShareDenyRead);
try
 if Stream.Size <> 0 then begin
   Stream.Position:= 0;
   FileStream.CopyFrom(Stream, Stream.Size);
 end;
finally
  Stream.Free;
end;
ну типа того, по кнопке выполнить, руботает?... а то уже начали разные нехорошие подозрения по поводу репорта возникать...


Romul   (2006-05-31 19:39:00) [28]

Хорошо, тогда выдрав кусок из fastreport копирования в stream делаю по образу и подобию

 DMMain.qryGetReports.Close;
 DMMain.qryGetReports.Parameters.ParamByName('FName').Value:=FromForm;
 DMMain.qryGetReports.Open;

 Stream := TADOBlobStream.Create(TBlobField(DMMain.qryGetReports.FieldByName('RepData')), bmRead);

 try
   Stream.Position := 0;
   frReport.LoadFromStream(Stream);
 finally
   Stream.Free;
 end;


и прога ругается следующим образом на строчке  Stream := TADOBlobStream.Create:
сначала
InvalidArgument
потом
InvalidVariantType

что то у меня такое ощущение что я не в ту сторону капаю....


sniknik   (2006-05-31 18:01:00) [29]

> при обращении к Blob полю как к потоку(TMemoryStream)
а ты не обращайся... говорил же поставь грид, он тоже обращается. он работает? а у тебя значит неправильно.  (естественно неправильно если "к Blob полю как к потоку(TMemoryStream)", надо не конвертить обращаясь как, а в поток из поля копировать... но это уже забегание вперед, обсуждение второй 17й строки не видя ее...)


Romul   (2006-05-31 17:47:00) [30]

Опять же это возникает когда данные есть базе, если их нет то все проходит великолепно


Romul   (2006-05-31 17:43:00) [31]

Если без предварительного объявления полей все делать, то возникает ошибка InvalidTypeCast при обращении к Blob полю как к потоку(TMemoryStream)


sniknik   (2006-05-31 17:27:00) [32]

> По желаниям трудящихся прилагаю "17 строку кода"
> Обращение к ADOQuery
и сразу же стало на "полшага" понятнее

> DMMain.qryGetReports.ExecSQL;
вот это глюк. раз.
или ExecSQL или Open, а еще лучше перейди на родные ADODataSet, ADOCommand у них четкое деление возвращающие/невозвращающие рекордсет запросы.

> frReport.LoadFromBlobField(DMMain.qryGetReportsRepData);
> frReport.PrepareReport;
> frReport.ShowReport;
вот это убери... пока, хотя бы.  ты же "грешиш" на ADO, а тут лишняя сущность, лучше добавь дбгрид и "привяжи" его к рекордсету для визуальности того что получаеш. работает?

все поля в дизайне созднные тоже убери. и т.д. ничего лишнего, кроме тестируемого ничего не должно остатся. после понемногу будеш добавлять/восстанавливать.


Romul   (2006-05-31 16:41:00) [33]

По желаниям трудящихся прилагаю "17 строку кода"
Обращение к ADOQuery

 DMMain.qryGetReports.Close;
 DMMain.qryGetReports.Parameters.ParamByName('FName').Value:=FromForm;
 DMMain.qryGetReports.ExecSQL;
 DMMain.qryGetReports.Open;
 frReport.LoadFromBlobField(DMMain.qryGetReportsRepData);
 frReport.PrepareReport;
 frReport.ShowReport;


Текст запроса

Select * from reports
where FormName=:FName


Скрипт создающий таблицу в БД

DROP TABLE IF EXISTS `reports`;
CREATE TABLE `reports` (
 `ID` int(10) unsigned NOT NULL auto_increment,
 `ReportName` varchar(100) NOT NULL default '',
 `RepData` blob,
 `ReportQuery` varchar(500) NOT NULL default '',
 `FormName` varchar(45) NOT NULL default '',
 PRIMARY KEY  (`ID`)
) ENGINE=InnoDB DEFAULT CHARSET=cp1251;

Создание полей в ADOQuery делаю следующим образом:
Кидаю qry на форму, заполняю SQL, двойной щелчек, Add all fields. и все.

Ошибка возникает на строке DMMain.qryGetReports.Open;


sniknik   (2006-05-31 16:10:00) [34]

> При запросе они и устанавливаются в те, которые стоят в базе
отлично! и зачем же тогда типу уже имеющему значение ftBlob еще раз устанавливать ftBlob? что от этого меняется?
смысла нет.
т.е. либо ты  меняеш на другой, априори неверный тип, либо ошибка в чемто другом. (в 17-й строке например)


Romul   (2006-05-31 16:04:00) [35]

При запросе они и устанавливаются в те, которые стоят в базе, и при открытии без данных они не вызывают ошибки, а если в этом поле появились данные, то тогда и возникает ошибка.


sniknik   (2006-05-31 15:53:00) [36]

не надо ставить у поля параметры отличные от типа поля в базе(таблице), их вообще не надо выставлять, создавать поле, если само оно не нужно, типы получаются при запросе, правильные.


Romul   (2006-05-31 15:41:00) [37]

Забыл добавить, ошибка возникает при открытии датасета


Romul   (2006-05-31 15:40:00) [38]

Если не секрет, то как мне при помощи того что вы указали избвится от переконвертации, которая происходит при установке поля типа blob?
Если в ADODataSet добавить поле, которое в базе MySQL5.0 хранится как blob, и указать в датасете при добавлении поля тип blob, то при отсутствии данных в этом поле все проходит нормально, но после того к в этом поле появились данные возникает ошибка: Type mistmach for field "FieldName" expecting:'Blob' actual 'VarBytes'.
Такая же фигня происходит и с полями типа ТЕХТ


Johnmen   (2006-05-31 12:21:00) [39]

TBlobField, TBlobStream, TADOBlobStream etc.


Romul   (2006-05-31 12:02:00) [40]

Подскажите хотябы компонент в котором можно спокойно работать с blob полями...
Плиззззз....


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

Наверх

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