none
ordenação com va´rios campos RRS feed

  • Pergunta

  • USE [DB_SISTEMA]
    GO
    /****** Object:  StoredProcedure [dbo].[SP_SELECT_REL_CONSULTAS_HISTORICO]    Script Date: 09/27/2012 10:27:33 ******/
    SET ANSI_NULLS ON
    GO
    SET QUOTED_IDENTIFIER ON
    GO
    ALTER PROCEDURE [dbo].[SP_SELECT_REL_CONSULTAS_HISTORICO]
    (
    @INICIO DATE,
    @FINAL DATE,
    @CLIENTEID INT,
    @MEDICOID INT,
    @ID INT,
    @ORDENACAO VARCHAR(20)
    )
    AS
    (
    SELECT     dbo.Consultas.ID,dbo.Consultas.Data, dbo.Consultas.HoraInicio, dbo.Consultas.HoraFinal, dbo.Consultas.Causa, Consultas.ClienteID, Consultas.MedicoID, Consultas.Descricao,dbo.Consultas.Revisao,
    Clientes.Nome AS CLIENTE,Medicos.Nome AS MEDICO
    FROM         dbo.Clientes INNER JOIN
                          dbo.Consultas ON dbo.Clientes.ID = dbo.Consultas.ClienteID INNER JOIN
                          dbo.Medicos ON dbo.Consultas.MedicoID = dbo.Medicos.ID
                          
    WHERE
    Consultas.Data BETWEEN @INICIO  AND @FINAL AND
    (@ID = 0 or Consultas.ID = @ID) AND
    (@MEDICOID = 0 or Medicos.ID = @MEDICOID) AND
    (@CLIENTEID = 0 or Clientes.ID = @CLIENTEID)
    )
    ORDER BY 
    CASE 
    	WHEN @ORDENACAO = 'DATA'
    	THEN CONSULTAS.Data
    	END,
    CASE 
    	WHEN @ORDENACAO = 'CODIGO'
    	THEN CONSULTAS.ID
    END,
    CASE 
    	WHEN @ORDENACAO = 'MEDICO'
    	THEN Medicos.Nome
    END

    ola pessoal, bom dia,

    estou enviando um parametro para fazer a ordenação.

    eu preciso do seguinte:

    Colocar mais um campo pra ordenar.

    ex:

    CASE
    WHEN @ORDENACAO = 'MEDICO'
    THEN Medicos.Nome, Consultas.Data
    END

    Da erro assim;

    como faço isso.

    Obrigado.

    quinta-feira, 27 de setembro de 2012 14:13

Respostas

  • Pedro, em relação às datas no SQL dinâmico, basta você concatenar aspas simples, conforme exemplo:

    Create Procedure stp_Teste (@Ordenacao VarChar(20), @DataInicial Date, @DataFinal Date) as
    Begin
      Declare @CamposOrdenacao VarChar(100)
    
      if (@Ordenacao = 'Nome')
        Set @CamposOrdenacao = 'NmProduto, CdClassificacao'
      else
        Set @CamposOrdenacao = 'CdClassificacao, NmProduto'
    
      Exec ('Select Top 50 * From Produto Where DtCadastro Between ' + '''' + @DataInicial + '''' + ' and ' + '''' + @DataFinal + '''' + ' Order by ' + @CamposOrdenacao)
    End
    Veja que imediatamente antes e imediatamente depois da utilização dos parâmetros de data eu concateno as aspas. Senão fizer isso o comando fica sem aspas. E é por isso que não estava funcionando.


    Roberson Ferreira - Database Developer
    Acesse: www.robersonferreira.com.br
    Email: contato@robersonferreira.com.br

    Se esta sugestão for útil, por favor, classifique-a como útil.
    Se ela lhe ajudar a resolver o problema, por favor, marque-a como Resposta.

    • Marcado como Resposta Pedrohgb7 sexta-feira, 28 de setembro de 2012 13:32
    sexta-feira, 28 de setembro de 2012 12:06
    Moderador

Todas as Respostas

  • Ou você vai ter que repetir Seu Select várias vezes (uma pra cada variação de ordenação), ou terá que usar SQL dinâmico (tomando cuidado com SQL Injection).

    Exemplo:

    Create Procedure stp_Teste (@Ordenacao VarChar(20)) as
    Begin
      Declare @CamposOrdenacao VarChar(100)
    
      if (@Ordenacao = 'Nome')
        Set @CamposOrdenacao = 'NmPessoa, NmCurto'
      else
        Set @CamposOrdenacao = 'TpPessoa, NmPessoa'
    
      Exec ('Select Top 50 * From Tabela Order by ' + @CamposOrdenacao)
    End

    Observação: Verifique se uma view não pode ser usada para esta finalidade.


    Roberson Ferreira - Database Developer
    Acesse: www.robersonferreira.com.br
    Email: contato@robersonferreira.com.br

    Se esta sugestão for útil, por favor, classifique-a como útil.
    Se ela lhe ajudar a resolver o problema, por favor, marque-a como Resposta.

    quinta-feira, 27 de setembro de 2012 14:23
    Moderador
  • ALTER PROCEDURE [dbo].[SP_SELECT_REL_CONSULTAS_HISTORICO]
    (
    @INICIO DATE,
    @FINAL DATE,
    @CLIENTEID INT,
    @MEDICOID INT,
    @ID INT,
    @ORDENACAO VARCHAR(20)
    )
    AS
    Declare @CamposOrdenacao VarChar(100)
    Begin
      
      if (@Ordenacao = 'MEDICO')
        Set @CamposOrdenacao = 'CONSULTAS.MEDICO, CONSULTAS.Data'
      else
        Set @CamposOrdenacao = 'CONSULTAS.Data'
        Exec ('SELECT dbo.Consultas.ID,dbo.Consultas.Data, dbo.Consultas.HoraInicio, dbo.Consultas.HoraFinal, dbo.Consultas.Causa, Consultas.ClienteID, Consultas.MedicoID, Consultas.Descricao,dbo.Consultas.Revisao, Clientes.Nome AS CLIENTE,Medicos.Nome AS MEDICO FROM dbo.Clientes INNER JOIN dbo.Consultas ON dbo.Clientes.ID = dbo.Consultas.ClienteID INNER JOIN dbo.Medicos ON dbo.Consultas.MedicoID = dbo.Medicos.ID WHERE Consultas.Data BETWEEN ' + @INICIO + ' AND ' + @FINAL + ' order by ' + @CamposOrdenacao)
    End
    -- set @strSQL = 'SELECT dbo.Consultas.ID,dbo.Consultas.Data, dbo.Consultas.HoraInicio, dbo.Consultas.HoraFinal, dbo.Consultas.Causa, Consultas.ClienteID, Consultas.MedicoID, Consultas.Descricao,dbo.Consultas.Revisao, Clientes.Nome AS CLIENTE,Medicos.Nome AS MEDICO FROM dbo.Clientes INNER JOIN dbo.Consultas ON dbo.Clientes.ID = dbo.Consultas.ClienteID INNER JOIN dbo.Medicos ON dbo.Consultas.MedicoID = dbo.Medicos.ID WHERE Consultas.Data BETWEEN ' + @INICIO + ' AND  @FINAL AND (@ID = 0 or Consultas.ID = @ID) AND (@MEDICOID = 0 or Medicos.ID = @MEDICOID) AND (@CLIENTEID = 0 or Clientes.ID = @CLIENTEID)) '

    Estou fazendo desse jeito, mas dá erro. acho que é na conversão de data.

    Estou no caminho certo?

    Obrigado pela ajuda.

    quinta-feira, 27 de setembro de 2012 17:13
  • Pedro,

    A ordenação não poderia ser através do número do campo de acordo com a ordem de declaração ao invês do nome do campo?

    Neste caso você poderia fazer uso do operador Between em seu Select.


    Pedro Antonio Galvão Junior [MVP | Microsoft Evangelist | Microsoft Partner | Engenheiro de Softwares | Especialista em Banco de Dados | SorBR.Net | Professor Universitário | MSIT.com]

    quinta-feira, 27 de setembro de 2012 17:48
  • como eu faria isto, o importante é ordenar, não importa a maneira. rsrsrr

    obrigado pela atenção

    quinta-feira, 27 de setembro de 2012 18:05
  • Pedro,

    Veja este exemplo:

    Create Table T1
     (codigo1 int,
      codigo2 int,
      codigo3 int,
      descricao varchar(10))
      
      Insert Into T1 values(1,1,1,'Testes')
      Insert Into T1 values(2,1,1,'Testes10')
      Insert Into T1 values(3,2,3,'xidjdp')
      Insert Into T1 values(4,23,45,'AAAA')
      Insert Into T1 values(5,10,1,'bbbb')
      
      Declare @ValorOrdenacao Char(10), @Comando Varchar(100)
      
      Set @ValorOrdenacao=	'3,1,2'
      
      Set @Comando=' Select * from T1 Order By '+ @ValorOrdenacao
    
    Exec(@Comando)


    Pedro Antonio Galvão Junior [MVP | Microsoft Evangelist | Microsoft Partner | Engenheiro de Softwares | Especialista em Banco de Dados | SorBR.Net | Professor Universitário | MSIT.com]

    quinta-feira, 27 de setembro de 2012 18:23
  • Exec ('SELECT dbo.Consultas.ID,dbo.Consultas.Data, dbo.Consultas.HoraInicio, dbo.Consultas.HoraFinal, dbo.Consultas.Causa, Consultas.ClienteID, Consultas.MedicoID, Consultas.Descricao,dbo.Consultas.Revisao, Clientes.Nome AS CLIENTE,Medicos.Nome AS MEDICO FROM dbo.Clientes INNER JOIN dbo.Consultas ON dbo.Clientes.ID = dbo.Consultas.ClienteID INNER JOIN dbo.Medicos ON dbo.Consultas.MedicoID = dbo.Medicos.ID WHERE Consultas.Data BETWEEN ' + @INICIO + ' AND ' + @FINAL + ' order by ' + @CamposOrdenacao)
    End
    -- set @strSQL = 'SELECT dbo.Consultas.ID,dbo.Consultas.Data, dbo.Consultas.HoraInicio, dbo.Consultas.HoraFinal, dbo.Consultas.Causa, Consultas.ClienteID, Consultas.MedicoID, Consultas.Descricao,dbo.Consultas.Revisao, Clientes.Nome AS CLIENTE,Medicos.Nome AS MEDICO FROM dbo.Clientes INNER JOIN dbo.Consultas ON dbo.Clientes.ID = dbo.Consultas.ClienteID INNER JOIN dbo.Medicos ON dbo.Consultas.MedicoID = dbo.Medicos.ID WHERE Consultas.Data BETWEEN ' + @INICIO + ' AND  @FINAL AND (@ID = 0 or Consultas.ID = @ID) AND (@MEDICOID = 0 or Medicos.ID = @MEDICOID) AND (@CLIENTEID = 0 or Clientes.ID = @CLIENTEID)) '

    junior, a questão da ordenação deu certo. obrigado.

    Preciso passar outros parametros da clásula where. na minha query eu coloquei o intervalo de dados.

    ta certo a minha query?

    mas dá erro.

    vlew

    quinta-feira, 27 de setembro de 2012 18:44
  • Pedro, em relação às datas no SQL dinâmico, basta você concatenar aspas simples, conforme exemplo:

    Create Procedure stp_Teste (@Ordenacao VarChar(20), @DataInicial Date, @DataFinal Date) as
    Begin
      Declare @CamposOrdenacao VarChar(100)
    
      if (@Ordenacao = 'Nome')
        Set @CamposOrdenacao = 'NmProduto, CdClassificacao'
      else
        Set @CamposOrdenacao = 'CdClassificacao, NmProduto'
    
      Exec ('Select Top 50 * From Produto Where DtCadastro Between ' + '''' + @DataInicial + '''' + ' and ' + '''' + @DataFinal + '''' + ' Order by ' + @CamposOrdenacao)
    End
    Veja que imediatamente antes e imediatamente depois da utilização dos parâmetros de data eu concateno as aspas. Senão fizer isso o comando fica sem aspas. E é por isso que não estava funcionando.


    Roberson Ferreira - Database Developer
    Acesse: www.robersonferreira.com.br
    Email: contato@robersonferreira.com.br

    Se esta sugestão for útil, por favor, classifique-a como útil.
    Se ela lhe ajudar a resolver o problema, por favor, marque-a como Resposta.

    • Marcado como Resposta Pedrohgb7 sexta-feira, 28 de setembro de 2012 13:32
    sexta-feira, 28 de setembro de 2012 12:06
    Moderador
  • ALTER PROCEDURE [dbo].[SP_SELECT_REL_CONSULTAS_HISTORICO]
    (
    @INICIO DATE,
    @FINAL DATE,
    @CLIENTEID INT,
    @MEDICOID INT,
    @ID INT,
    @ORDENACAO VARCHAR(20)
    )
    AS
    Declare @CamposOrdenacao VarChar(100)
    Begin
      
      if (@Ordenacao = 'MEDICO')
        Set @CamposOrdenacao = 'Medicos.Nome, CONSULTAS.Data,Consultas.HoraInicio'
      else if (@Ordenacao = 'DATA')
        Set @CamposOrdenacao = 'CONSULTAS.Data,Consultas.HoraInicio'
       else
        Set @CamposOrdenacao = 'Consultas.ID'
       
             
      Exec ('SELECT dbo.Consultas.ID,dbo.Consultas.Data, dbo.Consultas.HoraInicio, dbo.Consultas.HoraFinal, dbo.Consultas.Causa, Consultas.ClienteID, Consultas.MedicoID, Consultas.Descricao,dbo.Consultas.Revisao, Clientes.Nome AS CLIENTE,Medicos.Nome AS MEDICO FROM dbo.Clientes INNER JOIN dbo.Consultas ON dbo.Clientes.ID = dbo.Consultas.ClienteID INNER JOIN dbo.Medicos ON dbo.Consultas.MedicoID = dbo.Medicos.ID WHERE Consultas.Data BETWEEN  ' + '''' + @INICIO + '''' + ' and ' + '''' + @FINAL + '''' + ' AND (' + @ID + ' = 0 OR Consultas.ID = ' + @ID + ') AND (' + @MEDICOID + ' = 0 OR Medicos.ID = ' + @MEDICOID + ') AND (' + @CLIENTEID + ' = 0 OR Clientes.ID = ' + @CLIENTEID + ') Order by ' + @CamposOrdenacao)
            
    End

    MUITO BOM, DO JEITO QUE PRECISAVA.

    Só uma dúvida,  minha instrução sql ficou muito grande. Como eu dou uma quebra de linha nesse sql, pra ficar mais organizado.

    obrigado.

    sexta-feira, 28 de setembro de 2012 13:34