Club Delphi  
    Paypal   FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Bases de datos > Firebird e Interbase
Registrarse FAQ Miembros Calendario Guía de estilo Buscar Temas de Hoy Marcar Foros Como Leídos

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 17-07-2007
Avatar de Al González
[Al González] Al González is offline
In .pas since 1991
 
Registrado: may 2003
Posts: 5.610
Poder: 32
Al González Es un diamante en brutoAl González Es un diamante en brutoAl González Es un diamante en brutoAl González Es un diamante en bruto
Smile Final feliz alternativo

¡Hola de nuevo!

Ya me había ido a dormir, pero de pronto, entre el barullo de mis últimos pensamientos del día, reflexioné:

----------------------------------------------------
¿Por qué será que no se permite parametrizar un First?

Ah, pero podría "armar" el First n en el Select que llama al procedimiento (Select First n * From Procedimiento...). Después de todo, un procedimiento almacenado que devuelve un cursor hace un Suspend por cada fila, y si desde afuera le digo "First 10", pues sólo deberá traerme 10 y suspender definitivamente la obtención de las filas restantes.

Quizá por eso los creadores de InterBase / Firebird no permiten usar una variable o parámetro para indicar la cantidad en el interior de un procedimiento. Pareciera una forma sutil de decirnos, "¿pa' qué quieres el First parametrizado aquí? Tú pide desde afuera la cantidad que requieras." Aunque esto no suena muy convincente, quizá haya otra razón.

Ah, ¿pero qué pasaría si a ese Select exterior le añado una cláusula Order By? Temo que se va a traer todo el cursorote y ya luego tomará los First n del orden indicado, discriminando una gran cantidad de filas que ya se trajo. Eso lo volvería muy lento...

----------------------------------------------------

Entonces recordé que tenía una barra de chocolate con almendras en el congelador y aquello fue la gota que derramó la tentación.

Me levanté a la media noche para compartir estas reflexiones con ustedes y de paso hacer algunas pruebas adicionales con IB Expert y Delphi. Los resultados de esas pruebas fueron que:

1. Efectivamente, se puede utilizar First en el Select exterior para evitar el empleo de Execute Statement dentro del procedimiento.
2. Ese First puede tener un parámetro.
3. Por alguna razón no se permiten cláusulas First sin un valor literal dentro de procedimientos almacenados y disparadores.
4. Como era de esperarse, una cláusula Order By en el Select que llama al procedimiento hace que se obtengan todas las filas posibles de éste antes de aplicar el First de dicha sentencia Select, lo cual no es óptimo.

Conclusión para mi caso: Usaré First parametrizados en los Selects que llaman a los procedimientos. Dentro de éstos aplicaré un Order By acorde a ese First de afuera. En esos Selects exteriores evitaré el uso de Order By; con la ventaja de que, al estar utilizando CDSs (client data sets) conectados a los queries, puedo reordenar las filas en memoria según convenga para cada caso.

Esta solución podría ser útil en otros casos; todo depende de la cantidad de registros, los componentes utilizados y de qué tanto queramos variar el orden del cursor.

Cita:
Empezado por jhonny
Si necesitas usar la primera sintaxis que describe Alex Peshkoff en http://fresh.t-systems-sfr.com/unix/...cute_statement estarías limitado a 32765 caracteres que es el tamaño máximo de un tipo VARCHAR o 32767 si decides usar un CHAR...
Gracias por el enlace Jhonny. Al final de ese documento se explican otras desventajas de Execute Statement (como el mayor consumo de tiempo). Veo muy útil la instrucción, pero creo que sólo la emplearé en casos muy especiales.

Un abrazo chocolatoso.

Al González.
Responder Con Cita
  #2  
Antiguo 17-07-2007
Avatar de RolphyReyes
RolphyReyes RolphyReyes is offline
Miembro
 
Registrado: ago 2004
Ubicación: Santo Domingo
Posts: 285
Poder: 22
RolphyReyes Va por buen camino
Cool Ejemplos de las pruebas

Saludos.

Al González podrias si te es posible subir los select's de pruebas que utilizaste? .

Gracias de antemano.
__________________
Gracias,
Rolphy Reyes
Responder Con Cita
  #3  
Antiguo 17-07-2007
[egostar] egostar is offline
Registrado
 
Registrado: feb 2006
Posts: 6.572
Poder: 27
egostar Va camino a la fama
Bueno, el hecho de usar el FIRST, solo lo considero para obtener estadísticas, no para recuperar filas de las tablas, mi caso es por ejemplo, quiero saber los N números más marcados mas no las primeras N filas, eso no me hace sentido y lo haría con validaciones WHERE, HAVING.

Salud OS.
__________________
"La forma de empezar es dejar de hablar y empezar a hacerlo." - Walt Disney
Responder Con Cita
  #4  
Antiguo 17-07-2007
Avatar de ariefez
ariefez ariefez is offline
Miembro
 
Registrado: sep 2005
Ubicación: Perú - Lima
Posts: 63
Poder: 21
ariefez Va por buen camino
Tu sentencia esta bien solo le falta unos parentesis

Código SQL [-]
    SELECT FIRST (:PAGE_NF) SKIP (:PAGE_NF * (:PAGE_NRO - 1))
donde:
PAGE_NF Numero de registros por pagina
PAGE_NRO el numero de pagina

este es el codigo q uso, para darte un ejemplo

Código SQL [-]
/* CLIENTE - DISPONIBLES */

SET TERM ^ ;

CREATE OR ALTER PROCEDURE CLI_SELECT (
  CLIENTE TYPE OF D_CLI_NOM,
  DNI TYPE OF D_RUC,
  PAGE_NF INTEGER,
  PAGE_NRO INTEGER,
  IN_BLOCKED SMALLINT)
RETURNS (
  CLI_ID INTEGER,
  CLI_NOM VARCHAR(60),
  RUC VARCHAR(15),
  BLOCKED SMALLINT)
AS
BEGIN
  FOR
    SELECT FIRST (:PAGE_NF) SKIP (:PAGE_NF * (:PAGE_NRO - 1))
      CLI_ID, CLI_NOM, RUC, BLOCKED
    FROM
      CLIENTES
    WHERE
      0 < CLI_ID
      AND (:IN_BLOCKED = 1 OR BLOCKED = 0)
      AND (:CLIENTE IS NULL OR CLI_NOM LIKE '%' || :CLIENTE || '%')
      AND (NI IS NULL OR RUC LIKE '%' || NI || '%')
    ORDER BY CLI_NOM, RUC, CLI_ID
    INTO :CLI_ID, :CLI_NOM, :RUC, :BLOCKED
  DO SUSPEND;
END^

SET TERM ; ^

Agrego: probado en firebird 2.0 y 2.1 beta
Responder Con Cita
  #5  
Antiguo 17-07-2007
Avatar de jhonny
jhonny jhonny is offline
Jhonny Suárez
 
Registrado: may 2003
Ubicación: Colombia
Posts: 7.070
Poder: 32
jhonny Va camino a la famajhonny Va camino a la fama
Vaya, Vaya, Vaya¡¡¡
__________________
Lecciones de mi Madre. Tema: modificación del comportamiento, "Pará de actuar como tu padre!"

http://www.purodelphi.com/
http://www.nosolodelphi.com/
Responder Con Cita
  #6  
Antiguo 17-07-2007
[egostar] egostar is offline
Registrado
 
Registrado: feb 2006
Posts: 6.572
Poder: 27
egostar Va camino a la fama
, Funcionó perfectamente.

Muchas gracias ariefez, pues nada, cada día se aprende algo nuevo.

Así quedo finalmente mi SP

Código SQL [-]
SET TERM ^ ;

CREATE PROCEDURE NEW_PROCEDURE (
    e_limite integer,
    e_inicial date,
    e_final date)
returns (
    s_prefijo varchar(3),
    s_numero varchar(20),
    s_llamadas integer,
    s_duracion numeric(15,0))
as
begin
  /* Procedure Text */
  FOR
    select first (:e_limite) Prefijo, Numero, COUNT(*) as NumLla,
       SUM(DurEntera) as TotDur from llamadas
    where fecha between :e_inicial and :e_final
    group by prefijo, numero order by NumLla desc
  INTO :S_Prefijo, :s_numero, :s_duracion, s_llamadas DO
  suspend;
end^

SET TERM ; ^

GRANT SELECT ON LLAMADAS TO PROCEDURE NEW_PROCEDURE;

GRANT EXECUTE ON PROCEDURE NEW_PROCEDURE TO SYSDBA;

Solo hago notar que la funcion SUM() requiere de un tipo de dato Numeric, intentaba asignarlo como Integer y me daba un error de casting.

Salud OS.
__________________
"La forma de empezar es dejar de hablar y empezar a hacerlo." - Walt Disney
Responder Con Cita
  #7  
Antiguo 17-07-2007
Avatar de Al González
[Al González] Al González is offline
In .pas since 1991
 
Registrado: may 2003
Posts: 5.610
Poder: 32
Al González Es un diamante en brutoAl González Es un diamante en brutoAl González Es un diamante en brutoAl González Es un diamante en bruto
Smile Final feliz pa' todos

¡Hola a todos!

Cita:
Empezado por RolphyReyes
...podrias si te es posible subir los select's de pruebas que utilizaste?...
No sé si sirvan de mucho, y menos después de la tremenda solución dada por Ariefez, pero son los siguientes.

Select que detiene definitivamente el For Select del procedimiento spParte tras obtener las primeras 10 filas construidas por el procedimiento:
Código SQL [-]
-- Versión rápida
Select First 10 * From spParte (Null, Null, Null, Null, Null, Null)

Select que, por tener Order By, espera a que se realice todo el For Select del procedimiento spParte, para luego devolver solo 10 de las filas que construyó el procedimiento:
Código SQL [-]
-- Versión lenta
Select First 10 * From spParte (Null, Null, Null, Null, Null, Null) Order By Numero


Cita:
Empezado por egostar
...usar el FIRST, solo lo considero para obtener estadísticas, no para recuperar filas de las tablas, mi caso es por ejemplo, quiero saber los N números más marcados mas no las primeras N filas, eso no me hace sentido...
¡Hey, hey, hey! Este no es mi vaso de Batman. Eliseo: En tu procedimiento usas First para obtener las primeras n filas. Sí, las primeras n filas que construye en el aire el propio For Select del procedimiento con ayuda de Suspend. No dije que fueran las filas (registros) de una tabla.


Cita:
Empezado por ariefez
...Tu sentencia esta bien solo le falta unos parentesis

Código SQL [-]
    SELECT FIRST (:PAGE_NF)...
Agrego: probado en firebird 2.0 y 2.1 beta
Cita:
Empezado por jhonny
Vaya, Vaya, Vaya¡¡¡
Otros tres vayaes . Me sorprendió de la misma forma y lo mejor de todo es que ¡también funciona en Firebird 1.5!

Gracias por el tip Ariefez, creo que has dado con la mejor solución para los casos planteados. Y además he aprendido aquello del Order By en llamadas a procedimientos.


Un primer abrazo.

Al González.
Responder Con Cita
  #8  
Antiguo 17-07-2007
Avatar de ariefez
ariefez ariefez is offline
Miembro
 
Registrado: sep 2005
Ubicación: Perú - Lima
Posts: 63
Poder: 21
ariefez Va por buen camino
Para eso estamos para compartir lo que sabemos y de pasadita tambien para aprender ...
Responder Con Cita
Respuesta


Herramientas Buscar en Tema
Buscar en Tema:

Búsqueda Avanzada
Desplegado

Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro

Temas Similares
Tema Autor Foro Respuestas Último mensaje
problema con la consulta select count() enecumene PHP 5 01-02-2007 23:33:24
Problema con consulta not in (select ....) VRO Firebird e Interbase 12 03-10-2005 18:54:05
Problema conuna consulta select...not in (select ...) VRO Firebird e Interbase 2 11-08-2005 08:56:35
error Select firebird 1.5 ale21alito Firebird e Interbase 2 25-04-2005 20:20:03
Duplicidad de lineas en un grid con select contra firebird saruman91 Firebird e Interbase 6 29-10-2004 02:41:33


La franja horaria es GMT +2. Ahora son las 12:29:40.


Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2026, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi
Copyright 1996-2007 Club Delphi