При работе с 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->CLOBFUNCTION 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;
Комментариев нет :
Отправить комментарий