![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
VARCHAR(15000) ??? [IB6.x, FB]
GanibalLector © (2004-10-08 00:44:00)Насколько это опасно???
З.Ы. Это не поле в таблице,это выходой параметр в ХП.
З.З.Ы. Просто меня уморило делать UDF для преобразования в BLOB.
Johnmen (2004-10-08 10:04:00) [1]>GanibalLector © (08.10.04 09:51) [7]
В любом встречном вопросе есть доля намека. А в этом особенно. Ведь ты же, наверно, задумался, а чёй то он (т.е. я) задаёт такой (не очень в тему) вопрос ?
GanibalLector (2004-10-08 09:51:00) [2]2 Johnmen ©
Вот там, на что ты дал ссылку...:)
То,похоже не на намек,а на вопрос.Без обид
Johnmen (2004-10-08 09:45:00) [3]>Где это Вы намекали???Вроде постов Ваших не было.
Вот там, на что ты дал ссылку...:)
GanibalLector (2004-10-08 09:39:00) [4]2 Digitman © (08.10.04 09:04) [3]
Дело в том,что написал см. http://www.delphimaster.ru/cgi-bin/forum.pl?id=1097164914&n=1.Работает так
BL= BlobCat(некоторое поле,еще один BLOB)
когда делаю так:
BL= BlobCat(некоторое поле,BL) то в BLOBe сохраняется только последнее значения "некоторого поля"
Ну да ладно,ща я подключу Вашу...посмотрю.Спасибо как всегда.
2 Johnmen © (08.10.04 09:34) [4]
>Так я и намекал, что это проще. До 32000.
Где это Вы намекали???Вроде постов Ваших не было.
Johnmen (2004-10-08 09:34:00) [5]>сделал выходным параметром varchar(15000) и наступило СЧАСТЬЕ.
Так я и намекал, что это проще. До 32000.
Digitman (2004-10-08 09:04:00) [6]
> Просто меня уморило делать UDF для преобразования в BLOB
значит, ты чего-то недопонимаешь ..
никаких сложностей в этом нет
function InternalGetBlobSegment(Blob: PBlob; Buffer: Pointer; BufSize: ULong): ULong;
var
TotalBytesRead: Integer;
begin
TotalBytesRead := 0;
if Assigned(Blob) then with Blob^ do
if Assigned(BlobHandle) and Assigned(GetSegment)
and Boolean(GetSegment(BlobHandle, Buffer, Min(BufSize, MaxSegmentLength), TotalBytesRead)) then
Result:= TotalBytesRead
else
Result:= 0;
end;
function InternalGetBlob(Blob: PBlob; Buffer: Pointer; Size: Integer): ULong;
var
BytesRead: Integer;
begin
Result:= 0;
if Assigned(Blob) then with Blob^ do
if Assigned(BlobHandle) and Assigned(GetSegment) then
while (Size > 0) do
begin
BytesRead := InternalGetBlobSegment(Blob, PChar(Buffer) + Result, Size);
if BytesRead = 0 then
Break;
Inc(Result, BytesRead);
Dec(Size, BytesRead);
end;
end;
function InternalPutBlob(Blob: PBlob; Buffer: Pointer; Size: Integer): ULong;
var
BytesToWrite: Integer;
begin
Result:= 0;
if Assigned(Blob) then with Blob^ do
if Assigned(BlobHandle) and Assigned(PutSegment) then while (Size > 0) do begin
BytesToWrite:= Min(DefaultBlobSegmentSize, Size);
PutSegment(BlobHandle, PChar(Buffer) + Result, BytesToWrite);
Dec(Size, BytesToWrite);
Inc(Result, BytesToWrite);
end;
end;
function StringToBlob(Value: PChar; Blob: PBlob): PBlob; cdecl;
begin
Result:= Blob;
if Assigned(Result) and Assigned(Value) then
with Result^ do
try
if Assigned(BlobHandle) and Assigned(PutSegment) then
InternalPutBlob(Result, Value, StrLen(Value) + 1)
else
Result:= nil;
except
Result:= nil;
end;
end;
function BlobToString(Blob: PBlob): PChar; cdecl; //free_it
var
bytes_read: Longint;
begin
Result:= nil;
if Assigned(Blob) then
with Blob^ do
try
if Assigned(BlobHandle) and (TotalSize > 0) and Assigned(GetSegment) then
begin
Result := ib_util_malloc(TotalSize + 1);
bytes_read := InternalGetBlob(Blob, Result, TotalSize);
Result[bytes_read] := #0;
end;
except
Result:= nil;
end;
end;
declare external function StringToBlob
cstring(32767), blob
returns parameter 2
declare external function BlobToString
blob
returns cstring(32767) free_it
GanibalLector (2004-10-08 01:51:00) [7]2 kaif
Кстати,по поводу UDF.Откуда они были взяты???
З.Ы. Естественно интересует *.drp от ib_udf.dll
kaif (2004-10-08 01:43:00) [8]Да вроде спокойно можно такие вещи делать. Подумаешь! В конце-концов это всего 15К. Прикинь, что это jpeg-файл. Стал бы ты спрашивать про то, может ли быть такой большой jpeg? Какой же он большой? Совсем даже небольшой. Я не удивлюсь, если и 30K спокойно заработает. Это же не поле таблицы, на которое хочется индекс повесить?
Возьмем какую-нибудь UDF. Например:
DECLARE EXTERNAL FUNCTION RTRIM CSTRING(32767)
RETURNS CSTRING(32767) FREE_IT
ENTRY_POINT 'IB_UDF_rtrim' MODULE_NAME 'ib_udf';
Как видим, народ не скупится на длину параметра. А нафик такой длинный параметр? Откуда-то ведь предполагается в него данные-то передавать... Значит правда написана, что VARCHAR может иметь такие длины. Я бы просто на тормоз попробовал - и все дела. Единственная опасность - тормоз получить. Если тормоза не заметил бы - вообще даже думать бы не стал про какие-то там "опасности". Не мегабайт и не гигабайт. Вшивых 15K. Так что, ИМХО, нормально. Однако вот как-то нужно все же гарантировать, чтобы за длину не выскочить. Иначе неприятности будут.
Я обычно ограничиваю длины (если они могут выскочить, например, после конкатенации в ХП). Использую strlen, чтобы длину измерить и substr, чтобы обрезать, если выскочила:
DECLARE EXTERNAL FUNCTION substr
CSTRING(32767), SMALLINT, SMALLINT
RETURNS CSTRING(32767) FREE_IT
ENTRY_POINT 'IB_UDF_substr' MODULE_NAME 'ib_udf';
DECLARE EXTERNAL FUNCTION strlen
CSTRING(32767)
RETURNS INTEGER BY VALUE
ENTRY_POINT 'IB_UDF_strlen' MODULE_NAME 'ib_udf';
Правда я редко работаю с длинами больше 1K.