Форум: "Базы";
Текущий архив: 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