Tareas específicas de DL/I

A continuación se ofrecen instrucciones específicas para realizar las siguientes tareas de DL/I: Todos los ejemplos de estas instrucciones utilizan la Base de datos de ejemplo DL/I.

Utilizar llamadas de vía de acceso para acceder a varios segmentos

Si invoca una sentencia de E/S EGL con un objeto de registro de segmento dependiente, puede leer cualquiera de los segmentos de la vía de acceso desde el raíz hasta el objeto simultáneamente. Puede hacerlo añadiendo simplemente los registros de la llamada de vía de acceso a la sentencia. Por ejemplo, al recuperar un segmento de pedido (order) de la base de datos de clientes de ejemplo, puede leer el segmento de cliente y el segmento de ubicación en la misma llamada:
get myCustomer, myLocation;
Esta sentencia genera el siguiente pseudocódigo DL/I:
GU STSCCST*D (STQCCNO = :myCustomer.customerNo) 
   STSCLOC (STQCLNO = :myLocation.locationNo)
Si utiliza el código del mandato D en una sentencia get...forUpdate, la sentencia replace subsiguiente afectará a todos los segmentos recuperados. Puede evitar la sustitución de un segmento seleccionado especificando un código de mandato N explícito en el SSA de la palabra clave replace, como en el ejemplo siguiente:
get myCustomer, myLocation forUpdate;
replace myLocation with #dli{
	REPL STSCCST*N
	     STSCLOC };
La llamada DL/I por omisión que EGL crea para una función delete que sigue a una sentencia get forUpdate con los códigos de mandato D no suprime cada segmento recuperado. Sólo suprime el segmento de objeto de E/S.

Leer todos los segmentos con una sola llamada

Puede utilizar una sola función para leer todos los segmentos de una base de datos. Si emite una llamada DL/I get next sin SSA, DL/I devuelve el próximo segmento de la base de datos independientemente de su tipo. Para utilizar este procedimiento, siga estos pasos:
  1. Escriba una sentencia get next para el registro que representa el segmento más grande de la base de datos. Esto garantiza que cualquier segmento que lea no sobrepasará la memoria asignada.
  2. Edite la llamada DL/I por omisión de la sentencia para suprimir el SSA único.
  3. Cree registros que coincidan con los demás segmentos de la base de datos. Declárelos como registros redefinidos para el registro del paso 1.
  4. Compruebe DLIVar.segmentName después de la sentencia get next para determinar el tipo de segmento que se ha recuperado.
  5. Acceda al segmento recuperado desde la estructura de registro redefinido o asigne la estructura redefinida a otro registro del mismo tipo.
A continuación figura un ejemplo de código que imprimirá todo el contenido de la base de datos de clientes. En este ejemplo, HistoryRecordPart es el registro DLISegment de mayor tamaño:
redefCustomer CustomerRecordPart {redefines=HistoryRecordPart};
redefLocation LocationRecordPart {redefines=HistoryRecordPart};
...


//leer el próximo segmento, sea cual sea su tipo, del registro histórico
while (myHistory not EOF)
	get next myHistory with #dli{
		GN };

	//¿de qué tipo era?
	case (DLIVar.segmentName)
		when "STSCCST"                   // era customer
 			myCustomer = redefCustomer;
			printCustomer();               // myCustomer es global
		when "STSCLOC"                   // era location
 			myLocation = redefLocation;
			printLocation();
		...
	end
end

Buscar con un índice secundario

Hay varias maneras de añadir índices secundarios a una base de datos. La más sencilla consiste en añadir un campo secondaryIndex a la propiedad @PCB de la variable DB_PCBRecord del registro PSB. Si se trata del primer DB_PCBRecord del registro PSB, EGL utilizará este índice secundario por omisión. Por ejemplo, si desea buscar clientes en función del campo orderReference (STFCORF) del segmento orders, puede añadir un índice secundario al customerPCB de la base de datos de ejemplo, del siguiente modo:
//
PCB de base de datos	
customerPCB DB_PCBRecord { @PCB {
	pcbType = DB,
	pcbName = "STDCDBL",
	secondaryIndex = "STFCORF", //utilizar nombre DL/I
	hierarchy = [
		@Relationship { segmentRecord = "CustomerRecordPart"},
	 	@Relationship { 
			segmentRecord = "LocationRecord", 
			parentRecord = "CustomerRecordPart" }, 			
		@Relationship {
 			segmentRecord = "OrderRecord",
			parentRecord = "LocationRecordPart" },
		...
Realice una operación get para localizar un cliente (customer), como en el ejemplo siguiente:
get myCustomer;
EGL generará el siguiente código por omisión:
	GU STSCCST (STFCORF = :myOrder.orderReference)
Si desea poder elegir entre acceder a los clientes por orderReference o por customerNo, cree un segundo PCB para el índice secundario. En el ejemplo siguiente, el segundo PCB se denomina orderReferencePCB:
// PCB de base de datos --acceso
por número de cliente
customerPCB DB_PCBRecord { @PCB {
	pcbType = DB,
	pcbName = "STDCDBL",
	hierarchy = [
		@Relationship { segmentRecord = "CustomerRecordPart"},
	 	@Relationship { 
			segmentRecord = "LocationRecord", 
			parentRecord = "CustomerRecordPart" }, 			
		@Relationship {
 			segmentRecord = "OrderRecord",
			parentRecord = "LocationRecordPart" },
		...

// PCB de base de datos --acceso por referencia de pedido
orderReferencePCB DB_PCBRecord { @PCB {
	pcbType = DB,
	pcbName = "STDXDBL",
	secondaryIndex = "STFCORF", //utilizar nombre DL/I
	hierarchy = [
		@Relationship { segmentRecord = "CustomerRecordPart"},
	 	@Relationship { 
			segmentRecord = "LocationRecord", 
			parentRecord = "CustomerRecordPart" }, 			
		@Relationship {
 			segmentRecord = "OrderRecord",
			parentRecord = "LocationRecordPart" },
		...
El nombre del PCB (pcbName) debe coincidir con un PCB DL/I real. Ahora, el comportamiento por omisión de EGL será una vez acceder a un registro de cliente utilizando el campo customerNo. Para acceder a él utilizando la clave alternativa, la sentencia de E/S EGL debe especificar el orderReferencePCB con la palabra clave usingPCB , como en el ejemplo siguiente:
get myCustomer usingPCB orderReferencePCB;
También puede darse un caso más complejo, si desea cambiar la estructura de toda la base de datos cuando la visualiza el programa. (De nuevo, recuerde que la estructura del PCB del programa EGL debe coincidir con un PCB DL/I existente). Supongamos que desea que la base de datos de cliente parezca una base de datos de pedidos de cara al programa, con el número de referencia exclusivo como clave del segmento orders (pedidos). Puede tener un PCB con la siguiente estructura:
// vista de pedidos de la base de datos de
clientes
ordersPCB DB_PCBRecord { @PCB {
	pcbType = DB,
	pcbName = "STDCDBL",
	secondaryIndex = "STFCORF", //utilizar nombre DL/I
	hierarchy = [
		@Relationship { segmentRecord = "OrderRecordPart" },
		@Relationship { 
			segmentRecord = "LocationRecordPart", 
			parentRecord = "OrderRecordPart" },
		@Relationship { 
			segmentRecord = "CustomerRecordPart", 
			parentRecord = "LocationRecordPart" },
		@Relationship { 
			segmentRecord = "CreditRecordPart", 
			parentRecord = "CustomerRecordPart" },
		@Relationship { 
			segmentRecord = "HistoryRecordPart", 
			parentRecord = "CustomerRecordPart" },
		@Relationship { 
			segmentRecord = "ItemRecordPart", 
			parentRecord = "OrderRecordPart" }]}};
end
Suponiendo que el número de referencia de pedido sea exclusivo de cada cliente y pedido, y suponiendo que ordersPCB es ahora el PCB por omisión, puede buscar el cliente de un pedido realizando una llamada de vía de acceso modificada que elimine los calificadores de la ubicación y del cliente:
get myOrder, myCustomer with #dli{
	GU STPCORD (STQCODN = :myOrder.orderReference)
	   STSCLOC
	   STSCCST };

Buscar con otro campo no de clave

Puede utilizar cualquier campo de un segmento como argumento de búsqueda en una llamada DL/I modificando los argumentos de búsqueda (SSA) de la llamada. Por ejemplo, si desea leer la base de datos de clientes y recuperar el segmento de cliente y el segmento de crédito de cada cliente cuyo balance de crédito sea superior a la cantidad especificada, definirá los argumentos de búsqueda de la llamada DL/I del siguiente modo:
  1. Desea buscar en el campo creditBalance (STFCSBL) del segmento de crédito (STSCSTA). Para ello, defina una variable de tipo MONEY (por ejemplo, "targetBalance") que contenga la cantidad especificada que desea buscar.
  2. Escriba una sentencia get para el registro myCrStatus.
  3. Añada una directiva #dli a la línea, modificando el código por omisión. Añada un SSA calificado que busque un segmento en el que la cantidad del campo creditBalance sea superior a la de targetBalance.
  4. Incluya un código de mandato de vía de acceso (*D) para recuperar el segmento de cliente (STSCCST) que corresponda al segmento de crédito.
El código de ejemplo siguiente muestra este proceso:
	targetBalance MONEY;
	targetBalance = 10,000.00;

	get myCrStatus with #dli{
		GU STSCCST*D STSCSTA (STFCSBL >= :targetBalance) };
Puede que también desee buscar en función de la información de otro registro. Por ejemplo, podría buscar un cliente en función de un número de cliente (invCustNo) en un registro de facturas (myInvoice) de tipo (InvoiceRecordPart) que es un registro básico y no forma parte de la base de datos. El código sería parecido al siguiente:
get myCustomer with #dli{
	GU STSCCST (STQCCNO = :myInvoice.invCustNo) };

Conceptos relacionados:
Soporte de bases de datos DL/I
Soporte de entorno de ejecución IMS

Consulta relacionada:
DLIVar
Ejemplo de base de datos DL/I

Comentarios
(C) Copyright IBM Corporation 2000, 2005. Reservados todos los derechos.