SELECT COUNT:
Esta sentencia nos recuperará la cantidad de registros que cumplen una condición, es decir, lo que devuelve es un número.
EXEC SQL
SELECT COUNT(*)
INTO :NUMERO-REGISTROS :IND-NULL
FROM TABLA1
WHERE CAMPO1 = 'XX'
END-EXEC
SELECT COUNT(*)
INTO :NUMERO-REGISTROS :IND-NULL
FROM TABLA1
WHERE CAMPO1 = 'XX'
END-EXEC
La variable IND-NULL la definiremos como S9(4) COMP y la utilizaremos para controlar el retorno, en caso de que no encuentre ningún registro que cumpla la condición.
Controlando el SQLCODE:
EVALUATE TRUE
WHEN SQLCODE EQUAL ZEROES
IF IND-NULL EQUAL -1
MOVE ZEROES TO NUMERO-REGISTROS
END-IF
WHEN OTHER
DISPLAY 'ERROR HACIENDO EL SELECT COUNT. SQLCODE: 'SQLCODE
END-EVALUATE
WHEN SQLCODE EQUAL ZEROES
IF IND-NULL EQUAL -1
MOVE ZEROES TO NUMERO-REGISTROS
END-IF
WHEN OTHER
DISPLAY 'ERROR HACIENDO EL SELECT COUNT. SQLCODE: 'SQLCODE
END-EVALUATE
El indicador de nulos para el caso de no encontrar ningún registro valdrá -1. Si no controlásemos el indicador de nulos, la SELECT nos devolvería un SQLCODE -305.
SELECT MAX:
Esta sentencia nos recuperará el valor máximo de un campo para una determinada condición.
EXEC SQL
SELECT MAX(CAMPO2)
INTO :TABLA1-CAMPO2 :IND-NULL
FROM TABLA1
WHERE CAMPO1 = 01
END-EXEC
SELECT MAX(CAMPO2)
INTO :TABLA1-CAMPO2 :IND-NULL
FROM TABLA1
WHERE CAMPO1 = 01
END-EXEC
El control del retorno se hará del mismo modo que para el SELECT COUNT:
EVALUATE TRUE
WHEN SQLCODE EQUAL ZEROES
IF IND-NULL EQUAL -1
MOVE ZEROES TO TABLA1-CAMPO2
END-IF
WHEN OTHER
DISPLAY 'ERROR HACIENDO EL SELECT COUNT. SQLCODE: 'SQLCODE
END-EVALUATE
WHEN SQLCODE EQUAL ZEROES
IF IND-NULL EQUAL -1
MOVE ZEROES TO TABLA1-CAMPO2
END-IF
WHEN OTHER
DISPLAY 'ERROR HACIENDO EL SELECT COUNT. SQLCODE: 'SQLCODE
END-EVALUATE
FOR UPDATE:
Esta sentencia se utiliza para actualizar el registro en el que nos hemos posicionado con un FETCH.
EXEC SQL
DECLARE CUR-TABLA1 CURSOR FOR
SELECT
CAMPO1,
CAMPO2,
CAMPO3,
CAMPO4
FROM TABLA1
WHERE CAMPO1 = :TABLA1-CAMPO1
FOR UPDATE OF
CAMPO2,
CAMPO3,
CAMPO4
END-EXEC
DECLARE CUR-TABLA1 CURSOR FOR
SELECT
CAMPO1,
CAMPO2,
CAMPO3,
CAMPO4
FROM TABLA1
WHERE CAMPO1 = :TABLA1-CAMPO1
FOR UPDATE OF
CAMPO2,
CAMPO3,
CAMPO4
END-EXEC
En el programa haríamos un update por cada FETCH del siguiente modo:
EXEC SQL
UPDATE TABLA1
SET CAMPO2 = :UPD-CAMPO2,
CAMPO3 = :UPD-CAMPO3,
CAMPO4 = :UPD-CAMPO4
WHERE CURRENT OF CUR-TABLA1
END-EXEC
UPDATE TABLA1
SET CAMPO2 = :UPD-CAMPO2,
CAMPO3 = :UPD-CAMPO3,
CAMPO4 = :UPD-CAMPO4
WHERE CURRENT OF CUR-TABLA1
END-EXEC
De este modo no tendríamos que indicarle la clave del registro a actualizar, pues actualizaría el registro abierto por el FETCH.
8 comentarios:
Una forma muy interesante, poco utilizada y menos costosa de hacer un SELECT MAX(campo) es:
SELECT campo
WHERE ...
ORDER BY campo DESC
FETCH FIRST 1 ROW ONLY
Con esto conseguimos que el DB/2 nos devuelva una única fila que además al estar ordenada de forma descendente por el campo buscado nos dará el valor deseado
Muchas gracias por la aportación José Antonio. Esperamos que más gente se anime a compartir su conocimiento.
Incluiría también el SELECT MIN.
Si en la select indicada en la entrada sustituimos MAX por MIN lo que recuperamos es el valor mínimo de un campo para una determinada condición.
Otra manera de hacer lo mismo sería utilizando la select indicada por José Antonio Romero modificando el ORDER BY (siendo ASC en lugar de DESC).
pero para hacerla tuve que declarar un cursor porque en COBOL no me permite el ORDER BY en un SELECT
Una consulta, que valor toma la variable "NUMERO-REGISTROS" cuando el select devuelve un NOT FOUND, en los siguientes casos:
1.- Sin variable IND-NULL
EXEC SQL
SELECT COUNT(*)
INTO :NUMERO-REGISTROS
FROM TABLA1
WHERE CAMPO1 = 'XX'
END-EXEC
2.- Con variable IND-NULL
EXEC SQL
SELECT COUNT(*)
INTO :NUMERO-REGISTROS :IND-NULL
FROM TABLA1
WHERE CAMPO1 = 'XX'
END-EXEC
gracias
Buenas!
En el caso de no encontrar registros que cumplan la condición, sin el indicador IND-NULL no obtendrás un not found (+100) sino un -305 como se indica.
En ambos casos la variable NUMERO-REGISTROS toma valor NULL.
Hola requiero un cursos que pueda recuperar "n" registros, se puede usar el FETCH FIRST ROWS ONLY en el cursor ?
Hola. Para recuperar n registros en cada fetch puedes usar el cursor ROWSET. Si lo que quieres es limitar el número de registros devueltos por el cursor puedes indicarlo con el FETCH FIRST n ROWS ONLY.