Вот окончательное решение с генерацией XML для однострочного запроса
возвращает XML произвольного запроса
вида
select generate_xml('dic','*','n=98') from dual
результат
<?xml version="1.0"?>
<dic><N value="98" datatype="NUMBER"/><UP value="0" datatype="NUMBER"/><TYP value="1" datatype="NUMBER"/><NAME value="Test data" datatype="VARCHAR2"/><FD value="29-Jan-2003" datatype="DATE"/><TD value="" datatype="DATE"/>
</dic>
CREATE OR REPLACE
FUNCTION generate_xml (
tab IN VARCHAR2,
col IN VARCHAR2 := '*',
whr IN VARCHAR2 := NULL
)
RETURN XMLType AUTHID CURRENT_USER
IS
TYPE cv_type IS REF CURSOR;
CV cv_type;
column_name VARCHAR2 (255);
data_type VARCHAR2 (255);
val CLOB;
res XMLType;
BEGIN
res:=xmltype.CreateXML('<?xml version="1.0"?> <'||tab||'> </'||tab||'>' );
OPEN CV FOR 'select COLUMN_NAME , DATA_TYPE from ALL_TAB_COLUMNS '
|| ' WHERE DATA_TYPE in (''NUMBER'',''VARCHAR2'',''DATE'') and upper(trim(TABLE_NAME))=upper(trim('''
|| tab
|| '''))';
LOOP
FETCH CV
INTO column_name, data_type;
EXIT WHEN CV%NOTFOUND;
IF CV%ROWCOUNT <> 1
THEN
null;-- RESULT := RESULT || ';';
END IF;
EXECUTE IMMEDIATE 'SELECT to_char('
|| COLUMN_NAME
|| ') FROM '
|| tab
|| ' WHERE rownum=1 and '
|| NVL (whr, '1=1')
into val;
select insertchildxml( res, '/'||tab, COLUMN_NAME, xmltype( '<'||COLUMN_NAME||' value="'||val||'" datatype="'||data_type||'"/>') ) into res from dual ;
END LOOP;
CLOSE CV;
RETURN res;
END;
/
Креативу нет предела ;-)