При работе с XML+ADO+Oracle всё прекрасно, пока размер потока с XML не превышает 32k
Обмен данными в XML имеет ряд преимуществ:
Почему так происходит?
Посмотрим, что на подобный вопрос ответил о.Том:
Код для вставки данных в промежуточную таблицу (Delphi):
Применение функции:
Обмен данными в XML имеет ряд преимуществ:
- малое время выполнения транзакции;
- повышение надежности обработки информации в многопользовательских системах;
- упрощение отладки исполняемого модуля.
declare xmltypedoc xmltype; doc DBMS_XMLDOM.domdocument; docElem DBMS_XMLDOM.DOMElement; c clob begin ... xmltypedoc := xmltype(c); doc := dbms_xmldom.newDOMDocument(xmltypedoc); docElem := dbms_xmldom.getDocumentElement(doc); ... end;При попытке передать через ADO XML-структуру объемом больше 32767B, получим ошибку ORA-01460: затребовано нереализованное или неразумное преобразование.
Почему так происходит?
Посмотрим, что на подобный вопрос ответил о.Том:
So, how does this apply to CLOBs as parameters to a Packaged Procedure?32k - это ограничение длины типа данных varchar2. Так как ADO весьма криво работает (точнее, вообще не работает) c типом данных ftOraCLOB, сделаем так, как советует Т. Кайт: поместим данные в промежуточное BLOB поле, а затем сконвертируем BLOB в CLOB.
As an example, if I have a procedure that will parse & process an XML document, how do you perform the "CALL(SOME_PACKAGE.SOME_PROC('...'))" from the client if the XML document is larger than 4K?
I am using ADO to execute Procedure call from NT service against a 9i install on SUN UNIX. Is there a way to do this with the ADO or am I forced to use Embedded SQL (Pro*C/C++)? If the later, how would I perform the embedded execution?
Thanks!!
Followup April 11, 2002 - 7pm Central time zone:
The XML document can be 32k (the varchar2 limit in PLSQL is 32k, not 4000 bytes).
If you have >32k -- i would be tempted to use a global temporary table, stream the data into that and call a procedure to work against that clob/blob. you can do all of this from VB. No C needed.
Код для вставки данных в промежуточную таблицу (Delphi):
procedure PutXMLToPkg; var LStrStream : TMemoryStream; begin try LStrStream := TMemoryStream.Create; xml.SaveToStream(LStrStream); //TXMLDocument; ADOQuery1.Close; ADOQuery1.Parameters.ParamByName('pXML').LoadFromStream(LStrStream, ftBlob); // запрос выполняет insert ADOQuery1.ExecSQL; except on E : Exception do ShowMessage(E.Message); end; end;Функция на сервере для конвертации BLOB->CLOB
FUNCTION FNC_Blob_Para_Clob(pBLOB BLOB) RETURN CLOB IS nCLOB CLOB; nSRC_OFFSET NUMBER; nDEST_OFFSET NUMBER; nLANG_CONTEXT NUMBER := DBMS_LOB.default_lang_ctx; nWARNING NUMBER; nAMOUNT NUMBER; BEGIN IF DBMS_LOB.GETLENGTH(pBLOB) > 0 THEN DBMS_LOB.CREATETEMPORARY(nCLOB, TRUE); nSRC_OFFSET := 1; nDEST_OFFSET := 1; nAMOUNT := DBMS_LOB.GETLENGTH(pBLOB); DBMS_LOB.CONVERTTOCLOB( nCLOB , pBLOB , nAMOUNT , nSRC_OFFSET , nDEST_OFFSET -- кириллическая кодировка из sys.prop$ , NLS_CHARSET_ID ('CL8MSWIN1251') , nLANG_CONTEXT , nWARNING); RETURN nCLOB; ELSE nCLOB := TO_CLOB(''); RETURN nCLOB; END IF; DBMS_LOB.FREETEMPORARY(nCLOB); END;(полный список значений NLS_CHARSET_ID здесь)
Применение функции:
declare b blob; c clob; begin select fblob into b from TEMP_LOB where ID = 1; select FNC_Blob_Para_Clob(b) into c from dual; end;
Комментариев нет :
Отправить комментарий