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

Вниз

Чтение и запись в BLOB с помощью UDF в IB   Найти похожие ветки 

 
Patrick   (2002-06-24 10:33) [0]

Уже задавал вопрос про работу с BLOB полями посредством UDF
У меня никак не получается нормально прочитать и перезаписать информацию, содержащуюся в BLOB.
Например после запуска процедуры, приведённой ниже, вся информация из поля исчезает, независимо от количества строк в поле. Также пробовал побайтное чтение и запись из поля, результат тот же. Уже не знаю как поступить.
Подскажите что-нибудь, please.

function AddToBlob(Value: PChar; Blob: PBlob): PBlob; cdecl; export;
var total_bytes_read, bytes_left, bytes_read : Long;
Buffer : PChar;
ind : integer;
st : string;
begin
Result := Blob;
if (not Assigned(Blob)) or
(not Assigned(Blob^.BlobHandle)) then exit;
GetMem( Buffer, Blob^.MaxSegmentLength);
ind := 1;
repeat
Blob^.GetSegment(Blob^.BlobHandle, Buffer, Blob^.MaxSegmentLength, bytes_read);
Result^.PutSegment(Result^.BlobHandle, Buffer, bytes_read);
Inc( ind, 1);
until (ind >= Blob^.SegmentCount);
FreeMem(Buffer);
Blob := Result;
// Result^.PutSegment(BlobHandle, Buffer + Value, total_bytes_read + StrLen(Value));
end;


 
Digitman   (2002-06-24 12:38) [1]

function AddToBlob(Value: PChar; SrcBlob, DstBlob: PBlob): PBlob; cdecl; export;
var total_bytes_read, bytes_left, bytes_read : Long;
Buffer : PChar;
ind : integer;
st : string;
begin
Result := DstBlob;
if not Assigned(Result) or
not Assigned(Result.BlobHandle) or
not Assigned(Result.PutSegment) or
not Assigned(SrcBlob) or
not Assigned(SrcBlob.BlobHandle) or
not Assigned(SrcBlob.GetSegment) then
exit;
GetMem( Buffer, SrcBlob.MaxSegmentLength);
try
ind := 1;
repeat
SrcBlob.GetSegment(SrcBlob.BlobHandle, Buffer, SrcBlob.MaxSegmentLength, bytes_read);
Result.PutSegment(Result.BlobHandle, Buffer, bytes_read);
Inc(ind, 1);
until (ind >= SrcBlob.SegmentCount);
Result.PutSegment(Result.BlobHandle, Value, StrLen(Value) + 1);
finally
FreeMem(Buffer);
end;
end;


 
Digitman   (2002-06-24 14:14) [2]

Ну вот же я тебе объяснял по поводу Blob"ов :

http://delphi.mastak.ru/cgi-bin/forum.pl?look=1&id=1023945063&n=1

снова ту же ошибку делаешь)

вот смотри, что здесь к чему :

Value: PChar - адрес строки, добавляемой к тек.содержимому некоего Blob-поля

SrcBlob: PBlob - упр.структура того самого "некоего", уже существующего Blob-поля, в конец которого ты пытаешься добавить строку

DstBlob: PBlob - а это - тот самый неявный параметр, являющийся управляющей Blob-структурой, которую IB создает и инициализирует "прозрачно" для тебя, видя что ты требуешь возврата из своей UDF неких Blob-данных. Этот самы неявный параметр и нужно использовать для возврата UDF-результата, поэтому в тексте так или иначе должна присутствовать строчка Result:= DstBlob. После выполнения этой строчки обращение к Result и к DstBlob эквивалентны (как тебе удобней).
И, поскольку DstBlob-параметр создается неявно , его нужно описывать в ISQL-скрипте, регистрирующем такую UDF для последующего обращения к ней, но при вызове такой UDF последний параметр указывать не нужно !!
Иными словами, в дан.случае скрипт должен определять всего 3 входных (1 - Value , 2 - SrcBlob, 3 - DstBlob) и 1 выходной (parameter 3) параметры, а вот вызов UDF (например, в триггере обновления) выглядеть так :
new.blobfield = AddToBlob("Добавляемая строка", old.blobfield);

Как видишь, 3-й параметр в вызове не указан, тем не менее операция
new.blobfield = old.blobfield + "Добавляемая строка"
будет успешно выполнена !

P.S. Успешно, если только old.blobfield <> Null, потому как эту ситуацию ты не предусмотрел в коде UDF и результатом будет пустой Blob


 
Patrick   (2002-06-25 16:11) [3]

Огромное спасибо за присланное решение вопроса,

я вставил перевод строки в добавляемую строку

function AddToBlob(Value: PChar; SrcBlob, DstBlob: PBlob): PBlob; cdecl; export;
var bytes_read : Long;
Buffer : PChar;
ind : integer;
begin
Result := DstBlob;
if not Assigned(Result) or
not Assigned(Result.BlobHandle) or
not Assigned(Result.PutSegment) or
not Assigned(SrcBlob) or
not Assigned(SrcBlob.BlobHandle) or
not Assigned(SrcBlob.GetSegment) then
exit;
GetMem( Buffer, SrcBlob.MaxSegmentLength);
try
ind := 1;
repeat
SrcBlob.GetSegment(SrcBlob.BlobHandle, Buffer, SrcBlob.MaxSegmentLength, bytes_read);
Result.PutSegment(Result.BlobHandle, Buffer, bytes_read);
Inc(ind, 1);
until (ind >= SrcBlob.SegmentCount);
Result.PutSegment(Result.BlobHandle, PChar(String(Value) + #13#10), StrLen(Value) + 2);
finally
FreeMem(Buffer);
end;
end;

всё работает успешно, но только один раз
строка добавляется в BLOB, но при повторном запуске
фрагмента SQL,например

update complect
set history = AddToBlob("Добавляемая строка 2",history)
where complectcode = 0;

предыдущее добавление "Добавляемая строка 1"
заменяется на "Добавляемое значение 2"
перепробовал различные варианты, возникает такое подозрение, что предыдущий фрагмент как-бы не фиксируется.

И кстати попутный вопрос, как внутри UDF определить, что значение SrcBlob - null, я так понял, что указатель на структуру в этом случае равен nil или функция assigned(SrcBlob)=false.Я прав или не совсем.
заранее благодарен.


 
Digitman   (2002-06-25 17:39) [4]

1. Ну почему же until (ind >= SrcBlob.SegmentCount) ?
А если Blob состоит, к примеру, из 2-х сегментов ? 2-й сегмент ты не прочитаешь из-за неверного условия.

Переделай цикл :
ind := 0;
While ind < SrcBlob.SegmentCount do
begin

... читаешь очер.сегмент

if bytes_read > 0 then // пропуск пустых сегментов
... записываешь очер. непустой сегмент
Inc(Ind); //сч-к перезаписанных сегментов
end;


2.

Да. Null в IB соответствует nil в Delphi



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

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

Наверх





Память: 0.47 MB
Время: 0.006 c
3-57959
Андрусь
2002-06-25 11:27
2002.07.18
Сохранение настроек в базе


3-57957
nimble
2002-06-26 08:54
2002.07.18
Подключение


1-58160
Maikl
2002-07-05 09:54
2002.07.18
Анализ файлов (Формат Doc)


1-58094
Alex
2002-07-08 16:01
2002.07.18
Active:=True;


14-58320
Unown
2002-06-02 11:00
2002.07.18
Как создать?





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