XSD XML

1) Регистрация схемы из файла в directory

BEGIN
  DBMS_XMLSCHEMA.deleteSchema('RIGF.xsd',4);

   DBMS_XMLSCHEMA.registerSchema(
    SCHEMAURL  => 'RIGF.xsd',
    SCHEMADOC  => bfilename('XMLLOAD','RIGF.xsd'),
    LOCAL      => TRUE,
    GENTYPES   => TRUE,
    GENTABLES  => TRUE
    );

commit;
END;

SELECT *
  FROM ALL_XML_SCHEMAS s
 where s.owner='EGRIP'

begin
 dbms_xmlschema.compileSchema(schemaURL => 'RIGF.xsd');
end;

2) Создание таблицы на основе корневого элемента xsd, пополнение из clob

CREATE TABLE po_tab (id NUMBER, xmlcol XMLType)
 XMLType COLUMN xmlcol
 XMLSCHEMA "RIGF.xsd"
 ELEMENT "ROOTEL";

begin
  for ds in (select * from xml_files where id=50) loop
   INSERT INTO po_tab VALUES(ds.id, XMLType(ds.xml_file));
  end loop;
end;

3) Создание ресурса,

--[1]
BEGIN
   --DBMS_XMLSCHEMA.deleteSchema('RIGF.xsd',4);
   DBMS_XMLSCHEMA.registerSchema(
    SCHEMAURL  => 'RIGF.xsd',
    SCHEMADOC  => bfilename('XMLLOAD','RIGF.xsd'),
    LOCAL      => TRUE,
    GENTYPES   => TRUE,
    GENTABLES  => TRUE
    );
commit;
END;

==========================================

--[2]
DROP TABLE egrip_xml;

CREATE TABLE egrip_xml(id        NUMBER,
                       nyear     NUMBER,
                       file_name VARCHAR2(128),
                       xmlcol    XMLType)
 XMLType COLUMN xmlcol STORE AS CLOB
 XMLSCHEMA "RIGF.xsd"
 ELEMENT "EGRIP";

/*
create sequence S_EGRIP
minvalue 1
maxvalue 9999999999999999999999999999
start with 1
increment by 1
nocache;
*/

--[3] задание имен файлов
insert into egrip_xml(id,nyear,file_name)
select
rownum as id,
to_number(substr(t.filename,12,4)) as nyear,
t.filename
from
(
 SELECT 'EGRIP_FULL_2016-01-02_71710.XML' as FILENAME FROM DUAL UNION ALL
 SELECT 'EGRIP_FULL_2016-01-02_71803.XML' as FILENAME FROM DUAL
) t



--[4] загрузка файлов xml из директории
DECLARE
  src_loc     BFILE;
  src_offset  NUMBER := 1;
  dst_offset  NUMBER := 1;
  src_osin    NUMBER;
  dst_osin    NUMBER;
  bytes_rd    NUMBER;
  bytes_wt    NUMBER;
  w number;
  xml_data   clob;
BEGIN

  for ds in (select fl.* from egrip_xml fl)
  loop
  src_loc:= bfilename('XMLLOAD',ds.file_name);

  DBMS_LOB.createtemporary (xml_data, TRUE, DBMS_LOB.SESSION);

  DBMS_LOB.fileopen (src_loc, DBMS_LOB.file_readonly);
  DBMS_LOB.loadfromfile (xml_data, src_loc, DBMS_LOB.getlength (src_loc));
  DBMS_LOB.fileclose (src_loc);

  update egrip_xml t
     set t.xmlcol = XMLType(xml_data)
   where t.id = ds.id;

  COMMIT;
  end loop;
END;

--[5]
/*
 Сравнение быстродействия!
*/

  --[На прямую]
    select distinct
         --t.ID,
         extractValue(ds_svip.COLUMN_VALUE,'/СвИП/@ИННФЛ')                as INNFL,
         extractValue(ds_svip.COLUMN_VALUE,'/СвИП/СвФЛ/ФИОРус/@Фамилия')  as SURNAME
    from (
          ------------------------------------------------------------------------------------
          select f.id,
                 XMLType(f.xml_file) as xmlcol
            from xml_files f
          ------------------------------------------------------------------------------------
         ) t,
         table(XMLSequence(t.xmlcol.extract('/EGRIP/СвИП')))  ds_svip,
         table(XMLSequence(ds_svip.extract('/СвИП/СвОКВЭД'))) ds_svip_okved,
         table(XMLSequence(ds_svip_okved.extract('/СвОКВЭД/СвОКВЭДДоп'))) ds_svip_okved_dop
  where
        extractValue(ds_svip_okved_dop.COLUMN_VALUE,'/СвОКВЭДДоп/@НаимОКВЭД')='УПРАВЛЕНИЕ ФИНАНСОВЫМИ РЫНКАМИ'
       
       
  --[через схему]  
    select distinct
         --t.ID,
         extractValue(ds_svip.COLUMN_VALUE,'/СвИП/@ИННФЛ')                as INNFL,
         extractValue(ds_svip.COLUMN_VALUE,'/СвИП/СвФЛ/ФИОРус/@Фамилия')  as SURNAME
    from (
          ------------------------------------------------------------------------------------
          select f.*
            from egrip_xml f
          ------------------------------------------------------------------------------------
         ) t,
         table(XMLSequence(t.xmlcol.extract('/EGRIP/СвИП')))  ds_svip,
         table(XMLSequence(ds_svip.extract('/СвИП/СвОКВЭД'))) ds_svip_okved,
         table(XMLSequence(ds_svip_okved.extract('/СвОКВЭД/СвОКВЭДДоп'))) ds_svip_okved_dop
  where
        extractValue(ds_svip_okved_dop.COLUMN_VALUE,'/СвОКВЭДДоп/@НаимОКВЭД')='УПРАВЛЕНИЕ ФИНАНСОВЫМИ РЫНКАМИ'