none
SubConsulta SQL Server y condicionales RRS feed

  • Pregunta

  • Buenas compañeros.

    Estoy teniendo problemas en la creación de un procedimiento, algo asi es lo que quiero.

     create Procedure [dbo].[SP_ListadoProductos]
    @Inicio as int,
    @Cantidad as int,
    @Codigo as varchar(50),
    @Total as int output
    as
    begin try
    
    	if (@Codigo = '')
    	begin
    		Set @Codigo = null
    	end
    
    if exists(select * from Vproductos where codigo = ISNULL(@codigo, codigo))
    
     Select * from Vproductos where  codigo = ISNULL(@codigo, codigo) order by codigo offset @inicio rows fetch next @Cantidad rows only
    
    set @Total = (Select * from Vproductos where  codigo = ISNULL(@codigo, codigo) order by codigo offset @inicio rows fetch next @Cantidad rows only)
    
    else
    if exists(select * from vproductos where producto like +'%' + ISNULL(@codigo, Producto) + '%')
    
    select * from vproductos where Producto like + '%'+ ISNULL(@Codigo, Producto) + '%' order by codigo offset @inicio rows fetch next @Cantidad rows only
    
    set @total = (select * from vproductos where Producto like + '%'+ ISNULL(@Codigo, Producto) + '%' order by codigo offset @inicio rows fetch next @Cantidad rows only)
    			
    end try
    begin catch
    
    end catch

    pero me da el siguiente error.

    "Solo se puede especificar una expresión en la lista de selección cuando la subconsulta no se especifica con EXISTS."

    entonces compañeros, quisiera saber si existe una mejor forma de hacer lo que estoy tratando de hacer. o si pudieran especificarme como solucionar ese problema que me sale.

    Gracias de Antemano.


    Alexander Jimenez

    sábado, 29 de septiembre de 2018 0:49

Respuestas

  • Buenos dias Javi, me ha sevido de gran ayuda las sugerencias que me has dado y ya las aplique. ahora bien el problema esta en que necesito obtener el total de los registros ya filtrados, es decir, no quiero el total de registros de la tabla, sino, el total de registros que devuelve con la condicionales:

    que seria exactamenete esto lo que necesito:

    Set @Total = ( SELECT v.* FROM Vproductos v WHERE(codigo = @codigo OR @Codigo IS NULL) OR ((producto LIKE '%'+(@Codigo)+'%') OR (@Codigo IS NULL)))

    --Lo unico que eso me da un error "Solo se puede especificar una expresión en la lista de selección cuando la subconsulta no se especifica con EXISTS." -- y que me muestre al final la cantidad de registros ya filtrados, ejemplo: @total = 50

    Te explico mejor: la forma que me indicas obtengo el total de registros de la tabla, ejemplo 100 registros, a la hora de hacer la paginación si muestro 20 registros por pagina tendría un total de 5. perfecto. pero cuando hago la busqueda o el filtro ('panes') solo hay 22 'panes' por ejemplo. entonces necesito ese valor "22" para en el lenguaje cliente aplicar la paginación.

    No quiero enviar todos los registros al lenguaje ya que cuando son miles de registros se nota la carga de todos estos, quiero enviarlos de poco en poco

    Ojala quede mas claro lo que en verdad necesito hacer.

    De nuevo gracias de Antemano


    Alexander Jimenez



    sábado, 29 de septiembre de 2018 11:46

Todas las respuestas

  • Hola AJ Designs:

    Te pongo el ejemplo como puede ser.

    CREATE TABLE VProductos
    (codigo   VARCHAR(50),
     producto INT
    );
    GO
    INSERT INTO VProductos
    (codigo,
     producto
    )
    VALUES
    ('a',
     1
    ),
    ('a',
     5
    ),
    ('a',
     2
    ),
    ('a',
     3
    ),
    ('b',
     1
    ),
    ('b',
     2
    ),
    ('c',
     1
    ),
    ('c',
     2
    ),
    ('d',
     1
    ),
    ('d',
     2
    );
    GO
    CREATE PROCEDURE [dbo].[SP_ListadoProductos]
    (@Inicio   INT,
     @Cantidad INT,
     @Codigo   VARCHAR(50),
     @Total    INT OUTPUT
    )
    AS
        BEGIN TRY
            SET @Total =
    (
        SELECT COUNT(*)
        FROM Vproductos v
    );
            SELECT v.*
            FROM Vproductos v
            WHERE(codigo = @codigo
                  OR @Codigo IS NULL)
                 OR ((producto LIKE '%'+(@Codigo)+'%')
                     OR (@Codigo IS NULL))
     --group by codigo, producto
            ORDER BY codigo
            OFFSET @inicio ROWS FETCH NEXT @Cantidad ROWS ONLY;
        END TRY
        BEGIN CATCH
            THROW;
        END CATCH;
            RETURN;
    GO
    DECLARE @t INT;
    EXEC [dbo].[SP_ListadoProductos]
         @Inicio = 1,
         @Cantidad = 3,
         @Codigo = 'a',
         @Total = @T OUTPUT;
    PRINT @t;
    GO
    DECLARE @t INT;
    EXEC [dbo].[SP_ListadoProductos]
         @Inicio = 1,
         @Cantidad = 10,
         @Codigo = NULL,
         @Total = @T OUTPUT;
    PRINT @t;
     
    
    

    La primera parte de la sentencia, es para tener valores para ejecutar. Tu ya tienes tu tabla, por tanto no te hace falta.

    En el procedure, si te fijas te he cambiado varias cosas. La primera la forma del encabezado. Seguro que es válido tu forma de definir los parámetros pero yo no la he visto nunca, y no aporta claridad, porque as en SQL siempre esta asociado a alias de algo, y su lectura se hace raro. En lenguajes cliente es más fácil encontrarse eso.

    En la select final es más fácil y de mejor rendimiento y lectura, preguntarle si tu parámetro es igual a tu columna o tu parámetro es nulo. Si prefieres hacerlo con '' también vale, pero es el filtro el que decide si cumple una u otra condición, de lo cual te ahorras código, y lo que es más importante, el número de select que haces.

    Imagínate que tu tabla de productos, tiene 35 millones de referencias.

    Luego entiendo que en total querías saber cuantos registros tiene la tabla, porque si lo que quieres saber en total es cuantos te devuelve la petición paginada, desde donde la llames lo tienes por el número de registros que te ha devuelto. Todas las colecciones, de los lenguajes cliente, tienen un método count.

    Espero te sirva

    sábado, 29 de septiembre de 2018 5:30
  • Buenos dias Javi, me ha sevido de gran ayuda las sugerencias que me has dado y ya las aplique. ahora bien el problema esta en que necesito obtener el total de los registros ya filtrados, es decir, no quiero el total de registros de la tabla, sino, el total de registros que devuelve con la condicionales:

    que seria exactamenete esto lo que necesito:

    Set @Total = ( SELECT v.* FROM Vproductos v WHERE(codigo = @codigo OR @Codigo IS NULL) OR ((producto LIKE '%'+(@Codigo)+'%') OR (@Codigo IS NULL)))

    --Lo unico que eso me da un error "Solo se puede especificar una expresión en la lista de selección cuando la subconsulta no se especifica con EXISTS." -- y que me muestre al final la cantidad de registros ya filtrados, ejemplo: @total = 50

    Te explico mejor: la forma que me indicas obtengo el total de registros de la tabla, ejemplo 100 registros, a la hora de hacer la paginación si muestro 20 registros por pagina tendría un total de 5. perfecto. pero cuando hago la busqueda o el filtro ('panes') solo hay 22 'panes' por ejemplo. entonces necesito ese valor "22" para en el lenguaje cliente aplicar la paginación.

    No quiero enviar todos los registros al lenguaje ya que cuando son miles de registros se nota la carga de todos estos, quiero enviarlos de poco en poco

    Ojala quede mas claro lo que en verdad necesito hacer.

    De nuevo gracias de Antemano


    Alexander Jimenez



    sábado, 29 de septiembre de 2018 11:46
  • Entonces es identico pero no select * sino select count(*)....

    sábado, 29 de septiembre de 2018 14:54