Conector de Integración con Ficheros y con Bases de Datos


La Interface XOne es uno de los componentes de la Tecnología XOne, su función es la de traspasar o convertir datos de una base de datos hacia otra, a través de un sencillo fichero XML de configuración.


La conversión/trasvase de datos, no necesariamente tiene que tener como destino otra Base de Datos, pudiendo tener como destino ficheros de texto, XML…

Aunque este producto puede ser utilizado de forma independiente a los demás sistemas de la tecnología XOne, suele utilizarse cuando los clientes no quieren hacer ningún cambio en sus sistemas y desean movilizar su aplicación, creando una Base de Datos independiente para el proyecto de movilidad que interactúe con su sistema a través de la Interface XOne.

Algunos ejemplos de Interface que tenemos en producción:


SISTEMA DEL CLIENTE SISTEMA DESTINO
SAP ORACLE
ORACLE ORACLE
ORACLE MS SQL SERVER
MS SQL SERVER MYSQL
FICHEROS DE TEXTO BASE DE DATOS


En general, podemos utilizar cualquier Base de Datos relacional que pueda ser conectada a través de OLEDB u ODBC.


Ficheros Necesarios


Nombre Fichero Descripción
itfxone.exe Programa Ejecutable
itfxone.ini XML con la ruta donde se encuentra el fichero de configuración
itfxone.xml XML con toda la configuración necesaria para el traspaso de datos


Fichero “itfxml.ini”


El fichero con la ruta donde está el XML de configuración, tiene una única línea donde se pone la ruta y el nombre del fichero XML.

Este fichero tiene que estar en la misma ruta donde se encuentre el ejecutable del programa


Estructura del fichero itfxml.ini

[XML]
 
Name=C:\Programas_Xone\CGInterClientXone\itfxone.xml
  • Tanto el nodo [XML] como el atributo “Name” son obligatorios.
  • El fichero XML de configuración aqui referenciado podemos llamarlo como queramos, no necesariamente itfxone.xml.


Fichero “itfxone.xml”


En dicho fichero XML se configura todo.

Conexión con la base de datos origen.
Conexión con la base de datos destino.
Cada cuanto tiempo se ejecuta el proceso.
Qué se realiza con los campos de origen en el destino.
Operaciones a realizar después de pasar los datos del origen al destino.
Permite el traspaso de datos de tipo texto, entero, con decimales, tipo fecha, ficheros…


Este fichero tiene 3 nodos principales:

Nombre nodo Explicación
<app> En este nodo definimos la conexión con las bases de datos de origen y destino, así como el nombre de ciertos campos especiales y cada cuánto tiempo se va a ejecutar este proceso.
<transforms type=“client-to-source”> En este nodo definimos las acciones y transformaciones de datos de la BD del cliente a la BD XOne.
<transforms type=“source-to-client”> En este nodo definimos las acciones y transformaciones de datos de la BD XOne a la BD del cliente.


Estructura simplificada del fichero itfxone.xml

<?xml version="1.0" encoding="ISO-8859-1"?>
 
<xml>
 
	<interface>
 
		<app name="INTERFASE" logoper="true" sqlfieldname="CGSSQL"  slash="false" rowidfieldname="CGSROWID">
 
			<dsn>
 
			...
 
			</dsn>
 
			<schedule type="continue" interval="30"/>
 
		</app>
 
 
 
		<transforms type="client-to-source">
 
			<transform name="DELEGACION">
 
				<coll ..... >
 
				...
 
				</coll>
 
				...
 
			</transform>
 
			...
 
		</transforms>
 
 
 
		<transforms type="source-to-client">
 
			<transform name="pedidos">
 
				<coll ..... >
 
				...
 
				</coll>
 
				....
 
			</transform>
 
			...
 
		</transforms>	
 
	</interface>
 
</xml>
Los nodos se ejecutan en orden de aparición, si queremos ejecutar primero el nodo <transforms type=“client-to-source”> es tan simple como que aparezca primero en el fichero XML, y los distintos transform que haya dentro, les ocurre exactamente lo mismo, se ejecutan por orden de aparición en el fichero.

Detalle del nodo ‹app›

<app name="INTERFACE" logoper="true" sqlfieldname="CGSSQL"  slash="false" rowidfieldname="CGSROWID">
 
	<!-- 
 
	logoper="true": todo lo que hace la interface, queda registrado en el visor de sucesos de windows.
 
		IMPORTANTE!!! en herramientas administrativas, hay que marcar en las propiedades del visor, 
 
		"sobreescribir cuando sea necesario" para evitar errores con un log muy extenso.		
 
	sqlfieldname="CGSSQL": en lugar de utilizar el campo "SQL" de la tabla master_replica_queue, 
 
		utiliza el que le especifiquemos aqui, puesto que hay algunos DBMS en los que "SQL" 
 
		es una palabra reservada (MYSQL 5.X). 
 
	slash="false": POR DEFECTO, cuando nos encontramos un caracter "\", lo duplicamos, ya que algunos sistemas
 
		de base de datos (MYSQL) lo eliminan, por lo que nosotros añadimos otro para que no haya errores. 
 
		Para aquellos sistemas que no eliminen el caracter "\" poner a false.
 
	rowidfieldname="CGSROWID": En la tecnología XONE todas las tablas deben contener un campo "ROWID",
 
 		que resulta ser una palabra reservada en ORACLE, podemos utilizar este parámetro para indicar
 
 		cómo hemos llamado a dicho campo en este DBMS.
 
	-->
 
 
 
	<dsn>
 
		<client type="system" name="DSN_BD_ORIGINAL_CLIENTE" user="ROOT" pwd="cgs"/>	
 
		<!-- 
 
		type="system"		: El DSN es de sistema.
 
		name="xxxxx" 		: Nombre del DSN de sistema que apunta a la BD origen del cliente.
 
		user="xxx" y pwd="xxx"	: Hemos de especificar el usuario y la contraseña de la BD.
 
		--> 
 
		<source type="system" name="DSN_BD_MOVILIDAD" user="sa" pwd=""/>
 
		<!-- 
 
		type="system"		: El DSN es de sistema.
 
		name="xxxxx" 		: Nombre del DSN de sistema que apunta a la BD destino XONE.
 
		user="xxx" y pwd="xxx"	: Hemos de especificar el usuario y la contraseña de la BD.
 
		--> 
 
		<optional type="system" name="DSN_BD_OPTIONAL_CLIENTE" user="root"/>
 
		<!-- DSN opcional a la BD de origen, para multiconexión. -->	
 
	</dsn>
 
	<schedule type="continue" interval="30"/>
 
	<!-- 
 
	type="continue"      : Para que se ejecute cada cierto tiempo, especificado por interval.
 
	     "one-execution" : Sólo se ejecuta una vez, al terminar se cierra el programa.
 
	interval="xxx"        : Intervalo en segundos para la siguiente ejecución si type="continue".
 
	-->
 
</app>

Detalle del nodo transforms

<transforms type="client-to-source">
 
<!-- 
 
type="client-to-source" : Seleccionamos datos de la BD del cliente para transformarlos y pasarlos a la BD Xone.
 
type="source-to-client" : Seleccionamos datos de la BD XOne para transformarlos y pasarlos a la BD del cliente.
 
-->
 
	<transform name="Nombre_de_la_transformacion">
 
	<!-- 
 
	Tendremos un nodo transform por cada tabla que vayamos a rellenar en la BD Destino.
 
	-->
 
	<coll dest-table="nombre_tabla" source-table="Select ..." tbl-queue="false">
 
	<!-- PRIMERO SE COGE LA TABLA DESTINO. DESPUES SE SELECCIONA EL SQL DE LA TABLA ORIGEN, SELECCIONANDO LOS CAMPOS
 
     QUE QUEREMOS PASAR DEL CLIENTE AL DESTINO 
 
     SERÍA CONVENIENTE LIMITAR LA CANTIDAD DE REGISTROS PARA NO TRANSFORMAR CADA VEZ MUCHOS REGISTROS, YA QUE PUEDE LLEVAR A 
 
     ERRORES CON EL ODBC DEL ORIGEN O DEL DESTINO. NO ES LO MISMO TRANSFORMAR 100 REGISTRO QUE 100.000 REGISTROS.-->
 
 
 
		<data-condition>
 
			<client type="##ALL##"/>
 
		</data-condition>
 
		<prop source-name="nombre_campo" dest-name="nombre_campo" key="true" saved-source="true">
 
			<oper type="copy"/>
 
		</prop>
 
		<prop 
 
		...
 
		</prop>
 
		...
 
		<after-action>
 
			<action name="...">
 
				<param name="source" value="...>
 
			</action>
 
		</after-action>	
 
	</coll>
 
</transform>
 
....
 
</transforms>

Nodos del fichero XML:




Nodo que se pone en la parte superior del fichero. Sirve para que se pueda utilizar la codificación ISO-8859-1, y admita, entre otras cosas, los acentos.

OPTATIVO

Nodo principal, es el padre de todos los nodos, y todo fichero tiene que tener este nodo, en el que irá todo lo demás.

OBLIGATORIO

Nodo hijo del nodo xml, dentro de este irá el resto de opciones.

OBLIGATORIO



Nodo en el que se define quienes son las bases de datos origen y destino para poder realizar la Interfase.

OBLIGATORIO


Dicho nodo, tiene varios atributos, que son:

NAME=“INTERFASE” nombre de la aplicación.
TIMEACCESS=“false” atributo de sistema, es obligatorio.
LOGOPER=“true” para activar el LOG, mostrando todo lo que hace el CGInterclientXone, en el Visor de Sucesos de Windows.
SQLFIELDNAME la aplicación cuando pasa los datos desde una base de datos hacia otra, también escribe en la cola de réplica.


Dicha tabla, tiene un campo SQL, que en el que se introducen los SQL de la réplica. Bien, pues ese nombre de ese campo es palabra reservada en algunos sistema de base de datos, como el MYSQL 5.0.

Entonces lo que hay que hacer es crear la cola de réplica, y cambiar el nombre SQL por otro cualquiera, y posteriormente se pone este nombre en dicho atributo, para que el programa sepa el cambio que hay.

SLASH atributo al cual le podemos decir que no se duplique el carácter “\”. El programa lo duplica automáticamente, pero hay algunos sistemas de base de datos, que no hace falta duplicarlo, poniendo a false dicho atributo.


Lo de duplicar es porque hay en sistemas, que ese atributo es una palabra reservada, y para decirle que no queremos que haga nada, pues lo duplicamos, y posteriormente el sistema quita el duplicado.


Nodo en el que están las llamadas a las base de datos con las que interactúa el CGInterclient. Está formado por nodos hijos, con las llamadas a las base de datos.

<client type="system" name="DSN_BD_Origen" user="usuario" pwd="contraseña"/>
 
<source type="system" name="DSN_BD_Destino" user="usuario" pwd="contraseña"/>


El primer nodo, CLIENT, es el nodo que tiene la llamada a la base de datos origen, a la base de datos del cliente. El segundo nodo, SOURCE, es la llamada a la base de datos destino, la base de datos de movilidad, de XOne. Estos nodos tienen los siguientes atributos:

Atributos
TYPE= hay que poner system, ya que solo se admiten DSN de sistema, que son más seguros que otro tipo de DSN, como los de archivo.
NAME= nombre del DSN de sistema, que hemos creado.
USER= usuario de la base de datos.
PWD= Contraseña de la misma, si la tuviera, si no la tiene, se queda vacío, o incluso no se pone este atributo.


Hay un tercer nodo, que se puede poner para la multiconexión.

<optional type="system" name="DSN_BD_OPTIONAL_CLIENTE" user="root"/>


Como se puede ver, está formado igual que el resto de nodos, pero su nombre es “optional”.




Nodo en el que se indica cada cuanto tiempo se ejecuta la interfase.

Tiene 2 atributos:

Atributos
TYPE se pone continue, para indicar que tiene que continuar el tiempo que se le dice en el siguiente atributo.
INTERVAL aquí se pone el tiempo que espera para volver a ejecutarse. Si se pone valor 0, es continuo y nunca se para. Si queremos que se ejecute cada 10 minutos, tendremos que poner 600.




Nodo con el que se decide en que orden se hace el paso de datos, si desde la base de datos declarada en el nodo CLIENT a la SOURCE o al revés. El tipo se pone en el atributo TYPE, poniendo “client-to-source” o “source-to-client”, según sea el orden.

Una vez que hemos decidido en que orden pasan los datos, se empiezan a definir cada unos de los nodos transform. Se realiza cada uno de estos nodos, para cada una de las tablas que se pasan de un lado a otro.


Dicho nodo tiene un atributo, NAME, cuyo valor es el nombre que se le da a nodo transform, y que tiene que ser único en todo el fichero XML.



Nodo en el que se coge la tabla origen y el destino de los datos.

Sus atributos son:

Atributos
DEST-TABLE atributo que tiene el nombre de la tabla destino.
SOURCE-TABLE atributo que coge el nombre de la tabla que tiene los datos. En dicho atributo se puede poner un SQL, todo lo complejo que admite el sistema gestor de base de datos que estemos utilizando.
ROWS-LIMIT DEPRECATED. Si se quiere limitar el número de registros que se procesan habría que apoyarse en las funciones del DBMS que estemos utilizando (TOP, LIMIT, ROWNUM, etc).
LIMIT-END DEPRECATED, similar al anterior, pero para los borrados. Si se quiere limitar el número de registros que se procesan habría que apoyarse en las funciones del DBMS que estemos utilizando (TOP, LIMIT, ROWNUM, etc).
TBL-QUEUE Por defecto vale TRUE. Si lo ponemos a false, le decimos a la interface que NO rellene el campo TBL de la tabla master_replica_queue.
FILE atributo para decirle al programa que se va a realizar el paso de datos desde un fichero. Si no se pone, es false. Sirve para que al realizar los pasos de campos numéricos con sus decimales lo haga de una forma correcta.
ALWAYS Dicho atributo sirve para decirle al programa que la interface es para pasar datos desde una base de datos, hacia un fichero de texto. Y en cada paso de la interface, solo se pasa un documento que cumple la condición. Esto se ha hecho porque hay algunos clientes que leen el fichero entero, y supone que solo tiene un documento dentro del mismo.
DATA-SOURCE Atributo parte de la multiconexión. Si no existe, coge como origen el DSN que está en el nodo “client” del nodo DSN. Si existe, coge como DSN el nodo “optional”, que va a tener como nombre de DSN el que se ha puesto aquí, y viceversa.
ALWAYS-INSERT Atributo que si se va a realizar un update por cambio en los datos que se pasan, realmente en la cola de réplica, master_replica_queue, lo pone como un insert.


<data-condition>  
 
<client type="##ALL##"/>    
 
</data-condition>


Nodo obligatorio para poder funcionar.




A partir de este momento, se empieza a poner los distintos nodos, “prop”, que van cogiendo los distintos campos, diciendo de cada campo, el tipo de traspaso que se hace del mismo, si es clave primaria o no, o el tipo de campo que es.

Atributos que tiene el nodo “prop”:

Atributos del NODO PROP
SOURCE-NAME: Nombre del campo de origen.
DEST-NAME Nombre del campo de destino.
TYPE Atributo para decirle el tipo de datos del campo que se va a pasar. Hay varias opciones: T:Campo de tipo de texto.D:Campo de tipo fecha. Nx: Campo numérico. X:Para pasar datos que van a ser claves.
KEY Para decirle que el campo es clave primaria o no en la tabla destino. Por este campo se realizan las búsquedas de si existe el registro en la tabla destino. La clave, por supuesto, puede ser múltiple, por lo que puede existir más de un campo que sea la clave primaria del registro. Este campo es obligatorio que como mínimo uno de los “prop” que tiene la “coll”, tenga este atributo a true.
SAVED-SOURCE Atributo que va a guardar el valor que tiene el campo “source-name” en una macro, para posteriormente realizar operaciones sobre los campos que cumplen la condición que guarda la macro. La macro es ##SOURCEKEYVALUES##.
SAVED-DEST Atributo que guarda los valores que tiene el campo “dest-name” en una macro, para posteriormente operar con los registros que cumplen la condición. La macro ##DESTKEYVALUES##.
FILLFIELD Atributo para añadir al campo destino el valor que tiene este atributo. Va acompañado de los dos atributos que están por debajo.
LENGTH Número de caracteres que añade el atributo “fillfield” al campo destino.
ALIGNAlineación de los caracteres que se añaden al campo destino. Si no se pone nada es izquierda. Para hacer alineación derecha hay que poner “rigth”.
ALWAYS-UPDATEInserta una modificación de dicho campo en la master_replica_queue siempre, aunque su valor no esté modificado.
NOT-REPLICATEAtributo para indicar que si la operación de este campo se inserta en las operaciones de la master_replica_queue. Si es true no se inserta dicho valor, si no existe o es false, se inserta en la operaciones de réplica.


Tipos de operaciones que se pueden realizar con los campos que se quieren pasar de una tabla a otra, en el nodo “prop”:

Tipos de Operaciones
SETVAL Con esta operación lo que se hace es poner un valor dado en el campo destino. Por eso, el nodo “prop”, solo tiene el tipo del campo, “type”, y el nombre del campo que es el destino, “dest-name”.


En el ejemplo, estamos poniendo en el campo IDPADRE de la table destino, que es de tipo numérico, N, el valor 1.

        <prop dest-name="IDPADRE" type="N">
 
	        <oper type="setval" value="1"/>
 
        </prop>


En este ejemplo ponemos el valor “xone” en el campo destino NOMBRE, que es de tipo texto.

        <prop dest-name="NOMBRE" type="T">
 
	        <oper type="setval" value="xone"/>
 
        </prop>


COPY Operación para pasar el valor de un campo origen a un campo destino. Esta es la operación que más se utiliza. Este nodo tiene un atributo para decir el campo origen, “source-name”, otro para decir el atributo destino, “dest-name” que son obligatorios. El resto de campos no son obligatorios, como el tipo, ya que si no se pone, él coge que es de tipo texto, aunque se aconseja que se ponga el tipo del campo siempre, para estar seguros de lo que estamos haciendo.


Ahora se van a poner distintos ejemplos que realizan esta operación:

EJEMPLO 1
Nodo que pasa el valor del campo “delegación” al campo “ETIQUETA”. Dicho campo es de tipo texto. También es clave primaria, por lo que para buscar si existe dicho campo en el destino, se busca con el “where” por este campo. También se le está diciendo que guarde el valor del origen en la macro ##SOURCEKEYVALUES##, y que guarde el valor del destino en la macro ##DESTKEYVALUES##.

                <prop source-name="delegación" dest-name="ETIQUETA" key="true" type="T" saved-source="true" saved-dest="true">
 
		        <oper type="copy"/>
 
                </prop>


EJEMPLO 2
Nodo que pasa el valor del campo “PASSWORD_E” al campo PWD. Como vemos tiene el tipo X, por lo que se le está indicando que es un campo contraseña, y su valor lo guarda encriptado.

           <prop source-name="PASSWORD_E" dest-name="PWD" type="X">
 
                    <oper type="copy"/>
 
           </prop>


EJEMPLO 3
Nodo que pasa el valor del campo “DESCPTE” al campo “INCIDENCIA”. El mismo es de tipo texto. También vemos que tiene el atributo “always-update”, por lo que le estamos obligando a que en la cola de réplica, “master_replica_queue”, se le inserte un update aunque su valor no cambie.

        <prop source-name="DESCPTE" dest-name="INCIDENCIA" key="false" type="T" always-update="true">
 
	          <oper type="copy"/>
 
        </prop>


EJEMPLO 4
Nodo que pasa el valor del campo “FECCARGA” al campo “FECHA. El campo es de tipo fecha. También se puede ver un nodo nuevo, FORMAT, nodo que se utiliza dentro de los nodos “prop”, y que sirve para formatear el valor en el destino con las características que se le diga en el atributo value. En el ejemplo, al ponerlo, le estamos diciendo que en el destino la fecha se tiene que insertar de modo día/mes/año.

         <prop source-name="FECCARGA" dest-name="FECHA" type="D">				
 
                  <oper type="copy"/>
 
                  <format name="dest-name" value="dd/mm/yyyy"/>
 
         </prop>


EJEMPLO 6
Nodo que pasa los datos del campo “CODAVISO” al campo “TIPOPARTE”, y vemos que es de tipo texto. También se puede ver que está el nodo “format”. Aquí se puede ver que tiene un atributo nuevo, “trim”. Dicho atributo lo que hace es eliminar o no los espacios en blanco que llegan del origen en el destino. El atributo si no se define esta a “true”, es decir, elimina los espacios en blanco. Para que funcione, es necesario poner en el atributo “value”, el valor “NULL”.

        <prop source-name="CODAVISO" dest-name="TIPOPARTE" type="T">
 
	     <oper type="copy"/>
 
	     <format value="NULL" trim="false"/>
 
        </prop>


EJEMPLO 7
Nodo que pasa los datos del campo “PRETAR” al campo “PRECIO”. Es de tipo numérico, y en concreto con 5 decimales. Para que la copia se haga bien, se le ha puesto el nodo “format”, poniendo exactamente el número de decimales que se le va a poner.

        <prop source-name="PRETAR" dest-name="PRECIO" type="N5">
 
	     <oper type="copy"/>
 
	     <format name="dest-name" value="0.00000"/>
 
        </prop>


EJEMPLO 8
Nodo que pasa el valor del campo “delegacion” al campo “NOMBRE2”. El mismo es de tipo texto. También se puede ver que tiene el atributo “fillfield”, con el que le estamos diciendo que en el destino le tenemos que añadir 0. Con el atributo “length” le decimos el campo destino tiene que tener 10 caracteres como valor total, por lo que el programa coge la longitud del campo origen, y la cantidad de caracteres que tenga menos de 10, es el número de 0 que tiene que insertar en el campo destino. Los ceros se lo añadiremos por la parte derecha, esto se le dice con el atributo “align”.

        <prop source-name="delegación" dest-name="NOMBRE2" key="true" fillfield="0" length="10" align="rigth" type="T" saved-source="true" saved-dest="true">
 
	        <oper type="copy"/>					
 
        </prop>



SOURCE-COPY Operación para copiar el valor del campo origen en el campo destino. Hay que tener en cuenta que tanto el campo origen como el destino, son de la misma tabla, la tabla que está en el atributo dest-table.


El ejemplo lo que hace es guardar el valor que hay en IDUSUARIO en IDUSUARIO2. Esto es útil para la selectividad, para guardar el valor en un segundo campo, y dicho campo sea también campo que decide la selectividad de dicha tabla.

        <prop source-name=" IDUSUARIO " dest-name=" IDUSUARIO2"  type="N">
 
	         <oper type="source-copy"/>
 
        </prop>
SUM Operación para sumar el valor que se coge del campo origen en el campo destino. Solo es válido para campos numéricos.


El ejemplo lo que hace es sumar el valor que hay en el campo de origen de source-name, CANTIDAD, al valor que hay en el destino de dest-name, CANTIDAD.

        <prop source-name="CANTIDAD" dest-name="CANTIDAD"  type="N2">
 
	        <oper type="sum"/>
 
	        <format name="dest-name" value="0.00"/>
 
        </prop>


MAPVAL Operación para pasar datos de campos relacionados con valores que hay en otras tablas. Lo que sería en nuestros mappings campos de tipo IDEMPRESA o IDUSUARIO. Para ello, lo que se hace es coger el valor del campo origen, y buscarlo en una tabla, cuando encuentra el valor, pone el valor de un campo que le decimos de esa tabla en el campo destino del principio.


EJEMPLO
En el ejemplo que se ve, se coge el valor del campo “delegación”, y se compara con el campo “ETIQUETA”, que se pone en el atributo “mapfld”, que existe en la tabla “Gen_Empresa”, definido en el atributo “source”. Si existe un registro que tenga ese valor, que solo tiene que existir uno, ya que el campo por el que se realiza la búsqueda en la tabla “Gen_Empresa”, tiene que ser la clave primaria del mismo, coge el valor del campo que se define en el atributo “targetfld”, “ID”, y lo pone en el campo “dest-name”, “IDEMPRESA”.

        <prop source-name="delegación" dest-name="IDEMPRESA" type=”N”>
 
	        <oper type="mapval" source="Gen_Empresa" targetfld="ID">
 
	        <prop mapfld="ETIQUETA" mapvalue="##SELF##"/>
 
	        </oper>
 
        </prop>


AGGREGATE Operación que concatena valores que hay en varios registros, para ponerlos solo en uno de destino.


EJEMPLO
Ejemplo que coge el valor que hay en “COD_EMP”, que tiene que existir como “prop” en el “coll” actual, y lo busca en el “sql”, con o sin where. Entonces va concatenando los distintos valores que cumplen la condición, poniendo el valor en OBSERVACIONES, separados por el valor que hay en el atributo “separator”. También existe la posibilidad de poner la opción tabla, que busca en toda la tabla, sin condición ni nada.
En el ejemplo tiene las 3 posibilidades de búsqueda de registros que tienen los campos a concatenar, pero solo se pone una opción.

 
<oper type="aggregate" function="CONCAT(##FLD_COD_EMP##)" separator="-">
 
        <param name="sql" value="select * from gen_usuarios"/> 
 
	<param name="sql" value="select * from gen_usuarios where COD_EMP=##FLD_COD_EMP##"/>
 
	<param name="table" table="gen_usuarios"/>
 
</oper>


Esta opción lo que hace es concatenar tantas veces el valor “A” separado por el valor de que hay en el atributo “separate”, como veces como se cumpla la condición del valor del SQL. Es como hacer un count con el select que se lanza en la tabla que se pone que realice la búsqueda.

        <oper type="aggregate" function="CONCAT(A)" separator="-">
 
	        <param name="sql" value="select * from gen_usuarios"/> 
 
	        <param name="sql" value="select * from gen_usuarios where COD_EMP=##FLD_COD_EMP##"/>
 
	        <param name="table" table="gen_usuarios"/>
 
        </oper>


Opción que concatena el primer valor que este definido de la tabla gen_usuarios, separados por el atributo de “separator”, en el campo OBSERVACIONES.

        <oper type="aggregate" function="CONCAT" separator="-">
 
        	<param name="sql" value="select * from gen_usuarios"/> 
 
        	<param name="sql" value="select * from gen_usuarios where COD_EMP=##FLD_COD_EMP##"/>
 
        	<param name="table" table="gen_usuarios"/>
 
        </oper>

Nodo que se ejecuta al terminar de realizar el traspaso de datos desde una tabla a otra. Dentro del mismo se pueden realizar 5 operaciones distintas, que son:

DELETE-TABLE:

Operación que borra la tabla destino, o la tabla origen.

En el ejemplo vemos que en el atributo “name” se pone “dest, para indicar que se quiere borrar la tabla destino, si se pone cualquier otro valor, borra la tabla origen.

     <action name="delete-table">
 
         <param name="dest"/>					
 
     </action>

EXECUTE-QUERY:

Ejecuta el SQL que se le da para que ejecute. Esto es bastante útil para poner una campo de la tabla origen con un valor, para indicar que ya se ha pasado ese valor a la tabla destino.

En el ejemplo dado, vemos que tiene dos nodos “param”, en lo que se le dice que SQL se va a ejecutar, en el atributo “value”. También en qué base de datos, el atributo “name”, se le pone “dest”, que es la base de datos destino, y “source”, que es la base de datos origen.

También se puede ver que utiliza las macros ##SOURCEKEYVALUES## y ##DESTKEYVALUES##, que has sido rellenadas mientras se traspasan los datos de una base de datos hacia otra.

<action name="execute-query">
 
<param name="source" value="Update Gen_DetDocumento SET ACTUALIZADO=1 WHERE ##SOURCEKEYVALUES##"/>				
 
<param name="dest" value="UPDATE Gen_Documentos  SET ACTUALIZADO=1  WHERE ID IN (SELECT IDDOCUMENTO FROM GEN_DETDOCUMENTO WHERE ##DESTKEYVALUES##)"/>
 
</action>

CREATE-FICHERO:

Operación que crea un fichero, en el lugar y nombre que se le dice, y además insertando el texto que se le pone.

El ejemplo, crea un fichero en la ruta “D:\Proyectos_Xone\Proyecto1\Interfase\2-pedidos”, el fichero se va a llamar “OK.txt”, y al mismo se le inserta el texto “OK”.

<action name="create-fichero" path="D:\Proyectos_Xone\Proyecto1\Interfase\2-pedidos\OK.txt" texto="OK"/>

DELETE-FICHERO:

Operación que borra un fichero. Se le pone el lugar donde está el mismo y el nombre.

Ejemplo que borra el fichero “ESSPDA.TXT” que está en la ruta “C:\Archivos de programa\ CGSoft\ CGInterclient\ Captura\ Ficheros”.

<action name="delete-fichero" path="C:\Archivos de programa\ CGSoft\ CGInterclient\ Captura\ Ficheros\ ESPPDA.TXT"/>

Nodo para crear una tabla en el destino, que normalmente será la que tomará los datos de destino. Puede ser una tabla de una base de datos o un fichero de texto. Lo normal es utilizarlo para crea el fichero de destino de los datos, cuando se pasan datos de una base de datos hacia ficheros de texto.

<create name="dest-table" value="CREATE TABLE pedidos.txt (IDENTIFICADOR Char(11),PEDIDO char(15),CLIENTE char(11),ANYO char(4),MES char(2),DIA char(2),ARTICULO char(15),VENDEDOR char(11),CANTIDAD Char(9),PRECIO Char(15),ALMACEN Char(50))"/>
 
                                                                                                                                                    .

Nodo que se ejecuta antes de empezar el traspaso de datos. Se pueden utilizar todas las operaciones que existen en el nodo “after-action”, además de esta que se documenta aquí.

EXIST-FICHERO:

Esta operación se ha realizado exclusivamente para realizar el traspaso de datos desde una base de datos hacia ficheros. Lo que hace es buscar el fichero que se le pone en el atributo path. Busca dicho fichero y si lo encuentra, no sigue y se para hasta que no exista ese fichero.

Lo que hace el ejemplo es mirar si existe el fichero de PATH1, si existe el mismo, y no existe el de PATH2, crea el de PATH2 con el texto que se le pone. No existiendo el fichero de PATH1 se para la ejecución del programa.

<action name="exist-fichero" path1="c:\Proyectos_Xone\Proyecto1\Interfase\2-pedidos\copy\pedidos.txt"
 
path2="c:\Proyectos_Xone\Proyecto1\Interfase\2-pedidos\copy\ok.txt" texto="OK"/>

Nodo para realizar un borrado de los datos que se le dicen. Puede borrar tanto del origen como del destino.
Hay varios tipos de operaciones “delete” que se pueden realizar, que son:

DELETE-CONDITIONAL:

Este es para realizar el borrado de los datos que coinciden con los datos que se buscan en el origen, a partir del campo o campos que coinciden con la clave primaria que hemos definido.

En los ejemplos que vemos abajo, solo vemos el nodo “delete”, pero hay que tener en cuenta que se tiene que hacer un nodo “coll” como si fuéramos a pasar datos de una tabla a otra, por lo que tiene que tener como mínimo un nodo “prop” que tenga el atributo “key” igual a “true”.

En el ejemplo se realiza el borrado en la tabla “gen_sat”, de la base de datos de destino, por utilizar el atributo “delete-dest-table”, de aquellos datos que coinciden con la macro

##DESTKEYVALUES##.

<delete>
 
<action name="delete-conditional" delete-dest-table="gen_sat" use-saved-dest="true"/>
 
</delete>

Con este ejemplo se realiza el borrado en la base de datos origen como en la de destino. Para indicar una tabla de origen se utiliza el atributo “delete-source-table”, con este atributo se utiliza la macro ##SOURCEKEYVALUES##.

<delete>
 
<action name="delete-conditional" delete-dest-table="gen_usuarios" use-saved-dest="true"/>
 
<action name="delete-conditional" delete-source-table="EVUSUA" use-saved-source="true"/>
 
</delete>

DELETE-SQL:


Esta operación sirve para realizar el borrado tanto en el cliente, como en la base de datos de XOne, para que además de borrar de la tabla normal, inserta el borrado en la cola de réplica.

WHERE Es la condición de borrado. Se pueden utilizar las macros ##SOURCEKEYVALUES## y ##DESTKEYVALUES##.
DELETE-DEST-TABLE Atributo para indicar en qué tabla se quiere realizar el borrado. Si no se pone dicho atributo, se coge el valor que hay en el atributo del nodo “coll”, “dest”. Realiza el borrado de los registros que tienen el ROWID que cumplen la condición que se pone en el atributo “where”.
SELECT-DEST-TABLE Atributo para realizar la búsqueda de los registros que se quieren borrar. Puede ser cualquier tabla, pero hay que tener en cuenta, que se realiza la búsqueda de valores en dicha tabla, cogiendo el ROWID de los registros que cumplen el atributo “where”, y de esos ROWID se realiza el borrado. Si no se pone nada, se coge el valor que hay en el atributo del nodo “coll”, “dest”.
ALIAS-DEST-TABLE Alias de la tabla de la que se realiza la búsqueda, y posteriormente el borrado.
SOURCE-TABLE Para decir de que tabla origen queremos realizar el borrado.
DELETE-SOURCE Si se declara dicho atributo, y además está declarado el atributo “source-table”, realiza el borrado en tabla origen también, con la condición que se pone en el atributo “where”.


El ejemplo que se muestra en la parte de abajo, realiza las siguientes cosas:

1. Se realiza la búsqueda de en la base de datos de destino, en la tabla “gen_colla”(select-dest-table) de los ROWID que cumplen la condición del “where”(where), con el alias “c”(alias-dest-table).

SELECT c.ROWID FROM Gen_Colla WHERE ESTADO=1

2. Si hay valores con esa condición, los borra de la tabla “gen_colla”( delete-dest-table).

3. Si se encontró algún registro con el punto 1, existe el atributo delete-source=”true”, el atributo “source-table” con un nombre de tabla y hay una condición, se realiza el borrado en la tabla “Gen_USUARIOS”( source-table), con la condición que hay en el atributo “where”.

<delete>
 
<action name="delete-sql" source-table="Gen_USUARIOS" delete-source="true" where="ESTADO=1" delete-dest-table="Gen_Colla" select-dest-table="Gen_Colla" alias-dest-table="c"/>
 
</delete>
 
                                                                                                                                    .

DELETE-FICHERO:

Operación que sirve para realizar el borrado de un fichero.

Realiza el borrado del fichero que existe en el atributo “PATH”, con lugar y nombre del mismo.

<action name="delete-fichero" path="C:\Archivos de programa\CGSoft\CGInterclient\Captura\Ficheros\ESPPDA.TXT"/>