XML PLSQL
XML PLSQL
Roteiro
Introduo
XML versus Relacional
XML + Relacional
SQL/XML
Funes de Publicao
Vises SQL/XML
Introduo
Muitas aplicaes usam XML para troca de
dados com seus bancos relacionais
Os principais bancos de dados possuem
solues prprias para exportar XML de
dados relacionais e vice-versa, o que
impede a interoperabilidade entre esses
bancos
Introduo
necessria uma soluo para que as
aplicaes possam ser executadas sobre
qualquer banco de dados relacional
XML versus Relacional
As estruturas XML e relacional so bem
diferentes:
Relacional tabelas bidimensionais onde
no possvel definir hierarquia ou ordem
entre elas
XML baseado em rvores (hierarquia) onde
a ordem significante e pode ser definida no
esquema
XML versus Relacional
Em pginas Web, XML til por ter
estrutura compatvel com o formato de
exibio das pginas (HTML)
No entanto, grande parte das aplicaes
Web utilizam dados provenientes de bancos
relacionais, precisando assim serem
convertidos para XML
XML + Relacional
Dentre as principais solues para
aplicaes que necessitam extrair dados
XML de bancos relacionais, temos:
SAX ou DOM
Aplicao independente de banco
Grande quantidade de cdigo a ser gerado
Extenses XML proprietrias
Em geral, simples e manutenveis
Ferem a independncia de banco
SQL/XML
SQL/XML
SQL/XML uma extenso do SQL
Tambm denominada SQLX
Criada com a participao de Oracle, IBM,
Microsoft, Sybase, e DataDirect
Technologies
Permite que criar elementos XML a partir
de consultas SQL usando funes de
publicao
SQL/XML
Aprender SQL/XML se torna simples pois
so poucas as novas funes adicionadas
Como o SQL um padro j maduro,
muitas ferramentas e infra-estrutura j
existem para suport-lo, o que torna mais
fcil a implementao das novas
funcionalidades
SQL/XML
Execuo transparente
Statements SQLX so tratados por parsers do
banco e o resultado montado on the fly
suportado por: Sybase ASE 12.5, IBM DB2
8.1 e Oracle 9i R2 (mdulo XMLDB)
No SQL Server existe a clusula FOR XML
SQL/XML
Gargalos na performance: os mesmos de
quaisquer outros tipos de consulta
Junes caras e desnecessrias
Indexao pobre
Inexistncia de ajustes do banco para as
consultas (query tunings)
Normalizao
Funes de Publicao
As funes de publicao XML usam
valores SQL para gerar valores XML de
acordo com os tipos definidos no XML
Schema do W3C
Funes de Publicao
XMLElement()
transforma valores relacionais em elementos
XML
XMLAttributes()
define os atributos de um elemento XML
XMLForest()
transforma uma lista de valores relacionais em
uma lista de elementos XML
XMLConcat()
concatena um ou mais elementos XML
XMLAgg()
trata relacionamentos 1:n, ou seja, trata
colees
Exemplo: Esquema
Relacional
XMLElement()
Usado para criar elementos XML
XMLELEMENT (
[NAME] id
[, XMLAttributes() ]
[, ( instncia_elemento_XML )+ ]
)
XMLElement()
SELECT
XMLELEMENT(NAME "NOME_CLIENTE",
CLI.CNOME
)
FROM CLIENTES_REL CLI
WHERE CLI.CESTADO = 'CE'
<NOME_CLIENTE>Lineu</NOME_CLIENTE>
<NOME_CLIENTE>Valdiana</NOME_CLIENTE>
XMLElement()
SELECT XMLELEMENT("CLIENTE_CEARA",
XMLELEMENT("NOME",
CLI.CNOME
),
XMLELEMENT("CIDADE",
CLI.CCIDADE
)
)
FROM CLIENTES_REL CLI
WHERE CLI.CESTADO = 'CE' <CLIENTE_CEARA>
<NOME>Lineu</NOME>
<CIDADE>Fortaleza</CIDADE>
</CLIENTE_CEARA>
<CLIENTE_CEARA>
<NOME>Valdiana</NOME>
<CIDADE>Fortaleza</CIDADE>
</CLIENTE_CEARA>
XMLAttributes()
Define os atributos de um elemento
XMLATTRIBUTES (
expresso_valor [AS alias]
[, value_expr [AS alias]*
)
XMLAttributes()
SELECT XMLELEMENT("CLIENTE_CEARA",
XMLATTRIBUTES(
CLI.CCODIGO AS "CODIGO"
),
XMLELEMENT("NOME",
CLI.CNOME
),
XMLELEMENT("CIDADE",
CLI.CCIDADE
) <CLIENTE_CEARA CODIDO="1">
) <NOME>Lineu</NOME>
FROM CLIENTES_REL CLI <CIDADE>Fortaleza</CIDADE>
WHERE CLI.CESTADO = 'CE' </CLIENTE_CEARA>
<CLIENTE_CEARA CODIDO="3">
<NOME>Valdiana</NOME>
<CIDADE>Fortaleza</CIDADE>
</CLIENTE_CEARA>
XMLForest()
Gera uma lista de elementos XML a
partir de uma lista de expresses de
valor e seus aliases opcionais. Valores
nulos no geram elementos XML.
XMLFOREST (
expresso_valor [AS alias]
[, expresso_valor [AS alias] ]*
)
XMLForest()
SELECT XMLFOREST(
CLI.CNOME AS "NOME",
CLI.CCIDADE AS "CIDADE",
CLI.CEP AS "CEP"
)
FROM CLIENTES_REL CLI
WHERE CLI.CESTADO = 'CE'
<NOME>Lineu</NOME>
<CIDADE>Fortaleza</CIDADE>
<CEP>60356-030</CEP>
<NOME>Valdiana</NOME>
<CIDADE>Fortaleza</CIDADE>
<CEP>60486-025</CEP>
XMLAgg()
Gera uma lista de elementos XML a
partir de um agrupamento (GROUP BY).
Se nenhum GROUP BY for especificado,
retornado um agregado XML para
todas as clusulas da consulta.
XMLAGG (
instncia_elemento_XML
[ ORDER BY lista_atributos ]
)
XMLAgg()
SELECT XMLELEMENT("CLIENTES",
XMLATTRIBUTES(CLI.CCIDADE AS "CIDADE")
XMLAGG(
XMLELEMENT("CLIENTE",
CLI.CNOME )
)
)
FROM CLIENTES_REL CLI
GROUP BY CLI.CCIDADE;
<CLIENTES CIDADE="FORTALEZA">
<CLIENTE>Lineu</CLIENTE>
<CLIENTE>Valdiana</CLIENTE>
</CLIENTES>
<CLIENTES CIDADE="SOBRAL">
<CLIENTE>Marta</CLIENTE>
<CLIENTE>Joana</CLIENTE>
</CLIENTES>
XMLAgg()
SELECT XMLELEMENT("CLIENTES",
XMLAGG(
XMLELEMENT("CLIENTE",
CLI.CNOME )
)
)
FROM CLIENTES_REL CLI;
<CLIENTES>
<CLIENTE>Lineu</CLIENTE>
<CLIENTE>Valdiana</CLIENTE>
<CLIENTE>Marta</CLIENTE>
<CLIENTE>Joana</CLIENTE>
</CLIENTES>
XMLAgg() <PEDIDO_CEARA CODIGO="3">
<ITENS>
<ITEM>Mouse</ITEM>
<ITEM>Monitor</ITEM>
SELECT XMLELEMENT("PEDIDO_CEARA", <ITEM>Modem</ITEM>
XMLATTRIBUTES( </ITENS>
PED.PCODIGO AS CODIGO </PEDIDO_CEARA>
),
XMLELEMENT("ITENS",
(SELECT XMLAGG(
XMLELEMENT("ITEM",
PROD.PDESCRICAO
)
)
FROM ITENS_REL IT, PRODUTOS_REL PROD
WHERE IT.IPEDIDO = PED.PCODIGO AND
IT.IPRODUTO = PROD.PCODIGO)
)
)
FROM PEDIDOS_REL PED
WHERE PED.PESTADO = 'CE'
XMLConcat()
Gera um nico fragmento XML a partir dos
argumentos
XMLConcat (
instncia_elemento_XML
[, instncia_elemento_XML ]*
)
XMLConcat()
SELECT
XMLELEMENT("PRODUTO_NOME", PROD.PNOME),
XMLELEMENT("PRODUTO_PRECO", PROD.PPRECO)
FROM PRODUTOS_REL PROD
<PRODUTO_NOME>Monitor</PRODUTO_NOME> <PRODUTO_PRECO>589,50</PRODUTO_PRECO>
<PRODUTO_NOME>Mouse</PRODUTO_NOME> <PRODUTO_PRECO>50,25</PRODUTO_PRECO>
<PRODUTO_NOME>Teclado</PRODUTO_NOME> <PRODUTO_PRECO>165,88</PRODUTO_PRECO>
XMLConcat()
SELECT XMLCONCAT(
XMLELEMENT("PRODUTO_NOME", PROD.PNOME),
XMLELEMENT("PRODUTO_PRECO", PROD.PPRECO)
)
FROM PRODUTOS_REL PROD
XMLCONCAT(XMLELEMENT("PRODUTO_NOME", PROD.PNOME),
XMLELEMENT("PRODUTO_PRECO", PROD.PPRECO))
<PRODUTO_NOME>Monitor</PRODUTO_NOME>
<PRODUTO_PRECO>589,50</PRODUTO_PRECO>
<PRODUTO_NOME>Mouse</PRODUTO_NOME>
<PRODUTO_PRECO>50,25</PRODUTO_PRECO>
<PRODUTO_NOME>Teclado</PRODUTO_NOME>
<PRODUTO_PRECO>165,88</PRODUTO_PRECO>
Vises SQL/XML
Oracle estende o mecanismo de Viso para
suportar Viso SQL/XML.
Uma Viso SQL/XML uma viso com
instncias do tipo XMLType.
Estas instncias podem existir fisicamente
no banco de dados (em tabelas XML) e
podem ser sintetizados a partir de dados
no formato relacional ou de objetos.
Vantagens de Vises
SQL/XML
XML vem se tornando o padro para a troca de
dados na Web.
Dados XML podem ser mapeados na estrutura
das linguagens OO e assim aplicaes podem
manipul-los como estruturas nativas.
Vises XML provem a flexibilidade de ver o
mesmo dado relacional, OO ou XML de mais de
uma maneira. Assim o projetista pode ter mais
de uma representao para diferentes
aplicaes sem ter que mudar os dados no
banco.
Como os objetos da viso so processados no
SGBD, no no cliente, isto pode resultar em
menos trfico na rede.
Definindo Vises de Objetos
Existem dois tipos de vises SQL/XML:
No em conformidade com um
esquema: estas vises no esto em
conformidade com um esquema particular
Em conformidade com um esquema:
estas vises esto em conformidade com um
esquema, provendo uma tipagem mais forte
que do outro tipo de viso.
Definindo Vises SQL/XML
Qualquer que seja o tipo de viso
utilizado, os seguintes passos devem
ser seguidos:
1. Defina o nome e o tipo XML dos elementos
da viso.
2. Escreva uma consulta que especifique
quais dados em quais tabelas contm os
atributos para os elementos XML do tipo
definido anteriormente.
Definindo Vises SQL/XML
Definindo elementos de tipo simples
Definindo atributos
Definindo elementos de tipos complexo
Definindo elementos multivalorados
Definindo elementos de tipo
simples
Definindo elementos de tipo
simples
1. Criao do tipo
<schema xmlns:xs="...">
<element name="cliente" type="TCliente"/>
<complexType name="TCliente">
<sequence>
<element name="nome" type="xs:string"/>
</sequence>
</complexType>
</schema>
Definindo elementos de tipo
simples
2. Criao da consulta que define a viso
CREATE VIEW Clientes_v AS
SELECT XMLELEMENT("cliente",
XMLELEMENT("nome", C.CNOME)
) AS cliente Nome da coluna da viso
FROM Clientes_rel C
OU
<xs:schema xmlns:xs="...">
<xs:element name="cliente" type="TCliente"/>
<xs:complexType name="TCliente">
<xs:sequence>
<xs:element name="nome" type="xs:string"/>
</xs:sequence>
<xs:attribute name="codigo" type="xs:integer"/>
</xs:complexType>
</xs:schema>
Definindo atributos
2. Criao da consulta que define a viso
<xs:schema xmlns:xs="...">
<xs:element name="cliente" type="TCliente"/>
<xs:complexType name="TCliente">
<xs:sequence>
<xs:element name="nome" type="xs:string"/>
<xs:element name="endereco" type="TEndereco"/>
<xs:element name="telefone" type="xs:string"
maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="codigo" type="xs:integer"/>
</xs:complexType>
<xs:complexType name="TEndereco">...</xs:complexType>
</xs:schema>
Definindo elementos
multivalorados (1)
2. Criao da consulta que define a viso
<xs:schema xmlns:xs="...">
<xs:element name="cliente" type="TCliente"/>
<xs:complexType name="TCliente">
<xs:sequence>
<xs:element name="nome" type="xs:string"/>
<xs:element name="endereco" type="TEndereco"/>
<xs:element name="telefone" type="xs:string" .../>
<xs:element name="pedido" type="TPedido"
maxOccurs="unbounded"/>
</xs:sequence>
<xs:attribute name="codigo" type="xs:integer"/>
</xs:complexType>
<xs:complexType name="TEndereco">...</xs:complexType>
<xs:complexType name="TPedido">...</xs:complexType>
</xs:schema>
Definindo Vises em Conformidade
com um esquema
2. Registro do esquema
BEGIN
DBMS_XMLSCHEMA.registerSchema('http://www.oracle.com/emp_simple.xsd',
'<schema xmlns=http://www.w3.org/2001/XMLSchema
targetNamespace=http://www.oracle.com/emp_simple.xsd
xmlns:xdb=http://xmlns.oracle.com/xdb
elementFormDefault="qualified">
<xs:element name="cliente" type="TCliente"/>
<xs:complexType name="TCliente">...</xs:complexType>
<xs:complexType name="TEndereco">...</xs:complexType>
<xs:complexType name="TPedido">...</xs:complexType>
</schema>',
TRUE, TRUE, FALSE);
END;
Definindo Vises em Conformidade
com um esquema
3. Criao da consulta que define a viso
CREATE VIEW Clientes_v OF XMLType
XMLSCHEMA http://www.servidor.com/cliente.xsd
ELEMENT "cliente"
WITH OBJECT ID (extract(OBJECT_VALUE,
'/Cliente/codigo/text()').getnumberval())
AS
SELECT XMLELEMENT("cliente",
XMLATTRIBUTES(
'http://www.servidor.com/cliente.xsd' AS "xmlns",
'http://www.w3.org/2001/XMLSchema-instance' AS "xmlns:xsi",
'http://www.servidor.com/cliente.xsd' AS "xsi:schemaLocation",
C.CCODIGO AS "codigo"),
XMLFOREST(C.CNOME AS "nome"), XMLELEMENT("endereco", ... ),
XMLFOREST(C.CFONE1 AS "telefone", ...),
(SELECT XMLAGG( XMLELEMENT("pedido",...))
FROM Pedidos_rel P WHERE P.PCLIENTE = C.CCODIGO)
)
FROM Clientes_rel C
XPath em Vises SQL/XML
SQL/XML descreve funes para seleo de
elementos XML usando XPath como
linguagem de consulta
Exemplo: Esquema XML
Pedido
@codigo
dataEntrega
enderecoEntrega
rua
cidade
estado
cep
cliente
@codigo
nome
telefone*
item*
@codigo
quantidade
produto
Funo EXTRACT ()
Retorna ns (instncias de XMLType) que
satisfazem a expresso XPath
EXTRACT(
<instncia de XMLType>,
<consulta XPath>
)
Funo EXTRACT()
Obter o nome dos clientes que efetuaram pedidos:
SELECT EXTRACT(
P.PEDIDO,
'/pedido/cliente/nome'
)
FROM Pedidos_V P;
<nome>Lineu</nome>
<nome>Kelly</nome>
<nome>Valdiana</nome>
Funo EXTRACT()
Obter o nome dos clientes que efetuaram pedidos
para o Cear:
SELECT EXTRACT(
P.PEDIDO,
'/pedido[enderecoEntrega/estado="CE"]
/cliente/nome'
)
FROM Pedidos_V P;
<nome>Lineu</nome>
<nome>Valdiana</nome>
Funo EXTRACTVALUE()
Retorna o valor de atributos ou do n
TEXT de elementos que satisfazem a
expresso XPath
Os elementos que satisfazem a
expresso devem ter somente o
elemento TEXT como filho
EXTRACTVALUE(
<instncia de XMLType>,
<consulta XPath>
)
Funo EXTRACTVALUE()
SELECT EXTRACTVALUE(
P.PEDIDO,
'/pedido/cliente/nome'
)
FROM Pedidos_V P;
Lineu
Kelly
Valdiana
Funo EXTRACTVALUE()
SELECT EXTRACTVALUE(
P.PEDIDO,
'/pedido/cliente'
)
FROM Pedidos_V P;
<pedido codigo="1">
<dataEntrega>...</dataEntrega><enderecoEntrega>...</enderecoEntrega>
<cliente codigo="1">... </cliente>
<item codigo="1">
<quantidade>1</quantidade>
<produto>Mouse</produto>
</item>
<item codigo="2">...</item><item codigo="3">...</item>
</pedido>
Funo EXISTSNODE()
Obter os clientes que compraram Mouse:
<xsql:include-xml connection="sqlx"
xmlns:xsql="urn:oracle-xsql">
SELECT XMLELEMENT("clientes",
XMLAGG( XMLELEMENT("cliente", C.CNOME))
).getClobVal()
FROM CLIENTES_REL C
</xsql:include-xml>
Resultado
Exemplo com parmetros
<xsql:include-xml connection="sqlx"
xmlns:xsql="urn:oracle-xsql">
SELECT XMLELEMENT("cliente",
XMLELEMENT("cliente", C.CNOME)
).getClobVal()
FROM CLIENTES_REL C
WHERE C.CCODIGO = {@codigo}
</xsql:include-xml>
Resultado
Exemplo com funes de
consulta
Para cada pedido com numero de itens maior ou
igual a 2, retorne o cliente do pedido:
<xsql:include-xml connection="sqlx"
xmlns:xsql="urn:oracle-xsql">
SELECT XMLELEMENT("clientes",
XMLAGG(EXTRACT(P.PEDIDO, '/pedido/cliente'))
).getClobVal()
FROM Pedidos_V P
WHERE EXISTSNODE( P.PEDIDO,
'count(/pedido/item) >= 2') = 1
</xsql:include-xml>
Exemplo com funes de
consulta
OU
<clientes connection="sqlx"
xmlns:xsql="urn:oracle-xsql">
<xsql:include-xml>
</xsql:include-xml>
</clientes>
Resultado
Referncias
Oracle XML DB Reference
http://download-west.oracle.com/docs/cd/
B14117_01/appdev.101/b10790/xdb13gen.htm
#i1025386
The Joy of SQLX
http://www.vsj.co.uk/databases/display.asp?
id=322
J. E. Funderburk, S. Malaika, B. Reinwald,
XML programming with SQL/XML and
XQuery