Iniciar Sesión

Ver la Versión Completa : [Sintaxis] SQL embebido - cursor con COUNT() en PowerCOBOL 7


drvedia1981
11 de junio de 2018, 20:21
Hola tengo esta sentencia sql probada en phpadmin ahora lo quiero pasar a un programa en power con sql embebido pero no me funciona alguna ayuda, gracias

Codigo en php admin
SELECT caja, COUNT( 1 )
FROM `ventanilla`
where DATE( fecha ) = '2018-05-03'
GROUP BY caja

en power
EXEC SQL CONNECT TO 'BASE' END-EXEC.

EXEC SQL DECLARE Registro CURSOR FOR SELECT caja, COUNT( 1 ) FROM 'ventanilla' where DATE( fecha ) = '2018-05-03' GROUP BY caja END-EXEC

EXEC SQL OPEN Registro END-EXEC.
PERFORM cargo UNTIL SQLSTATE = "02000".
EXEC SQL CLOSE Registro END-EXEC
EXEC SQL DISCONNECT 'BASE'
END-EXEC. EXIT PROGRAM.

cargo.
.....

Kuk
11 de junio de 2018, 20:27
drvedia1981, danos más datos. ¿Qué error te da exactamente?

drvedia1981
11 de junio de 2018, 20:49
Hola KUK, el cursor no me devuelve nada o algo pongo mal, el resultado de la sentencia da 0 el sqlstate creo que eso esta bien, estoy trabajando con esta base pero no recuperando datos de esta forma que puede ser gracias es algo urgente!!!.
Esto me devuelve el phpadmin
01 47
02 18
03 34
04 55
06 59
07 31
08 18

Josber
11 de junio de 2018, 22:04
drvedia1981, No puedes usar sql embebido con un declare cursor y un select count, o por lo menos yo no lo he conseguido, ejecútalo sin el count y verás como funciona perfectamente.

Un saludo.-

drvedia1981
11 de junio de 2018, 22:08
Hola si todo parece ser el COUNT( 1 ) como puedo hacerlo de otra forma que no sea sql embebido necesito esos resultados para mostrar gracias

Kuk
12 de junio de 2018, 09:16
Me parece muy raro que no se pueda hacer cursores con COUNT(). Habéis probado con COUNT(*) ?

drvedia1981, puedes hacer algo así:


EXEC SQL
CONNECT TO 'BASE'
END-EXEC.

EXEC SQL
DECLARE Registro CURSOR FOR
SELECT DISTINCT caja
FROM 'ventanilla'
where DATE( fecha ) = '2018-05-03'
END-EXEC.

EXEC SQL
OPEN Registro
END-EXEC.

PERFORM cargo

PERFORM UNTIL SQLSTATE = "02000"
SELECT COUNT(*)
INTO :WS-COUNT
FROM caja
WHERE ID_caja = :WS-ID-CAJA

PERFORM cargo
END-PERFORM

EXEC SQL
CLOSE Registro
END-EXEC

EXEC SQL
DISCONNECT 'BASE'
END-EXEC.

Josber
12 de junio de 2018, 11:41
drvedia1981,

A ver una cosa, no me había dado cuenta pero ... es ilógico usar un COUNT con un DECLARE CURSOR, los cursores, se utilizan para un FETCH, (un READ NEXT en COBOL), y un SELECT COUNT, no se puede utilizar con un FETCH, por lo menos hasta donde yo sé, donde yo lo he probado y no funciona, es en un PREPARE.

¿Qué es lo que quieres hacer exactamente?, a ver si es que lo estás haciendo mal y podemos ayudarte.


Kuk,

No he probado a hacer un SELECT COUNT(*), porque no es lógico, sobre todo por hacer el COUNT más rápido y no sobrecargar la BD haciéndole contar todas las columnas, imagínate una tabla con 50.000 registros y 40 columnas, por ejemplo, pero lo pruebo y digo algo.


Un saludo.-

Kuk
12 de junio de 2018, 12:10
Josber, lo decía por si había un bug en el parser de sintaxis.

Y en cuanto a lo de usar COUNT() en un cursor, no es frecuente pero puede haber necesidad. Y DB2, que es lo que más he usado, lo permite: IBM MAINFRAME: Db2 query to fetch duplicate rows (http://ibmmainframes.com/about33858.html)

Josber
12 de junio de 2018, 13:37
drvedia1981,

He estado haciendo pruebas y SÍ se puede usar un COUNT() en un PREPARE, vamos a suponer que tienes una tabla que se llama ABREVIAS y tiene como campos:
ABRCOD varchar(3) UNIQUE
ABRNOM varchar(60)

la programación en PWC sería de ésta manera:


WORKING-STORAGE SECTION.
EXEC SQL
BEGIN DECLARE SECTION
END-EXEC.
01 WTEX PIC X(100).
01 CONTASQL PIC S9(5).
EXEC SQL
END DECLARE SECTION
END-EXEC.
.
.
.
.

PROCEDURE DIVISION.
INICIO.
*
MOVE "SELECT COUNT(ABRCOD) FROM ABREVIAS WHERE ABRCOD LIKE '%A%'" TO WTEX.

EXEC SQL
PREPARE CONSULTA FROM :WTEX
END-EXEC.

EXEC SQL
execute CONSULTA INTO :CONTASQL
END-EXEC.


Lo que ya no reconoce el SqlEmbebido es la instrucción DEALLOCATE PREPARE ..., pero bueno, el resto funciona perfectamente, tanto poniendo un * como el nombre de la variable en el COUNT.

Y en cuanto a lo de usar COUNT() en un cursor

No le veo la utilidad, si lo que quieres es contar los registros que cumplan unos parámetros, y SQL, te los cuenta sin tener que hacer un recorrido por la tabla con un FETCH, el que se pueda usar, vale, pero el que sea útil ...

Un saludo.-

Kuk
12 de junio de 2018, 13:55
Josber, según entiendo, lo que tiene es una tabla con campos:


CAJA - que viene a ser el ID
FECHA


Donde CAJA no es único y puede haber varios registros.

Para los resultados de phpMyAdmin:


01 47
02 18
03 34
04 55
06 59
07 31
08 18


Lo que deduzco es que tal ID ha hecho una acción (por ejemplo venta) tantas veces al día.

¿Cómo lo harías tú?

Lo mismo no es la mejor manera como lo está haciendo, pero yo en este caso le veo sentido al COUNT(). Porque el cursor no es otra cosa que crear una tabla temporal basada en tu SELECT que vas recorreidno.

Josber
12 de junio de 2018, 15:16
Kuk,

Ostras, después de lo que has dicho tú, ya no tengo tan claro que es lo que quiere, a ver si pone un post explicándolo un poco más detalladamente, de todas maneras, si es lo que me imagino, yo creo que incluyendo un DISTINCT en el SELECT y construyendo correctamente el WHERE, se podría hacer lo que quiere.

Un saludo.-

David
6 de junio de 2023, 21:36
Hola a todos
Interesante tema, pero si la intención es solo conocer la cantidad de registros de una tabla, a mi me funciona de esta manera:

EXEC SQL
SELECT COUNT(*)
FROM ABREVIAS
WHERE ABRCOD LIKE '%A%'" WTEX
INTO :WTEX
END-EXEC.
Display WTEX.

- - - Updated - - -

Corrijo


EXEC SQL
SELECT COUNT(*)
FROM ABREVIAS
WHERE ABRCOD LIKE '%A%'"
INTO :WTEX
END-EXEC.
Display WTEX.

Josber
7 de junio de 2023, 11:01
@David, No sabemos si a @drvedia1981, se le solucionó el problema, es lo que más me fastidia de todo esto, ya no en éste post, si no en muchos más, una persona pide ayuda, se le ofrecen varias posibilidades, contesta que ninguna, se le pide que explique o dé "más pistas" sobre qué necesita y .... ¡¡Ta-Chánnnn!!, desaparece, no sabemos si porque ha encontrado la solución, porque ha abandonado la idea, o cualquier otro motivo. Estaría bien que, todo el mundo, sea cual sea la causa, diesen por cerrado el post, con una mención a la causa, bien diciendo cuál ha sido la solución final, que ha abandonado la idea o lo que sea, ya que mucha gente, se ha molestado y ha invertido su tiempo en contestar, (tiempo que es tan valioso como el de la persona que hace la pregunta), además, de esa manera, muchos otros, no se quedarían con la duda de si será esa alguna de las soluciones o que "leshes" a pasado

Y ahora, después de éste desahogo, a ver, no, no creo que esa fuera la solución, máxime, cuando es igual a la que yo le puse en su momento

Un salu2.-

David
7 de junio de 2023, 11:28
Hola Josber

Coincido totalmente con lo expresado en tu post, es desilusionante el posterior mutismo de quien que solicita ayuda en el foro.
Desde mi poca experiencia, quise, a pesar de la antigüedad del post inicial, aportar una posible solución a lo planteado.


Saludos