Para enviar información (transaccional) hacia una base de datos centralizada, prodríamos emplear un servicio web: recibe los datos y los persiste de forma autónoma, segura y confiable. Pero como alternativa, es invocar un procedimiento almacenado remoto.
Consideremos la limitante que no podemos enviar la información en formato JSON. La versión del motor no lo soporta: Oracle 11g. La solución será emplear el formato XML.
No pasemos por alto los riesgos de enviar la información no cifrada (el sistema está en una red privada o no), el tamaño de los datos y el costo de procesamiento del servidor.
Este ejemplo nuestra cómo generar el formato XML en el cliente. Se etiqueta los bean's con la anotación @XmlRootElement.
/** | |
* | |
* @author erios | |
*/ | |
@XmlRootElement | |
public class Cabecera { | |
private String numero; | |
private Date fecha; | |
private List<Detalle> detalle; | |
... | |
} | |
@XmlRootElement | |
public class Detalle { | |
private int secuencial; | |
private double monto; | |
... | |
} | |
public class Main { | |
public static String jaxbObjectToXML(Cabecera customer, boolean pretty) { | |
String xmlString = ""; | |
try { | |
JAXBContext context = JAXBContext.newInstance(Cabecera.class); | |
Marshaller m = context.createMarshaller(); | |
if(pretty){ | |
m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE); // To format XML | |
} | |
StringWriter sw = new StringWriter(); | |
m.marshal(customer, sw); | |
xmlString = sw.toString(); | |
} catch (JAXBException e) { | |
e.printStackTrace(); | |
} | |
return xmlString; | |
} | |
} |
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> | |
<cabecera> | |
<detalle> | |
<monto>10.0</monto> | |
<secuencial>1</secuencial> | |
</detalle> | |
<detalle> | |
<monto>6.95</monto> | |
<secuencial>2</secuencial> | |
</detalle> | |
<fecha>2016-09-13T13:23:28.319-05:00</fecha> | |
<numero>00001</numero> | |
</cabecera> |
El procedimiento para interpretar el xml y grabar las tablas correspondientes. La solución es válida para todas las base de datos relacionales (como Postgres y Sql Server), aunque el código varía entre ellas.
CREATE OR REPLACE PROCEDURE P_INSERT_DOCUMENTO(id_in IN CHAR,xml_in IN VARCHAR2) AS | |
PRAGMA AUTONOMOUS_TRANSACTION; | |
BEGIN | |
INSERT INTO CABECERA(NUMERO,FECHA) | |
SELECT x.numero,to_date(replace(x.fecha,'T',' '),'YYYY-MM-DD HH24:MI:SS') fecha | |
FROM XMLTABLE ('/cabecera' | |
PASSING XMLTYPE(xml_in) | |
COLUMNS numero CHAR(5) PATH 'numero', | |
fecha VARCHAR2(19) PATH 'fecha') x | |
WHERE x.numero = id_in; | |
INSERT INTO DETALLE(NUMERO,SECUENCIAL,MONTO) | |
SELECT id_in,x.secuencial,TO_NUMBER(x.monto,'990.00') monto | |
FROM XMLTABLE ('/cabecera/detalle' | |
PASSING XMLTYPE(xml_in) | |
COLUMNS monto VARCHAR2(6) PATH 'monto', | |
secuencial NUMBER(4,0) PATH 'secuencial') x | |
; | |
COMMIT; | |
EXCEPTION | |
WHEN OTHERS THEN | |
ROLLBACK; | |
RAISE_APPLICATION_ERROR(-20112,'Error al grabar:'||SQLERRM); | |
END; |
DECLARE | |
id_in CHAR(5); | |
xml_in VARCHAR2(500); | |
BEGIN | |
id_in := '00001'; | |
xml_in := '<?xml version="1.0" encoding="UTF-8" standalone="yes"?> | |
<cabecera> | |
<detalle> | |
<monto>10.0</monto> | |
<secuencial>1</secuencial> | |
</detalle> | |
<detalle> | |
<monto>6.95</monto> | |
<secuencial>2</secuencial> | |
</detalle> | |
<fecha>2016-09-13T13:23:28.319-05:00</fecha> | |
<numero>00001</numero> | |
</cabecera>'; | |
P_INSERT_DOCUMENTO(id_in,xml_in); | |
END; |
Documentación
https://github.com/edgargs/Ejemplo-2016-01.git
http://howtodoinjava.com/jaxb/jaxb-exmaple-marshalling-and-unmarshalling-list-or-set-of-objects/
http://viralpatel.net/blogs/oracle-xmltable-tutorial/
Top comments (0)