Archivo de plantilla de consulta

El archivo de plantilla de consulta es un mecanismo mediante el cual se puede correlacionar fácilmente una consulta del modelo lógico con una o más sentencias SQL. Los elementos de SQL se conservan en archivos independientes, que están aislados del código Java de tiempo de ejecución. Esta plantilla ayuda a los administradores y programadores de la base de datos a localizar y analizar sentencias SQL. Además, los cambios en SQL que se utilizan para consultas no requieren la recompilación del código Java. Asimismo, es posible que la adición de nuevas columnas a las tablas existentes no requiera cambiar las sentencias SQL que utilizan dichas tablas. La información de las columnas aparece separada en la sección SYMBOL_DEFINITIONS.

Ubicación y denominación del archivo de plantilla de consulta

Un módulo de servicio puede tener uno o más archivos de plantilla de consulta. Asigne el prefijo 'wc-query' a los archivos de plantilla y utilice la extensión .tpl.

Los archivos de plantilla de consulta predeterminados están en los siguientes directorios: workspace_dir\WC\xml\config\com.ibm.commerce.servicemodule

Puede añadir nuevas consultas o ampliar las consultas facilitadas, colocando sus archivos de plantilla de consulta bajo el directorio de configuración ampliado del módulo de servicio.

Los archivos de plantilla de consulta personalizados deben colocarse en los siguientes directorios: workspace_dir\WC\wc\xml\config\com.ibm.commerce.servicemodule-extPor ejemplo, un archivo de plantilla de consulta de catálogo se encuentra en este directorio: xml\config\com.ibm.commerce.catalog-ext.

Nota: Añadir nuevas columnas a las tablas personalizadas requiere cambiar los SDO físicos que representan esas tablas, con el asistente de Capa de servicios de datos.

Sintaxis y carga del archivo de plantilla de consulta

Los archivos de plantilla de consulta se cargan por orden alfanumérico ascendente. Cuando se cargan archivos que contienen definiciones de consulta, las nuevas consultas alteran las consultas cargadas anteriormente.

Los bloques de la plantilla de consulta han de estar en este orden.

  1. BEGIN_SYMBOL_DEFINITIONS
  2. END_SYMBOL_DEFINITIONS
  3. BEGIN_XPATH_TO_SQL_STATEMENT
  4. END_XPATH_TO_SQL_STATEMENT
  5. BEGIN_ ASSOCIATION_SQL_STATEMENT
  6. END_ ASSOCIATION_SQL_STATEMENT
  7. BEGIN_SQL_STATEMENT
  8. END_SQL_STATEMENT
  9. BEGIN_PROFILE
  10. END_PROFILE.
Los bloques BEGIN_PROFILE_ALIASES y END_PROFILE_ALIASES pueden definirse en cualquier lugar dentro de un archivo de plantilla de consulta.
Nota:
  • Cada línea de comentario o bloque de comentario ha de empezar por <!-- y finalizar por -->. Un bloque o una línea de comentario pueden estar en cualquier lugar del archivo.
  • Durante el desarrollo, es posible que desee modificar y volver a cargar un archivo de plantilla de consulta sin tener que reiniciar el servidor. Puede utilizar un archivo .reloadconfig. Para obtener más información sobre el archivo .reloadconfig, consulte recarga de la configuración de un módulo de servicio BOD.

Organización del archivo de plantilla de consulta

Un archivo de plantilla de consulta tiene cinco secciones principales, de las cuales las dos primeras son obligatorias:
SYMBOL_DEFINITIONS
La sección de definición de símbolo de columna define símbolos de columna que se utilizan y a los que se hace referencia en la lista SELECT de las sentencias SQL de plantilla. Si el esquema físico cambia, podrá ajustar los símbolos sin volver a escribir el SQL. La definición de símbolos es parecida a la definición de constantes en lenguajes de programación. Puede definir información en una ubicación y utilizarla en varios lugares. Este método ayuda a localizar el lugar donde se debe realizar la actualización si se necesitan realizar cambios futuros. Al definir un subconjunto de columnas para seleccionar de una tabla, asegúrese de que la consulta incluye las columnas de clave primaria y foránea.
  • Solo debe haber un bloque BEGIN_SYMBOL_DEFINITIONS, END_SYMBOL_DEFINITIONS por archivo de plantilla de consulta.
  • Todos los símbolos deben definirse en el bloque BEGIN_SYMBOL_DEFINITIONS.
  • Pueden ser una línea de comentario o una línea de definición de símbolo. La definición de símbolo debe completarse en una línea.
  • Una línea de definición de símbolo solo define una definición de símbolo.
  • El nombre de símbolo, entre "COLS:" y '=', es el único identificador de los símbolos. Los caracteres legales de los símbolos son a-z, A-Z y 0-9.
  • Si el comodín (*) se utiliza en la definición de columna, los nombres de columna se recuperan de Metadatos relacionales de objeto y las definiciones de columna tienen un ámbito de archivo.
Ejemplo
BEGIN_SYMBOL_DEFINITIONS

	COLS:CATENTRY_ID=CATENTRY:CATENTRY_ID
	COLS:CATENTRY=CATENTRY:*	
	COLS:CATENTDESC=CATENTDESC:CATENTRY_ID,SHORTDESCRIPTION, OPTCOUNTER

END_SYMBOL_DEFINITIONS
Nota: Cuando defina un subconjunto de las columnas para seleccionar en una tabla, incluya la columna OPTCOUNTER. Consulte Bloqueo optimista para obtener más detalles. Debe añadir siempre una columna OPTCOUNTER a las tablas personalizadas. Por ejemplo:
COLS:DMACTIVITY_NAME=DMACTIVITY:DMACTIVITY_ID, NAME, OPTCOUNTER 
XPATH_TO_SQL_STATEMENT
La XPATH_TO_SQL_STATEMENT enlaza las capas lógica y física correlacionando directamente una clave XPath con una sentencia SQL. El nombre de XPATH_TO_SQL_STATEMENT es la clave de una expresión XPath. En el caso de consultas de un solo paso, este nombre es una combinación de la clave XPath y el perfil de acceso. Por ejemplo, si la clave XPath es /CatalogEntry[CatalogEntryIdentifier[ExternalIdentifier[(PartNumber=)]]] y el perfil de acceso es IBM_Admin_Details, el nombre de una plantilla de un solo paso es /CatalogEntry[CatalogEntryIdentifier[ExternalIdentifier[(PartNumber=)]]]+IBM_Admin_Details . Puede utilizar el programa de utilidad wcs_xpathkey para obtener la clave XPath para una expresión XPath.
Nota: La correlación de la clave XPath con la consulta SQL se puede alterar temporalmente. Si se define una clave XPath en más de un archivo de plantilla de consulta, el que esté definido en el último archivo cargado alterará temporalmente los demás.
  • Puede haber más de un bloque BEGIN_XPATH_TO_SQL_STATEMENT, END_XPATH_TO_SQL_STATEMENT.
  • Cada bloque define únicamente una sentencia SQL.
  • Cada bloque debe tener definidos un nombre (name) y una tabla base (base_table).
  • No se permiten espacios en el nombre.
  • La sentencia SQL puede tener varias líneas y debe definirse en último lugar en el bloque.
  • La etiqueta opcional dbtype se especifica cuando una sentencia SQL es específica de la plataforma de la base de datos. Este código es útil cuando se desarrollan sentencias SQL para varias plataformas de base de datos. Estas sentencias se pueden incluir en un solo archivo de plantilla. Los valores válidos para la etiqueta dbtype incluyen 'db2', 'oracle', 'derby' y 'any'. Las consultas para las que no se ha especificado ese código se aplican a todas las plataformas de base de datos. Si incluye una consulta para una plataforma de base de datos específica, incluya también una predeterminada (valor dbtype 'cualquiera') para utilizarla en otras plataformas.
  • Los elementos del bloque debe estar en el mismo orden que el que se muestra en el ejemplo.
    Ejemplo
    BEGIN_XPATH_TO_SQL_STATEMENT
    name=/CatalogEntry[CatalogEntryIdentifier[ExternalIdentifier[(PartNumber=)]]]
    base_table=CATENTRY
    sql=
    SELECT 
    	CATENTRY.$COLS:CATENTRY_ID$
    FROM
    	CATENTRY
    JOIN
    	STORECENT ON (CATENTRY.CATENTRY_ID = STORECENT.CATENTRY_ID AND
    	STORECENT.STOREENT_ID = $CTX:STORE_ID$)
    WHERE
    	CATENTRY.PARTNUMBER IN (?PartNumber?) 
    	AND CATENTRY.MARKFORDELETE = 0
    
    END_XPATH_TO_SQL_STATEMENT 
    
  • El fragmento de código anterior contiene códigos CTX que representan contextos de negocio. La capa de servicios de datos permite a un desarrollador especificar un código especial, $CTX:KEY$, en la plantilla SQL. La capa de servicios de datos utiliza este código para ayudar a extraer de la base de datos información según el contexto. Este código se sustituye en el tiempo de ejecución por el valor de la propiedad de contexto, como ID de idioma o ID de tienda, correspondiente a 'KEY'.

    Para obtener más información sobre estas etiquetas, consulte etiquetas de archivo de plantilla de consulta.

  • La sentencia SQL se puede escribir para gestión de contenido de espacio de trabajo.

    Para obtener más información sobre la escritura para la gestión de contenido de espacio de trabajo, consulte Técnicas para mejorar el rendimiento de las consultas SQL en espacios de trabajo de la capa de servicios de datos.

ASSOCIATION_SQL_STATEMENT
Las sentencias SQL asociadas definen una consulta SQL específica. Entonces estas consultas se pueden reutilizar para crear perfiles de acceso diferentes que se definen en la sección PROFILE.
  • Puede haber más de un bloque BEGIN_ ASSOCIATION_SQL_STATEMENT, END_ ASSOCIATION_SQL_STATEMENT.
  • Cada bloque puede definir como máximo una sentencia SQL.
  • Las reglas del bloque XPATH_TO_SQL_STATEMENT se aplican a este bloque.
  • El nombre es el indicador exclusivo de la ASSOCIATION_SQL_STATEMENT.
Ejemplo
BEGIN_ASSOCIATION_SQL_STATEMENT
	name=IBM_CatalogEntryWithDescription
	base_table=CATENTRY
	sql=
	     SELECT 
	        CATENTRY.$COLS:CATENTRY$,
                CATENTDESC.$COLS:CATENTDESC$
	     FROM
	        CATENTRY
	           LEFT OUTER JOIN CATENTDESC ON 
                     (CATENTDESC.CATENTRY_ID = CATENTRY.CATENTRY_ID  AND 
                      CATENTDESC.LANGUAGE_ID IN ($CONTROL:LANGUAGES$))
	     WHERE
                CATENTRY.CATENTRY_ID IN ($ENTITY_PKS$)
END_ASSOCIATION_SQL_STATEMENT
SQL_STATEMENT
Esta sección contiene sentencias SQL con nombre. Las sentencias SQL se ejecutan directamente mediante la interfaz JDBC con la clase JDBCQueryService. Esta clase es parecida al ayudante de JDBC del bean de sesión utilizado por los módulos de servicio SOI. Esta sección puede contener sentencias de selección que utilicen funciones de totales, como sum() o avg(). Debido al uso de estas funciones, las consultas no se correlacionan con objetos Java físicos por metadatos relacionales de objeto.

En determinadas circunstancias, puede ser necesario ejecutar las sentencias SQL para actualizar datos, eliminar datos o recuperar datos independientes del modelo de datos. Por ejemplo, una operación de negocio puede insertar o eliminar registros en tablas de datos que no estén definidas en el modelo lógico. La empresa que opera tambiéon puede actualizar varios objetos de datos que son más eficientes para emitir una sentencia SQL directa en lugar de utilizar la capa de servicios de datos para recuperar y actualizar cada objeto.

Ejemplo
BEGIN_SQL_STATEMENT
	name=IBM_Update_DeleteCatalogEntry
	base_table=CATENTRY
	sql= UPDATE CATENTRY   	
				SET CATENTRY.PARTNUMBER=
	     				CASE WHEN 
	     					LENGTH(CATENTRY.PARTNUMBER||'-'||$DB:CURRENT_TIMESTAMP$)<=64 
	     				THEN 
	     					CATENTRY.PARTNUMBER||'-'||$DB:CURRENT_TIMESTAMP$  
	     				ELSE 
	     					SUBSTR(CATENTRY.PARTNUMBER,1,64-LENGTH(''||$DB:CURRENT_TIMESTAMP$)-1)||'-'||$DB:CURRENT_TIMESTAMP$ END
	     				,CATENTRY.MARKFORDELETE=1
	     	WHERE
			CATENTRY.CATENTRY_ID=?catalogEntryId? 
			OR CATENTRY.CATENTRY_ID IN (SELECT CATENTREL.CATENTRY_ID_CHILD FROM CATENTREL WHERE CATENTREL.CATENTRY_ID_PARENT=?catalogEntryId?)
END_SQL_STATEMENT	

La clase JDBCQueryService da soporte a las sentencias de actualización, inserción y supresión de lotes con la interfaz de actualización de lotes executeBatchUpdate.

Nota: La sección SQL_STATEMENT aparece solo en el archivo wc-query-utilities.tpl. Esta aparición es un convenio especial para un archivo de plantilla de consulta que contiene estas sentencias SQL nombradas.
Nota: No debe leer ni actualizar nunca los mismos datos utilizando JDBCQueryService y PhysicalDataContainer en la misma transacción. Si lo hace, existe la posibilidad de que pueda leer datos obsoletos o terminar con datos corruptos en la base de datos.
La sentencia SQL se puede escribir para gestión de contenido de espacio de trabajo. Para obtener más información sobre la escritura para la gestión de contenido de espacio de trabajo, consulte Técnicas para mejorar el rendimiento de las consultas SQL en espacios de trabajo de la capa de servicios de datos.
PROFILE
Esta sección define perfiles de acceso que utilizan sentencias SQL asociadas. Si es necesario, un perfil puede utilizar más de una sentencia SQL asociada. Cada una de las sentencias SQL asociadas se ejecuta una por una y los resultados de las distintas sentencias SQL asociadas se fusionan utilizando una clase GraphComposer.

Las consultas que están asociadas a un perfil de acceso siempre deben definirse en el mismo archivo en el que está definido el perfil de acceso. La excepción para esta ubicación definición es cuando se amplía un perfil de acceso. El mecanismo de ampliación proporciona la capacidad de reutilizar las sentencias SQL asociadas predeterminadas sin tener que volver a definirlas en el archivo de plantilla de consulta personalizado.

  • Puede haber más de un bloque BEGIN_PROFILE, END_PROFILE.
  • Todos los bloques de perfil han de estar al final del archivo.
  • Cada bloque tiene un nombre de perfil que está definido y el nombre de perfil es el identificador exclusivo del perfil.
  • Cada bloque de perfil puede tener únicamente un bloque BEGIN_ENTITY, END-ENTITY y en cada bloque de entidad.
    • La tabla base ha de estar definida.
    • Puede haber una o más sentencias SQL asociadas (associated_sql_statement) definidas. Esta associated_sql_statement debe coincidir con uno de los nombres de ASSOCIATION_SQL_STATEMENT definidos. Además, el nombre de tabla base definido en el bloque de entidad debe coincidir con el nombre de tabla base de las consultas correspondientes en el bloque ASSOCIATION_SQL_STATEMENT y el bloque XPATH_TO_SQL_STATEMENT que se utiliza en el perfil de acceso.
    • Se puede especificar un Compositor gráfico opcional en el bloque de entidad. Si se especifica el nombre de clase (className), ha de ser la vía de acceso completa de la clase, y la clase debe crear una subclase de com.ibm.is.component.dsl.GraphComposer.
Ejemplo
BEGIN_PROFILE 
 name=IBM_Admin_Summary
 BEGIN_ENTITY
   base_table=CATENTRY
   associated_sql_statement=IBM_CatalogEntryWithDescription
 END_ENTITY
END_PROFILE
PROFILE_ALIASES
Utilice la sección PROFILE_ALIASES para definir los alias para los perfiles. Los alias tienen un ámbito global y se utilizan para soportar perfiles de acceso en desuso que se redenominan. Puede especificar alias para perfiles de acceso diferentes en un único bloque BEGIN_PROFILE_ALIASES - END_PROFILE_ALIASES cuando los perfiles se aplican a la misma tabla base, por ejemplo, el mismo nombre.
Por ejemplo, el código siguiente define el IBM_CatalogAttachmentReference y IBM_CatAttachment como alias del perfil IBM_Admin_CatalogAttachmentReference.
BEGIN_PROFILE_ALIASES
  base_table=CATALOG
  IBM_CatalogAttachmentReference=IBM_Admin_CatalogAttachmentReference
  IBM_CatAttachment=IBM_Admin_CatalogAttachmentReference
END_PROFILE_ALIASES

Soporte para alias de columnas

Para evitar la ambigüedad en seleccionar columnas con nombre idéntico de diferentes tablas, se utilizan alias de columnas. El prefijo de alias de columna se puede especificar antes de una referencia de símbolo de columna. La sintaxis general de la referencia del símbolo de columna es:

[<table_alias>.][<columns_alias_prefix>]$COLS:<column_symbol_name>$
Por ejemplo:

WITH TEMP_TABLE AS (
SELECT 
      CATENTRY.CE_$COLS:CATENTRY_ID$, ATTRVALUE.ATTR_$COLS:ATTRVALUE$, ATTRVALUE2.ATTR2_$COLS:ATTRVALUE$
FROM CATENTRY, ATTRVALUE 
JOIN ATTRIBUTE 
      ON ATTRIBUTE.LANGUAGE_ID = ATTRVALUE.LANGUAGE_ID 
      AND ATTRIBUTE.ATTRIBUTE_ID = ATTRVALUE.ATTRIBUTE_ID 
LEFT OUTER JOIN ATTRVALUE ATTRVALUE2 
      ON ATTRIBUTE.ATTRIBUTE_ID = ATTRVALUE2.ATTRIBUTE_ID 
      AND ATTRVALUE2.CATENTRY_ID = 0 
      AND ATTRIBUTE.LANGUAGE_ID = ATTRVALUE2.LANGUAGE_ID 
WHERE CATENTRY.CATENTRY_ID IN ($ENTITY_PKS$) 
      AND ATTRVALUE.CATENTRY_ID = CATENTRY.CATENTRY_ID 
) SELECT * FROM TEMP_TABLE
Supongamos que existen las siguientes definiciones de símbolos:

COLS:CATENTRY_ID=CATENTRY:CATENTRY_ID
COLS:ATTRVALUE=ATTRVALUE:ATTRVALUE_ID,LANGUAGE_ID
La consulta resultante se convierte como:

WITH TEMP_TABLE AS (
SELECT 
      CATENTRY.CATENTRY_ID CE_CATENTRY_ID, 
      ATTRVALUE.ATTRVALUE_ID ATTR_ATTRVALUE_ID, ATTRVALUE.LANGUAGE_ID ATTR_LANGUAGE_ID,                         
 ATTRVALUE2.ATTRVALUE_ID ATTR2_ATTRVALUE_ID, ATTRVALUE2.LANGUAGE_ID ATTR2_ATTRVALUE_ID
FROM CATENTRY, ATTRVALUE 
JOIN ATTRIBUTE 
      ON ATTRIBUTE.LANGUAGE_ID = ATTRVALUE.LANGUAGE_ID 
      AND ATTRIBUTE.ATTRIBUTE_ID = ATTRVALUE.ATTRIBUTE_ID 
LEFT OUTER JOIN ATTRVALUE ATTRVALUE2 
      ON ATTRIBUTE.ATTRIBUTE_ID = ATTRVALUE2.ATTRIBUTE_ID 
      AND ATTRVALUE2.CATENTRY_ID = 0 
      AND ATTRIBUTE.LANGUAGE_ID = ATTRVALUE2.LANGUAGE_ID 
WHERE CATENTRY.CATENTRY_ID IN ($ENTITY_PKS$) 
      AND ATTRVALUE.CATENTRY_ID = CATENTRY.CATENTRY_ID 
) SELECT * FROM TEMP_TABLE