none
Problemas com Exec RRS feed

  • Pergunta

  •  

    Alguém sabe me dizer qual o problema com este script?

     

    Declare

    @count int, @equipe2 varchar(10), @equipe3 varchar(10), @verif varchar(50)

     

    Set @count = 2

    Set @equipe2 = '8'

    Set @equipe3 = '10'

     

    While @count <= 3

    Begin

    Set @verif = 'Select @equipe' + Cast(@count As varchar(10))

    Exec(@verif)

    Set @count = @count + 1

    End

     

    quando eu rodo ele me retorna o seguinte erro:

     

    Msg 137, Level 15, State 2, Line 1

    Must declare the scalar variable "@equipe2".

    Msg 137, Level 15, State 2, Line 1

    Must declare the scalar variable "@equipe3".

     

     

    ele parece dizer que eu não declarei as variáveis, mas elas estão declaradas. porque o erro então? se alguém puder me ajudar agradeço...
    terça-feira, 3 de junho de 2008 13:27

Respostas

  • Anderson,

     

    O problema esta ocorrendo na linha do Exec!!!

     

    O que esta ocorrendo é que as variáveis foram declaradas dentro de outro bloco transacional, quando se utiliza o EXEC o SQL Server gera uma nova transação por isso a mensagem de erro informa que as variáveis não foram declaradas.

    terça-feira, 3 de junho de 2008 14:14
  • Bom Dia,

     

    Infelizmente no TSQL temos essas limitações. Toda vez que usamos um EXEC ou um sp_executesql, uma nova sessão é criada e a sessão externa não enxerga tabelas temporárias e variáveis da sessão interna e vice-versa. Para situações como essa, você pode tentar montar o código na aplicação e submetê-lo (o que ficaria ruim também) ou então tentar trabalhar com CLR (o que pode ser mais trabalhoso).

     

    O TSQL foi feito para dar um suporte procedural ao SQL Ansi no SQL Server, mas realmente não podemos extendê-lo tanto de forma a torná-lo uma linguagem tão flexível como Java, VB ou C#. Infelizmente ele possui essa limitação.

     

    [ ]s,

     

    Gustavo

     

    terça-feira, 3 de junho de 2008 14:39
  • Olá Anderson,

     

    É possível sim quebrar o isolamento entre sessões e fazer com que uma sessão acesse recursos de outra (o que não ocorre por padrão), mas isso se dá em relação a recursos como tabelas e esquemas bloqueados e não de variáveis.

     

    Se uma sessão A bloqueia uma tabela T1 para escrita, apenas a sessão A (pelos níveis de isolamento padrão) poderá acessar essa tabela. Se uma sessão B tentar acessar T1, ela ficará esperando. É possível fazer com que a sessão B acesse os dados bloqueados pela sessão A sem alterar o nível de isolamento através do ContextInfo, mas isso se dá com recursos mais complexos e não com variáveis.

     

    Receio que a construção que você citou não possua um equivalente no SQL Server, mas posso estar enganado. Talvez o ContextInfo possa ajudar, mas eu teria que pesquisá-lo um pouco mais.

     

    Com certeza não custa perguntar... A dúvida de um pode ser a inspiração de outros

     

    [ ]s,

     

    Gustavo

     

     

    terça-feira, 3 de junho de 2008 14:56

Todas as Respostas

  • O problema está no

     

    Exec(@verif)

     

    Sua string @verif está errado repare que a variável utilizada no select não foi declarada @equipe

    Set @verif = 'Select @equipe' + Cast(@count As varchar(10))

    Imagino que você queria fazer algo tipo assim.

     

      Set @verif = 'Select ' + @equipe2 + Cast(@count As varchar(10))

    Ou

      Set @verif = 'Select ' + @equipe3 + Cast(@count As varchar(10))

     

    terça-feira, 3 de junho de 2008 14:12
  • Anderson,

     

    O problema esta ocorrendo na linha do Exec!!!

     

    O que esta ocorrendo é que as variáveis foram declaradas dentro de outro bloco transacional, quando se utiliza o EXEC o SQL Server gera uma nova transação por isso a mensagem de erro informa que as variáveis não foram declaradas.

    terça-feira, 3 de junho de 2008 14:14
  • Júnior

     

    e será que se eu declarar a variável dentro do Exec funciona? mas aí eu creio que não tenho como aplicar os valores nas variáveis... então acho que não tem como né?

    será que existe alguma outra forma de testar estas variáveis em tempo de execução?

     

    vai ficar uma várzea o meu código se eu tiver que testar

     

    if @equipe2 > 0

    begin

    bla bla bla

    end

    if @equipe3 > 0

    begin

    bla bla bla

    end

     

    no script onde terei que usar este recurso, estas variáveis vem de um cursor, e eu preciso testar se elas possuem valor, para fazer insert em uma tabela auxiliar...

    terça-feira, 3 de junho de 2008 14:16
  • Bom Dia,

     

    Infelizmente no TSQL temos essas limitações. Toda vez que usamos um EXEC ou um sp_executesql, uma nova sessão é criada e a sessão externa não enxerga tabelas temporárias e variáveis da sessão interna e vice-versa. Para situações como essa, você pode tentar montar o código na aplicação e submetê-lo (o que ficaria ruim também) ou então tentar trabalhar com CLR (o que pode ser mais trabalhoso).

     

    O TSQL foi feito para dar um suporte procedural ao SQL Ansi no SQL Server, mas realmente não podemos extendê-lo tanto de forma a torná-lo uma linguagem tão flexível como Java, VB ou C#. Infelizmente ele possui essa limitação.

     

    [ ]s,

     

    Gustavo

     

    terça-feira, 3 de junho de 2008 14:39
  • Gustavo

     

    eu posso me referir à uma sessão em especial? o SQL grava em algum lugar alguma informação sobre as sessões abertas?

     

    tipo digamos que eu declarei uma variável na sessão, sei lá, 1.

     

    então eu preciso executar através do EXEC, utilizando o nome da variável, não existe algo como:

     

    Select sessão1.variável etc etc etc???

     

    creio que não deva existir, mas perguntar não custa nada.

     

    de qualquer forma valeu pela ajuda pessoal...

     

    terça-feira, 3 de junho de 2008 14:46
  • Olá Anderson,

     

    É possível sim quebrar o isolamento entre sessões e fazer com que uma sessão acesse recursos de outra (o que não ocorre por padrão), mas isso se dá em relação a recursos como tabelas e esquemas bloqueados e não de variáveis.

     

    Se uma sessão A bloqueia uma tabela T1 para escrita, apenas a sessão A (pelos níveis de isolamento padrão) poderá acessar essa tabela. Se uma sessão B tentar acessar T1, ela ficará esperando. É possível fazer com que a sessão B acesse os dados bloqueados pela sessão A sem alterar o nível de isolamento através do ContextInfo, mas isso se dá com recursos mais complexos e não com variáveis.

     

    Receio que a construção que você citou não possua um equivalente no SQL Server, mas posso estar enganado. Talvez o ContextInfo possa ajudar, mas eu teria que pesquisá-lo um pouco mais.

     

    Com certeza não custa perguntar... A dúvida de um pode ser a inspiração de outros

     

    [ ]s,

     

    Gustavo

     

     

    terça-feira, 3 de junho de 2008 14:56
  • valeu pelas respostas pessoal, vou deixar o código daquele jeito mesmo, testando uma por uma...

     

    terça-feira, 3 de junho de 2008 15:01
  • Anderson,

     

    Obrigado pelo retorno.

    terça-feira, 3 de junho de 2008 15:30