none
Dificuldades com sintaxe em query dinamica.... RRS feed

  • Pergunta

  • Boas senhores, 

    Estou apanhando com sintaxe ao montar as minhas query dinamicas, não uso com frequencia e tenho que dar manutenção em uma.

    Duvidas:

    1 - Ao criar um declare e tb uma variaves que ira conter declare dentro dela, desta forma qual a visibilidade delas.

    Ex. 

    Declare @query varchar(500)

    Declare @q1 int

    @query = 'declare @q2 int'

    @query = @query + 'select @q2 = campo1 from tabela'

    @query = @query + 'if @q1 = @q2'

    @query = @query + 'Begin'

    .....

    @query = @query + 'End'

    Isto que fiz é possível?

    2 - Para o começo do if e else, tenho que usar o begin sempre, mesmo para uma linha?

    3 - Indicação de site com exemplos de sintaxe, ajudaria bastante...

    Por enquanto são essas 

    t+

    segunda-feira, 13 de fevereiro de 2012 18:07

Respostas

  • DET1, boa tarde,

    Utilize da seguinte forma: declare @query varchar(max). Isto vará com que vc utilize o tamanho máximo do tipo de dados varchar. Se vc colocar 500, vc pode ter futuros problemas, quando seu código ultrapassar este valor.

    Em relação ao if, se vc colocar apenas linha não precisa colocar begin e end. Se for mais de uma linha é necessário.

    Outra coisa importante: se deseja concatenar uma variável do tipo diferente de texto em seu código é necessário a conversão da variável para texto.

    Abs.


    Eduardo Gomes - http://www.h1solucoes.com.br - Twitter: @edugp_sp

    • Marcado como Resposta DET1 quarta-feira, 22 de fevereiro de 2012 13:06
    segunda-feira, 13 de fevereiro de 2012 18:48
  • Olá DET1,

    Vamos às respostas:

    1- Não é possível fazer o que você fex neste caso. Sua variável @q1 está fora do contexto de execução dinâmica, ao executar o código dinâmico vai ser gerado um erro falando que a variável @q1 tem de ser declarada.

    2- Não. O uso do BEGIN..END é somente obrigatório quando no IF ou no ELSE serão executados mais de um comando. Entretanto é uma boa prática sempre utilizar BEGIN..END em todos os seus IFs. Eu particularmente uso e acho que ajuda muito na legibilidade do código.

    3- Quanto a sintaxe e sites de recomendação, eu particularmente prefiro ter uma base forte de estudo em livros. Recomendo a leitura dos livros do Itzik Ben-Gan, que é considerado como o "guru" de T-SQL.

    Bons Estudos!!!

    []'s


    Erickson Ricci
    Microsoft MCITP 2008 Admin, MCTS SQL Server 2005, 2008
    Visite o meu blog: http://ericksonricci.wordpress.com
    Me siga no twitter: @EricksonRicci
    LinkedIN: http://br.linkedin.com/in/ericksonricci
    e-mail: ericksonfabricio@gmail.com
    **Ajude a melhorar o sistema de busca do fórum.Marque a(s) resposta(s) que foram úteis**
    **Se esta resposta solucionou a questão, então, por favor, marque-a como resposta.**

    • Marcado como Resposta DET1 quarta-feira, 22 de fevereiro de 2012 13:06
    segunda-feira, 13 de fevereiro de 2012 19:06
  • Agora ficou mais claro =)

    Sua variável @Atualizado foi declarada e populada dentro do texto de execução dinâmica. Neste caso, você tem que colocar ela dentro do texto, e não fora. Ela faz parte do escopo de execução dinâmico. Ficaria assim...

    SET @Sql = @Sql + 'update tabela3 set obs =  @Atualizado ' + char(13)

    []'s


    Erickson Ricci
    Microsoft MCITP 2008 Admin, MCTS SQL Server 2005, 2008
    Visite o meu blog: http://ericksonricci.wordpress.com
    Me siga no twitter: @EricksonRicci
    LinkedIN: http://br.linkedin.com/in/ericksonricci
    e-mail: ericksonfabricio@gmail.com
    **Ajude a melhorar o sistema de busca do fórum.Marque a(s) resposta(s) que foram úteis**
    **Se esta resposta solucionou a questão, então, por favor, marque-a como resposta.**

    • Sugerido como Resposta Erickson F. D. Ricci segunda-feira, 13 de fevereiro de 2012 20:47
    • Marcado como Resposta DET1 quarta-feira, 22 de fevereiro de 2012 13:06
    segunda-feira, 13 de fevereiro de 2012 20:46
  • Det,

    O Erickson esta certo, por favor poste sua codificação atual para que possamos ajuda-lo, segue um exemplo que fiz rapidamente...



    DECLARE @Query VARCHAR(MAX)



    SET @Query = ''





    SET @Query = @Query + 'DECLARE @Var UNIQUEIDENTIFIER' + CHAR(13)



    SET @Query = @Query + 'DECLARE tb_Cur CURSOR FOR' +
    CHAR(13)



    SET @Query = @Query + 'SELECT Id FROM Teste' +
    CHAR(13)



    SET @Query = @Query + 'OPEN tb_Cur' + CHAR(13)



    SET @Query = @Query + 'FETCH NEXT FROM tb_Cur INTO @Var' + CHAR(13)



    SET @Query = @Query + 'WHILE @@FETCH_STATUS = 0' +
    CHAR(13)



    SET @Query = @Query + 'BEGIN' + CHAR(13)



    SET @Query = @Query + 'SELECT @Var' + CHAR(13)



    SET @Query = @Query + 'END' + CHAR(13)



    SET @Query = @Query + 'CLOSE tb_Cur' + CHAR(13)



    SET @Query = @Query + 'DEALLOCATE tb_Cur' + CHAR(13)





    EXEC (@Query)



    Fabrizzio A. Caputo
    MCT
    Certificações:
    Oracle OCA 11g
    MCITP SQL Server 2008 Implementation and Maintenance
    MCITP SQL Server 2008 Developer
    Blog Pessoal: www.fabrizziocaputo.wordpress.com
    Blog Empresa: www.tripletech.com.br/blog
    Twitter: @FabrizzioCaputo
    Email: fabrizzio.antoniaci@gmail.com

    • Marcado como Resposta DET1 quarta-feira, 22 de fevereiro de 2012 13:06
    terça-feira, 14 de fevereiro de 2012 14:07
    Moderador
  • DET1,

    Seria basicamente isso, se você não vai utilizar esta variável dentro da query dinâmica, pode muito bem, fazer uso dela fora da query, utilizando em qualquer procedimento, desde que a mesma tenha sido declarada.


    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]

    • Marcado como Resposta DET1 quarta-feira, 22 de fevereiro de 2012 13:06
    sexta-feira, 17 de fevereiro de 2012 13:09

Todas as Respostas

  • DET1, boa tarde,

    Utilize da seguinte forma: declare @query varchar(max). Isto vará com que vc utilize o tamanho máximo do tipo de dados varchar. Se vc colocar 500, vc pode ter futuros problemas, quando seu código ultrapassar este valor.

    Em relação ao if, se vc colocar apenas linha não precisa colocar begin e end. Se for mais de uma linha é necessário.

    Outra coisa importante: se deseja concatenar uma variável do tipo diferente de texto em seu código é necessário a conversão da variável para texto.

    Abs.


    Eduardo Gomes - http://www.h1solucoes.com.br - Twitter: @edugp_sp

    • Marcado como Resposta DET1 quarta-feira, 22 de fevereiro de 2012 13:06
    segunda-feira, 13 de fevereiro de 2012 18:48
  • Olá DET1,

    Vamos às respostas:

    1- Não é possível fazer o que você fex neste caso. Sua variável @q1 está fora do contexto de execução dinâmica, ao executar o código dinâmico vai ser gerado um erro falando que a variável @q1 tem de ser declarada.

    2- Não. O uso do BEGIN..END é somente obrigatório quando no IF ou no ELSE serão executados mais de um comando. Entretanto é uma boa prática sempre utilizar BEGIN..END em todos os seus IFs. Eu particularmente uso e acho que ajuda muito na legibilidade do código.

    3- Quanto a sintaxe e sites de recomendação, eu particularmente prefiro ter uma base forte de estudo em livros. Recomendo a leitura dos livros do Itzik Ben-Gan, que é considerado como o "guru" de T-SQL.

    Bons Estudos!!!

    []'s


    Erickson Ricci
    Microsoft MCITP 2008 Admin, MCTS SQL Server 2005, 2008
    Visite o meu blog: http://ericksonricci.wordpress.com
    Me siga no twitter: @EricksonRicci
    LinkedIN: http://br.linkedin.com/in/ericksonricci
    e-mail: ericksonfabricio@gmail.com
    **Ajude a melhorar o sistema de busca do fórum.Marque a(s) resposta(s) que foram úteis**
    **Se esta resposta solucionou a questão, então, por favor, marque-a como resposta.**

    • Marcado como Resposta DET1 quarta-feira, 22 de fevereiro de 2012 13:06
    segunda-feira, 13 de fevereiro de 2012 19:06
  • Obrigado pelo retorno....

    Valeu pelas orientações....quanto a solicitação de site, estou arrumando o aviao em pleno voo :-), o livro irei verificar mas preciso achar alguma ajuda rapida, ou melhor, na net...

    Então Erickson, como resolver o caso onde tenho que fazer o seguinte....

    imagine o exemplo que dei...

    Tenho que comparar duas tabelas, caso sejam diferentes faço algumas ações de insert e na sequencia atualizo outra tabela informando se procisou processar ou não...

    Ex. if diferente 

         begin

               insert

               variavel de apoio = 'Atualizado'

         end

         else

              não atualiza 

              variavel de apoio = 'Ja atualizado'

    end

    atualiza tabela x com coluna 1 = variavel de apoio

    Isso tudo dentro de uma variavel no declare.

    Será que ficou claro?

    Obrigado

    segunda-feira, 13 de fevereiro de 2012 19:20
  • DET1,

    Não ficou muito claro o que você precisa fazer mas, se entendi bem, você terá duas variáveis dentro do seu código dinâmico.

    Um código dinâmico nada mais é que qualquer código SQL, só que ele pode ser "montado" em partes e depois executado. Dentro dele você pode, por exemplo, colocar quantas variáveis precisar para executar seu código.

    Dê uma olhada nesta referência. Eu sei que é um pouco grande mas é uma ótima referência que cobre todos os aspectos de consultas dinamicas: http://www.sommarskog.se/dynamic_sql.html

    Bons Estudos!

    []'s


    Erickson Ricci
    Microsoft MCITP 2008 Admin, MCTS SQL Server 2005, 2008
    Visite o meu blog: http://ericksonricci.wordpress.com
    Me siga no twitter: @EricksonRicci
    LinkedIN: http://br.linkedin.com/in/ericksonricci
    e-mail: ericksonfabricio@gmail.com
    **Ajude a melhorar o sistema de busca do fórum.Marque a(s) resposta(s) que foram úteis**
    **Se esta resposta solucionou a questão, então, por favor, marque-a como resposta.**

    segunda-feira, 13 de fevereiro de 2012 19:37
  • vou dar uma olhada....

    Segue uma query com minha realidade....não consigo atualizar a tabela 3...a variavel @Atualizado não é atualizado....

    USE Banco

    GO


    SET ANSI_NULLS ON
    GO
    SET QUOTED_IDENTIFIER ON
    GO


    ALTER PROCEDURE [dbo].[usp_Carga]



    AS
    BEGIN
    SET NOCOUNT ON;

    declare @base varchar(30)
    set @base = 'BASEX'


    DECLARE @Sql varchar(8000)
    DECLARE @mes_V varchar(10)
    DECLARE @ano_V varchar(10)
        DeCLARE @Atualizado varchar(50)



    SET @mes_V = '4'
    SET @ano_v = '2009'


     




    SET @Sql = @Sql + char(13)  


    SET @Sql = @Sql + 'DECLARE @qtd1 int ' + char(13)
    SET @Sql = @Sql + 'DECLARE @qtd2 int ' + char(13)

    SET @Sql = @Sql + 'SELECT @qtd2 = count(*) ' + char(13)
    SET @Sql = @Sql + 'FROM tabela1 with(nolock) ' + char(13)
    SET @Sql = @Sql + 'WHERE year(data) = ' + @ano_v + char(13)
    SET @Sql = @Sql + 'and month(data) = ' + @mes_v + char(13)
    SET @Sql = @Sql + char(13)
    SET @Sql = @Sql + 'SELECT @qtd1 = count(*) ' + char(13)
    SET @Sql = @Sql + 'FROM tabela2 with(nolock) ' + char(13)
    SET @Sql = @Sql + 'WHERE year(data) = ' + @ano_v + char(13)
    SET @Sql = @Sql + 'and month(data) = ' + @mes_v + char(13)
    SET @Sql = @Sql + char(13)
    SET @Sql = @Sql + 'IF @qtd1 <>  @qtd2' + char(13)
    SET @Sql = @Sql + 'BEGIN ' + char(13)
    SET @Sql = @Sql + 'INSERT INTO ....' + char(13)
    SET @Sql = @Sql + ' SET  @Atualizado = ''Processado''' + char(13)
    SET @Sql = @Sql + 'END ' + char(13)
    SET @Sql = @Sql + 'ELSE ' + char(13)
    SET @Sql = @Sql + ' SET  @Atualizado = ''Já Processado''' + char(13)
    SET @Sql = @Sql + 'update tabela3 set obs =  ' + @Atualizado + char(13)
    SET @Sql = @Sql + char(13)
       
        exec (@Sql)

    END



    Obrigado

    att

    segunda-feira, 13 de fevereiro de 2012 20:38
  • Agora ficou mais claro =)

    Sua variável @Atualizado foi declarada e populada dentro do texto de execução dinâmica. Neste caso, você tem que colocar ela dentro do texto, e não fora. Ela faz parte do escopo de execução dinâmico. Ficaria assim...

    SET @Sql = @Sql + 'update tabela3 set obs =  @Atualizado ' + char(13)

    []'s


    Erickson Ricci
    Microsoft MCITP 2008 Admin, MCTS SQL Server 2005, 2008
    Visite o meu blog: http://ericksonricci.wordpress.com
    Me siga no twitter: @EricksonRicci
    LinkedIN: http://br.linkedin.com/in/ericksonricci
    e-mail: ericksonfabricio@gmail.com
    **Ajude a melhorar o sistema de busca do fórum.Marque a(s) resposta(s) que foram úteis**
    **Se esta resposta solucionou a questão, então, por favor, marque-a como resposta.**

    • Sugerido como Resposta Erickson F. D. Ricci segunda-feira, 13 de fevereiro de 2012 20:47
    • Marcado como Resposta DET1 quarta-feira, 22 de fevereiro de 2012 13:06
    segunda-feira, 13 de fevereiro de 2012 20:46
  • Bom dia, uma coisa aparentemente tão simples e esta tirando meu sono..:-)

    Fiz a mudança declaranto dentro do @sql,  teire a declaração de fora e tirei as aspas,  mesmo assim não atualiza a variável não atualizando o campo no update.

    att

    terça-feira, 14 de fevereiro de 2012 12:26
  • Det,

    O Erickson esta certo, por favor poste sua codificação atual para que possamos ajuda-lo, segue um exemplo que fiz rapidamente...



    DECLARE @Query VARCHAR(MAX)



    SET @Query = ''





    SET @Query = @Query + 'DECLARE @Var UNIQUEIDENTIFIER' + CHAR(13)



    SET @Query = @Query + 'DECLARE tb_Cur CURSOR FOR' +
    CHAR(13)



    SET @Query = @Query + 'SELECT Id FROM Teste' +
    CHAR(13)



    SET @Query = @Query + 'OPEN tb_Cur' + CHAR(13)



    SET @Query = @Query + 'FETCH NEXT FROM tb_Cur INTO @Var' + CHAR(13)



    SET @Query = @Query + 'WHILE @@FETCH_STATUS = 0' +
    CHAR(13)



    SET @Query = @Query + 'BEGIN' + CHAR(13)



    SET @Query = @Query + 'SELECT @Var' + CHAR(13)



    SET @Query = @Query + 'END' + CHAR(13)



    SET @Query = @Query + 'CLOSE tb_Cur' + CHAR(13)



    SET @Query = @Query + 'DEALLOCATE tb_Cur' + CHAR(13)





    EXEC (@Query)



    Fabrizzio A. Caputo
    MCT
    Certificações:
    Oracle OCA 11g
    MCITP SQL Server 2008 Implementation and Maintenance
    MCITP SQL Server 2008 Developer
    Blog Pessoal: www.fabrizziocaputo.wordpress.com
    Blog Empresa: www.tripletech.com.br/blog
    Twitter: @FabrizzioCaputo
    Email: fabrizzio.antoniaci@gmail.com

    • Marcado como Resposta DET1 quarta-feira, 22 de fevereiro de 2012 13:06
    terça-feira, 14 de fevereiro de 2012 14:07
    Moderador
  • Obrigado pelo retorno Fabrizzio.

    No seu exemplo caso precise usar o conteudo de @var fora do contexto da variavel @query, como fazer?

    Exemplo um if @var = 1 begin.....

    sexta-feira, 17 de fevereiro de 2012 13:00
  • DET1,

    Seria basicamente isso, se você não vai utilizar esta variável dentro da query dinâmica, pode muito bem, fazer uso dela fora da query, utilizando em qualquer procedimento, desde que a mesma tenha sido declarada.


    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]

    • Marcado como Resposta DET1 quarta-feira, 22 de fevereiro de 2012 13:06
    sexta-feira, 17 de fevereiro de 2012 13:09
  • Preciso usar dentro e fora, ou seja, preciso passar o conteudo para fora.....

    exemplo

    declare @sql nvarchar(max)
    set @sql = 'Declare @qtde int' + char(13)
    set @sql = @sql + 'select @qtde = 1'
    exec(@sql)
    if @qtde <> 1
    begin
    select @qtde
    end

    Outra coisa....uma saida seria tirar tudo da variavel....como ficaria a sintaxa abaixo sem jogar para @ssql?

    SELECT @sSQL = N'SELECT @retvalOUT = count(*) FROM ' + @tablename

    • Editado DET1 sexta-feira, 17 de fevereiro de 2012 15:21
    sexta-feira, 17 de fevereiro de 2012 13:34
  • Obrigado senhores pela ajuda, no final usei EXEC sp_executesql com retorno e consegui a principio resolver o problema....

    Qq coisa aviso....

    valeu

    quarta-feira, 22 de fevereiro de 2012 13:08