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

Вниз

ADO + Ora = пропихнуть в хранимку blob более 32 кбайт   Найти похожие ветки 

 
Es   (2012-08-16 16:02) [0]

Имеется хранимка на сервере Oracle, один из входящих параметров blob:

...
i_FILE_BODY in blob,
...


Имеем TAdoConnection и TADOStoredProc, натравленный на хранимку.
Тип параметра указан как ftBlob. Грузится как [AddParam].LoadFromStream(..., ftBlob)

При execute получаем ошибку:

ORA-01460: затребовано нереализованное или неразумное преобразование
http://www.onlinedisk.ru/get_image.php?id=928134

Что за фигня с ADO? Что он такого делает, что потом ругается ОРАКЛ со СВОЕЙ стороны?

Эксперименты показали, что если сформировать большой блоб на стороне сервера (мегабайт на 15) и запихнуть его в хранимку - то все здорово и беспроблемно. Но если с дельфового клиенту через ADO указанным выше способом - то облом.

Провайдер используется родной: OraOLEDB.Oracle.1 (так как в MS"ном вообще blob не поддерживается).
Клиент Win 7, ора 11g на nix.

Кто-нибудь сталкивался еще с таким бредом?


 
AV ©   (2012-08-16 16:16) [1]

ага,
переделал через query

 oqTmp.sql.text := "Update SUBSCRIBER set PIC=EMPTY_BLOB() Where ID_SUBSCRIBER = :ID_SUBSCRIBER RETURNING PIC INTO :PIC";
 oqTmp.ParamByName("PIC").ParamType := ptInput;
 oqTmp.ParamByName("PIC").DataType := ftOraBlob;
 oqTmp.ParamByName("PIC").AsBLOBLocator.LoadFromFile(dlgOpenPic.FileName);
 oqTmp.ParamByName("ID_SUBSCRIBER").asinteger := FSubscriber;
 oqTmp.ExecSQL;


 
QAZ   (2012-08-16 16:41) [2]

а зачем человеки вообще пихают в базы всякие блобы с картинками ?
почему их не хранить файлами а в базе хранить адрес?


 
DVM ©   (2012-08-16 16:43) [3]


> QAZ   (16.08.12 16:41) [2]
> а зачем человеки вообще пихают в базы всякие блобы с картинками
> ?
> почему их не хранить файлами а в базе хранить адрес?

удобно потому что


 
AV ©   (2012-08-16 16:43) [4]


> QAZ   (16.08.12 16:41) [2]

Все в одном, ничего не потеряется
или потеряется все :)


 
имя   (2012-08-16 16:46) [5]

Удалено модератором


 
QAZ   (2012-08-16 16:47) [6]

а резервировать и тд?


 
DVM ©   (2012-08-16 16:47) [7]


> AV ©   (16.08.12 16:43) [4]

Да кроме этого причин хранить бинарные данные в базе масса, а вот причин не хранить и хранить в файлах я не знаю ни одной.


 
DVM ©   (2012-08-16 16:50) [8]

Удалено модератором


 
QAZ   (2012-08-16 16:51) [9]


> DVM ©   (16.08.12 16:47) [7]

ну наверно в базе нужно хранить то что можно искать,сортировать, это ведь основная идея существования баз данных?
а картинку то зачем мучить?


 
Es   (2012-08-16 16:55) [10]

Так никто в проблема не разбирался? Что за нафиг делает ADO с блобом при передачи, что у Оры крышу рвет?


 
DVM ©   (2012-08-16 16:55) [11]


>  QAZ  

Из прочих плюсов

1. Разграничение прав на уровне базы.
2. Гораздо легче открыть 1 порт для подключения к базе через интернет, чем городить доступ к файловому серверу и еще как то связывать пути на нем с записями в базе.
3. При хранении файлов отдельно от базы надо заботиться о том, чтобы ссылки всегда были верными и что делать при удалении файла?

Вообще на ibase.ru была статья для опасающихся хранить файлы в базе от создателей Firebird.


 
QAZ   (2012-08-16 16:56) [12]

Удалено модератором


 
AV ©   (2012-08-16 16:57) [13]


> Что за нафиг делает ADO с блобом при передачи, что у Оры
> крышу рвет?

Есть подозрение, что как -то не так размер передается
Но не разбирался до конца, тупо стал грузить запросом


 
Sergey Masloff   (2012-08-16 16:59) [14]

QAZ   (16.08.12 16:51) [9]
>ну наверно в базе нужно хранить то что можно искать,сортировать, это >ведь основная идея существования баз данных?
>а картинку то зачем мучить?
Не надо свое видение обобщать. Я лично из своего опыта согласен с DVM (с) и не вижу ни одной причины хнанить связанные данные в разных местах.

DVM ©   (16.08.12 16:50) [8]
>База же ограничена лишь размером максимального файла в фс.
И даже этим не ограничена.


 
Sergey Masloff   (2012-08-16 17:02) [15]

QAZ   (16.08.12 16:56) [12]
>нену как сорганизуеш,сдается мне что отображение картинки не самое >важное,и можно потерпеть загрузку при запросе
>даи всякие фрагментации баз за щет ненужной инфы тоже не убыстрят >процесс
Извини но ЯХДР от этого потока сознания ;-)
- что такое "потерять загрузку при запросе"
- про фрагментацию баз вообще достаточно смешно.


 
DVM ©   (2012-08-16 17:03) [16]


> QAZ   (16.08.12 16:56) [12]


> даи всякие фрагментации баз за щет ненужной инфы тоже не
> убыстрят процесс

Информация в файле базы записывается постранично, при удалении страницы помечаются как свободные, файл базы на диске как правило не уменьшается никогда сам пос себе, может только расти. Т.е фактически запись в базу - это просто запись в файл на диск в свободные страницы. Это по скорости примерно тоже самое что прямо писать в файл. Чуть-чуть медленнее, но самым медленным звеном тут всегда будет диск и сеть, а не сервер баз данных и какие то дополнительные обработки.


 
QAZ   (2012-08-16 17:07) [17]

Удалено модератором


 
DVM ©   (2012-08-16 17:12) [18]


> QAZ   (16.08.12 17:07) [17]
> нуи нахрена нужен файл где половина размера есть неиспользуемое
> место после удалений записей ?

Плата за удобство.

Есть правда один вариант, который я допускаю, но особенно хорошим его все же не считаю. Во многих СУБД можно сделать так (в Firebird например за счет написания своих расширений - udf), чтобы при загрузке файла на сервер баз данных он сохранялся не в базе а рядом с ней в файловой системе. И читался из файловой системы при попытке чтения из базы. Т.е к файлам в файловой системе доступ будет иметь только сервер субд, но прямого доступа извне к ним нет. Но у этого способа есть куча недостатков и они перевешивают единственное "достоинство" - файлы не лежат в базе.


 
QAZ   (2012-08-16 17:14) [19]


> Но у этого способа есть куча недостатков

какие


 
DVM ©   (2012-08-16 17:15) [20]


> QAZ   (16.08.12 17:07) [17]
> нуи нахрена нужен файл где половина размера есть неиспользуемое
> место после удалений записей ?

Это решаемо кстати на NTFS. Там есть понятие разреженные файлы - файлы которые имеют размер больше чем реально на диске занимают.


 
AV ©   (2012-08-16 17:17) [21]

имхо, все равно, наверное почти все субд, "форматируют" отведенное им место под себя и пишут данные блоками. Предпочтительно, кратными ФС.
Так что не особо "дырки" будут мешать


 
QAZ   (2012-08-16 17:17) [22]


> DVM ©   (16.08.12 17:15) [20]

врятли, ведь запись при удалении не зануляется


 
DVM ©   (2012-08-16 17:20) [23]


> QAZ   (16.08.12 17:17) [22]


> врятли, ведь запись при удалении не зануляется

Ее не надо занулять, достаточно сказать системе, что место от сих до сих (смещение в файле) не используется. Драйвер сам разберется что кому и куда. Я не знаю, использует ли эту возможность хоть одна из существующих субд.


 
QAZ   (2012-08-16 17:24) [24]

Удалено модератором


 
QAZ   (2012-08-16 17:26) [25]

чувствую что надо изобрести свою СУБД для ленивых батонокидателей дабы спасти,а потом поработить мир


 
DVM ©   (2012-08-16 17:26) [26]


> QAZ   (16.08.12 17:24) [24]


> далан, и какой функцией?

DeviceIoControl


 
DVM ©   (2012-08-16 17:27) [27]


> QAZ


////////////////////////////////////////////////////////////////////////////////
//
//  ****************************************************************************
//  * Модуль       : uNTFSFileStream.pas
//  * Назначение   : Класс файлового потока, реализующий доп. возможности NTFS
//  * Copyright    : 2012 © Дмитрий Муратов (dvmuratov@yandex.ru)
//  * Версия       : 1.0
//  * Дата         : 06.02.2012
//  ****************************************************************************
//
////////////////////////////////////////////////////////////////////////////////

unit uNTFSFileStream;

interface

{$I DEFINES.INC}

{$IFNDEF MSWINDOWS}
These streams are only usable in Windows!!!
{$ENDIF}

{$WARN SYMBOL_PLATFORM OFF}

uses
{$IFDEF DELPHIXE2_UP}
 Winapi.Windows, System.SysUtils, System.Classes;
{$ELSE}
 Windows, SysUtils, Classes;
{$ENDIF}

type
 TNTFSFileStreamOption = (fsoCompressed, fsoSparse, fsoTemporary, fsoEncrypted,
   fsoWriteThrough, fsoNoBuffering, fsoRandomAccess, fsoSequentialScan,
   fsoDeleteOnClose);

 TNTFSFileStreamOptions = set of TNTFSFileStreamOption;

 TNTFSFileStream = class(THandleStream)
 strict private
   FFileName: string;
   FMode: Word;
   FOptions: TNTFSFileStreamOptions;
   procedure SetCompression(const AHandle: THandle; const AEnabled: Boolean);
   procedure SetSparse(const AHandle: THandle);
   function CreateFile(const AFilename: string; const AMode: Word;
     const AOptions: TNTFSFileStreamOptions = []): THandle;
   function GetCompressed: Boolean;
   procedure SetCompressed(const AValue: Boolean);
 public
   constructor Create(const AFilename: string; const AMode: Word = fmCreate;
     const AOptions: TNTFSFileStreamOptions = []);
   destructor Destroy; override;
   procedure ZeroData(const AFileOffset: Int64 = 0; const ALength: Int64 = 0);
   procedure ZeroDataForTwoOffsets(const AFirstOffset, ALastOffset: Int64);
   procedure ZeroToCurrPosition;
   property Compressed: Boolean read GetCompressed write SetCompressed;
   procedure Recompress;
   procedure Decompress;
   procedure Compress;
   property FileName: string read FFileName;
   property Mode: Word read FMode;
   property Options: TNTFSFileStreamOptions read FOptions;
 end;



 
DVM ©   (2012-08-16 17:28) [28]


implementation

resourcestring
 rsCanNotEncryptFiles = "Can not encrypt files on a non-NT platform";
 rsFileIsNotSparse = "File "%s" is not sparse";

type
 TEncryptFile = function(lpFilename: PChar): BOOL; stdcall;

type
 TFileZeroDataInformation = record
   FileOffset: Int64;
   BeyondFinalZero: Int64;
 end;
 PFileZeroDataInformation = ^TFileZeroDataInformation;

var
 EncryptFile: TEncryptFile;

const
 FILE_ATTRIBUTE_SPARSE_FILE  = $80;
 FSCTL_GET_COMPRESSION       = $9003C;
 FSCTL_SET_COMPRESSION       = $9C040;
 FSCTL_SET_ZERO_DATA         = $980C8;
 FSCTL_SET_SPARSE            = $900C4;

 COMPRESSION_FORMAT_NONE     = 0;
 COMPRESSION_FORMAT_DEFAULT  = 1;

{ TNTFSFileStream }

procedure TNTFSFileStream.Compress;
begin
 Compressed := True;
end;

//------------------------------------------------------------------------------

constructor TNTFSFileStream.Create(const AFilename: string;
 const AMode: Word = fmCreate; const AOptions: TNTFSFileStreamOptions = []);
begin
 FFileName := AFilename;
 FMode := AMode;
 FOptions := AOptions;
 inherited Create(CreateFile(FFilename, FMode, FOptions));
end;

//------------------------------------------------------------------------------

function TNTFSFileStream.CreateFile(const AFilename: string;
 const AMode: Word; const AOptions: TNTFSFileStreamOptions): THandle;
var
 DesiredAccess: Cardinal;
 ShareMode: Cardinal;
 CreationDisposition: Cardinal;
 FlagsAndAttributes: Cardinal;
 Option: TNTFSFileStreamOption;
begin
 DesiredAccess := 0;
 ShareMode := 0;
 if (AMode and fmCreate) = fmCreate then
   begin
     if FileExists(AFilename) then
       if not DeleteFile(AFilename) then
         RaiseLastOSError;

     DesiredAccess := GENERIC_READ or GENERIC_WRITE;
     ShareMode := 0;
     CreationDisposition := CREATE_ALWAYS;

     FlagsAndAttributes := FILE_ATTRIBUTE_NORMAL;
     for Option := Low(TNTFSFileStreamOption) to High(TNTFSFileStreamOption) do
       if Option in AOptions then
         case Option of
           fsoTemporary: FlagsAndAttributes := FlagsAndAttributes or FILE_ATTRIBUTE_TEMPORARY;
           fsoWriteThrough: FlagsAndAttributes := FlagsAndAttributes or FILE_FLAG_WRITE_THROUGH;
           fsoNoBuffering: FlagsAndAttributes := FlagsAndAttributes or FILE_FLAG_NO_BUFFERING;
           fsoRandomAccess: FlagsAndAttributes := FlagsAndAttributes or FILE_FLAG_RANDOM_ACCESS;
           fsoSequentialScan: FlagsAndAttributes := FlagsAndAttributes or FILE_FLAG_SEQUENTIAL_SCAN;
           fsoDeleteOnClose: FlagsAndAttributes := FlagsAndAttributes or FILE_FLAG_DELETE_ON_CLOSE;
         end;
   end
 else
   begin
     FlagsAndAttributes := FILE_ATTRIBUTE_NORMAL;
     case AMode and 3 of
       fmOpenRead: DesiredAccess := GENERIC_READ;
       fmOpenWrite: DesiredAccess := GENERIC_WRITE;
       fmOpenReadWrite: DesiredAccess := GENERIC_READ or GENERIC_WRITE;
       fmOpenReadWrite or fmOpenWrite: DesiredAccess := GENERIC_READ or GENERIC_WRITE;
     end;
     case AMode and $F0 of
       fmShareCompat, fmShareExclusive: DesiredAccess := DesiredAccess or 0;
       fmShareDenyWrite: DesiredAccess := DesiredAccess or FILE_SHARE_READ;
       fmShareDenyRead: DesiredAccess := DesiredAccess or FILE_SHARE_WRITE;
       fmShareDenyNone: DesiredAccess := DesiredAccess or (FILE_SHARE_READ or FILE_SHARE_WRITE);
     end;
     CreationDisposition := OPEN_EXISTING;
   end;

 {$IFDEF DELPHIXE2_UP}
 Result := Winapi.Windows.CreateFile(PChar(Filename), DesiredAccess,
   ShareMode, nil, CreationDisposition, FlagsAndAttributes, 0);
 {$ELSE}
 Result := Windows.CreateFile(PChar(AFilename), DesiredAccess, ShareMode,
   nil, CreationDisposition, FlagsAndAttributes, 0);
 {$ENDIF}

 if Result = INVALID_HANDLE_VALUE then
   RaiseLastOSError;

 try
   if (AMode and fmCreate) = fmCreate then
   begin
     if fsoEncrypted in AOptions then
       begin
         CloseHandle(Result);
         if not Assigned(EncryptFile) then
           raise Exception.Create(rsCanNotEncryptFiles);
         if not EncryptFile(PChar(AFilename)) then
           RaiseLastOSError;
         Result := CreateFile(AFilename, fmOpenReadWrite or fmShareExclusive, AOptions);
       end
     else
       SetCompression(Result, fsoCompressed in AOptions);
   end;

   if fsoSparse in AOptions then
     SetSparse(Result);

 except
   CloseHandle(Result);
   raise;
 end;
end;


 
DVM ©   (2012-08-16 17:28) [29]


//------------------------------------------------------------------------------

procedure TNTFSFileStream.Decompress;
begin
 Compressed := False;
end;

//------------------------------------------------------------------------------

destructor TNTFSFileStream.Destroy;
begin
 if Handle <> 0 then
   CloseHandle(Handle);
 inherited;
end;

//------------------------------------------------------------------------------

function TNTFSFileStream.GetCompressed: Boolean;
var
 CompressionAlgorithm: Word;
 Dummy: Cardinal;
begin
 if not DeviceIoControl(Handle, FSCTL_GET_COMPRESSION, nil, 0,
   @CompressionAlgorithm, SizeOf(CompressionAlgorithm), Dummy, nil) then
   RaiseLastOSError;
 Result := (CompressionAlgorithm <> COMPRESSION_FORMAT_NONE);
end;

//------------------------------------------------------------------------------

procedure TNTFSFileStream.Recompress;
begin
 if Compressed then
   begin
     Decompress;
     Compress;
   end;
end;

//------------------------------------------------------------------------------

procedure TNTFSFileStream.SetCompressed(const AValue: Boolean);
begin
 if AValue <> GetCompressed then
   SetCompression(Handle, AValue);
end;

//------------------------------------------------------------------------------

procedure TNTFSFileStream.SetCompression(const AHandle: THandle;
 const AEnabled: Boolean);
var
 Dummy                 : Cardinal;
 CompressionAlgorithm  : Word;
const
 CompressionAlgorithms : array[Boolean] of Word = (
   COMPRESSION_FORMAT_NONE,
   COMPRESSION_FORMAT_DEFAULT
 );
begin
 CompressionAlgorithm := CompressionAlgorithms[AEnabled];
 if not DeviceIoControl(AHandle, FSCTL_SET_COMPRESSION, @CompressionAlgorithm,
   SizeOf(CompressionAlgorithm), nil, 0, Dummy, nil) then
   RaiseLastOSError;
end;

//------------------------------------------------------------------------------

procedure TNTFSFileStream.SetSparse(const AHandle: THandle);
var
 Dummy : Cardinal;
begin
 if not DeviceIoControl(AHandle, FSCTL_SET_SPARSE, nil, 0, nil, 0, Dummy, nil) then
   RaiseLastOSError;
end;

//------------------------------------------------------------------------------

procedure TNTFSFileStream.ZeroData(const AFileOffset, ALength: Int64);
begin
 ZeroDataForTwoOffsets(AFileOffset, AFileOffset + ALength);
end;

//------------------------------------------------------------------------------

procedure TNTFSFileStream.ZeroDataForTwoOffsets(const AFirstOffset, ALastOffset: Int64);
var
 FileZeroDataInformation: TFileZeroDataInformation;
 BytesReturned: Cardinal;
begin
 if not (fsoSparse in FOptions) then
   raise Exception.CreateFmt(rsFileIsNotSparse, [FFileName]);
 FileZeroDataInformation.FileOffset := AFirstOffset;
 FileZeroDataInformation.BeyondFinalZero := ALastOffset;
 if not DeviceIoControl(Handle, FSCTL_SET_ZERO_DATA, @FileZeroDataInformation,
   SizeOf(FileZeroDataInformation), nil, 0, BytesReturned, nil) then
   RaiseLastOSError;
end;

//------------------------------------------------------------------------------

procedure TNTFSFileStream.ZeroToCurrPosition;
begin
 ZeroDataForTwoOffsets(0, Position);
end;

//------------------------------------------------------------------------------

var
 ADVAPI32Handle  : THandle;

initialization

 EncryptFile := nil;

 ADVAPI32Handle := LoadLibrary("advapi32.dll");
 if ADVAPI32Handle <> 0 then
   {$IFDEF UNICODE}
   EncryptFile := GetProcAddress(ADVAPI32Handle, "EncryptFileW");
   {$ELSE}
   EncryptFile := GetProcAddress(ADVAPI32Handle, "EncryptFileA");
   {$ENDIF}

finalization

 FreeLibrary(ADVAPI32Handle);
 EncryptFile := nil;

end.



 
имя   (2012-08-16 17:32) [30]

Удалено модератором


 
имя   (2012-08-16 17:35) [31]

Удалено модератором


 
DVM ©   (2012-08-16 17:36) [32]


> QAZ   (16.08.12 17:32) [30]


> одно дело сказать что файл спарседный, а другое дело указать
> место

Смещения можно указать в разреженном файле всегда и какие угодно. Все что между ними будет исключено из файла и места занимать не будет на диске. В чем проблема то?


 
QAZ   (2012-08-16 17:42) [33]


> В чем проблема то?

да все норм,показалось


 
Es   (2012-08-16 19:18) [34]


> согласен с DVM (с) и не вижу ни одной причины хнанить связанные
> данные в разных местах.

Серег, ну вообще в контексте WEB есть одна причина и имя ей - HTTP-протокол, ибо он запрос-ответ ориентированный. Браузер грузит страницу - а там HTTP-ссылки на 20 изображений. Он генерирует еще 20 запросов на получение этих 20 картинок. Самое наглядное, когда используется распространенный вариант front в виде nginx для быстрой отдачи статики, а за ним back в виде apache для обработки динамики.

1) обработка статики:

Клиент / Браузер -> GET/ -> Nginx -> Файловая система, считывание файла и отдача

2) обработка динамики

Клиент / Браузер -> GET/ -> Nginx -> Apache -> PHP -> Database -> blablabla...

В случае хранения картинок в БД первый вариант обработки исключен, а это ооочень сильно снижает быстродействие и не позволяет пользоваться уже считай стандартизированными решениями. Ибо nginx безумно быстро умеет отдавать статический файл с диска, не нагружая Apache инициализацией подключения. Специфика, но очень распространенная, отсюда большая привычка многих начинающих с программирования под веб хранить файлы на диске, а не в БД.

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


 
MsGuns ©   (2012-08-17 11:39) [35]

Аргументы против файл-серверов:
1) Реляционность. Во многих нормальных КС в базе хранятся не только данные, но и масса непосрественно софта: шаблоны, отчеты, визуальные элементы интерфейса (формы, фрэймы, диалоги, стили и т.д.). Если все это вынести в файлы, получится туча разнокалиберных файлов со сложной системой привязки к собственно логическим объектам модели БД. В самой же базе все связи прекрасно представлены средствами сервера (бизнес-логика).
2) Целостность. Если часть данных модели раположена вне самой БД, то на порядки возрастает сложность ПО по поддержке целостности данных. "Вшивать" в триггеры обращение к внешним файлам - это что-то, да и не всякий скл-сервер позволяет. И что делать с транзакционностью ?
Про бэкапы и ресторы вообще умолчу.
3) Масштабируемость. При резком повышении интенсивности работы (в т.ч. на запись) в файл-серверном варианте обеспечены длительные ожидания и даже зависания, управлять которыми фактически нет возможности. При серверном решении такие возможности имеются, и весьма в ассортименте.
4) Конфеденциальность. Тут все ясно без слов.

Хватит ?


 
Es   (2012-08-17 12:05) [36]

Удалено модератором


 
QAZ   (2012-08-17 13:13) [37]

а мне кажеца или на серверах где крутятся сотни сайтов и форумов с милиардами файлов, кучей запросов и прочей белеберды, все както работает, с масштабируемостью, конфиденциальностью, бэкапами и тд ?


 
AV ©   (2012-08-17 13:20) [38]


> QAZ   (17.08.12 13:13) [37]

Разумно..
Но есть подозрение, что это все опять виртуально
Сайт - файл. Внутри твои картинки, скрипты, др. А снаружи это один файл.
У нас так сайт сделан. На одном из серверов виртуалка стоит, бэкап сайта - бэкап файла виртуалки :)


 
Sergey Masloff   (2012-08-17 13:21) [39]

QAZ   (17.08.12 13:13) [37]
Кажется


 
QAZ   (2012-08-17 13:27) [40]


> AV ©   (17.08.12 13:20) [38]

кая разница что это снаружи один файл когда внутри тот же милион, да и виртуализация не прибавляет скорости


 
AV ©   (2012-08-17 13:41) [41]


> QAZ   (17.08.12 13:27) [40]

ну как, тебе дали место, видится нормально, ваяй что хочешь. Миллион файлов, так миллион. Значит, ССЗБ.
Администрация выделила тебе ресурс, как места, так времени процессора, памяти, др.
А чтобы ты ничего не свалил, что бы переезды там всякие были быстрые/успешные, или если тебя ломанули - все восстановимо простым f5 в тотале (это я утрирую сейчас)
А хочешь  быстро - покупай свой сервак, договоры заключай( или что там провайдеры еще делают)


 
QAZ   (2012-08-17 13:46) [42]


> или что там провайдеры еще делают

продают белый IP за стописят руб. месяц

> AV ©   (17.08.12 13:41) [41]

так не, тут народ говорит что дескать база данных из дохрена файлов это ужасное зло обреченное на скорую погибель
а интернет почемуто до сих пор жив, и всякие фейсбуки где база явно не из трех файлов состоит процветает


 
Es   (2012-08-17 13:46) [43]

Sergey Masloff, а ты то ничего не расскажешь про хранимки в контексте ADO + Oracle или вы окончательно съехали на шарп и про дельфю забыли? )


 
Sergey Masloff   (2012-08-17 14:14) [44]


> Es   (17.08.12 13:46) [43]

 ADO никогда не использовали. Про ODAC и DOA могу рассказать много чего если понадобится кому ;-)
 Ну еще про BDE вот там много чего было подводного но кого это сейчас волнует ;-)


 
Es   (2012-08-20 11:35) [45]

Ну что, господа.

Не может же быть такого, чтобы мы не разобрались как вызывать хранимку с BLOB"ом большого размера. Тем более Oracle точно не против. Он почему-то против ADO...


 
DVM ©   (2012-08-20 12:00) [46]


> Es   (20.08.12 11:35) [45]


> Тем более Oracle точно не против.

А в документации везде сказано что в хранимую процедуру Oracle нельзя передать BLOB больше 32к


 
Sergey Masloff   (2012-08-20 12:11) [47]


> А в документации везде сказано что в хранимую процедуру
> Oracle нельзя передать BLOB больше 32к

Да ну на ;-) Это микрософтовский провайдер может быть ограничивает - говорят он поверх OCI7 лежит


 
Sergey Masloff   (2012-08-20 12:18) [48]


> Не может же быть такого, чтобы мы не разобрались как вызывать
> хранимку с BLOB"ом большого размера. Тем более Oracle точно
> не против. Он почему-то против ADO...

Есть такое мнение что ты не задаешь значение SPPrmsLOB. Поэтому провайдер не биндит его как BLOB а то через чего он его биндит в PL/SQL не может иметь длинну более 32К

Мне не на чем попробовать


 
Sergey Masloff   (2012-08-20 12:21) [49]

стырено на просторах инета

with ADOCommand1 do try
   CommandObject.Set_ActiveConnection(ADOConnection1.ConnectionObject);
   Properties["SPPrmsLob"].Value := true;
   .....
   Parameters.ParamByName("bDATA").LoadFromStream(...,ftBlob);
   Execute;
 finally
   ADOCommand1.Properties["SPPrmsLob"].Value := false;
 end;


ОНО?


 
DVM ©   (2012-08-20 12:22) [50]


> Sergey Masloff   (20.08.12 12:11) [47]


>  Это микрософтовский провайдер может быть ограничивает

Я с Oracle практически не работал, может быть, но просто полез в гугл и нашел множество таких замечаний в разных мануалах, например в JDBC:

http://docs.oracle.com/cd/B19306_01/java.102/b14355/oralob.htm


Passing BLOB and CLOB Locators

Given a standard JDBC prepared statement or callable statement, you can use standard setter methods to pass LOB locators. These methods are defined as follows:

public void setBlob(int index, Blob value);
public void setClob(int index, Clob value);
Note:

If you pass a BLOB to a PL/SQL procedure, then the BLOB must be no bigger than 32K - 7. If you pass a BLOB that exceeds this limit, then you will receive a SQLException.


http://docs.oracle.com/cd/E11882_01/java.112/e16548/oralob.htm


 
DVM ©   (2012-08-20 12:23) [51]


> Sergey Masloff   (20.08.12 12:21) [49]

Тут важно, чтобы именно в хранимую процедуру передавалось


 
Es   (2012-08-20 12:47) [52]

DVM, нет. По крайней мере на 11g проверено. Мы генерировали BLOB-поток на стороне оры, порядка 16 мбайт (то что у нас в тесте с клиента через ADO не прошло по размеру). Отлично такой BLOB уходит как параметр в хранимку, а хранимка его потом записала в поле таблицы.

Так что ора не против.


 
DVM ©   (2012-08-20 13:33) [53]


> Es   (20.08.12 12:47) [52]


> По крайней мере на 11g проверено.

А у тебя какая версия Oracle? Там как раз написано, что в 11 нет ограничения, а в 10 вроде как есть.


 
Es   (2012-08-20 13:42) [54]

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


 
Es   (2012-08-20 13:54) [55]

да, на десятом оракле всё точно также хорошо работает, блоб в 20 мегабайт в хранимку улетает хорошо.


 
Es   (2012-08-20 14:06) [56]


> ОНО?

ну я не очень понял причем здесь ADOCommand... Ведь Insert / Update и так работает хорошо с большими блобами в несколько мегабайт.

Затык идет с передачей именно в хранимки. С хранимкой работаю через TADOStoredProc, если там устанавливать свойство "SPPrmsLob", так у меня вообще вылетает AV...

http://www.onlinedisk.ru/get_image.php?id=930217


 
Sergey Masloff   (2012-08-20 14:14) [57]


> Затык идет с передачей именно в хранимки. С хранимкой работаю
> через TADOStoredProc, если там устанавливать свойство "SPPrmsLob",
>  так у меня вообще вылетает AV...

там типп cmdStoredProc и вызывается именно хранимка - в том месте откуда я код драл ;-)

Приведи свой пример кода где там AV?
вот это
CommandObject.Set_ActiveConnection
делал ДО установки свойства?


 
Sergey Masloff   (2012-08-20 14:15) [58]


> Тут важно, чтобы именно в хранимую процедуру передавалось

Это именно для хранимой процедуры.
У автора ж в query работает а в sp нет. Это значит что там биндится через какой-то тип который имеет разный допустимый размер в SQL и PL/SQL
То есть его "нелигитимное" преобразование становится таким только в случае с использованием системы типов PL/SQL

Если задать этот параметр то биндинг будет гарантировано проходить с использованием типа BLOB который одинаковый в SQL и PL/SQL энджайнах

Пока предположение такое дальше будем смотреть


 
Sergey Masloff   (2012-08-20 14:17) [59]

Про размеры - и в 8 (вроде бы) и в 9 и далее вставлял блобы через хранимые размерами гораздо больше жалких десятка мегабайт ;-)
 Так как не использовал ADO даже не знал что с ними проблемы могут быть
;-)


 
Es   (2012-08-20 14:20) [60]

А-а-а, Серёг, я неправильно понял твой выдранный код ))

Я ставил у ADOStoredProc.Properties, а оказывается еще есть ADOStoredProc.Parameters.Properties.

Всё заработало на ура, спасибо )



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

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

Наверх




Память: 0.64 MB
Время: 0.063 c
15-1330201802
Юрий
2012-02-26 00:30
2013.03.22
С днем рождения ! 26 февраля 2012 воскресенье


15-1351694777
Handler
2012-10-31 18:46
2013.03.22
как будет на английском


15-1329381756
Pit
2012-02-16 12:42
2013.03.22
borland.ru


15-1339078612
Artem
2012-06-07 18:16
2013.03.22
Посоветуйте электронные шахматы...


15-1350725654
Anrey
2012-10-20 13:34
2013.03.22
Трассировка+замер скорости+отправка отчета





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