none
Duvida Update RRS feed

  • Pergunta

  •  

    Gostaria da saber se é possivel escrever um update da seguinte forma

     

    (abaixo estou colocando a procedure q estou comecando a montar...to fazendo testes para ver se é possivel fazer esse tipo de update)

     

    A tabela chamada de janeiro tem varias colunas  dia01, dia02, dia03  ...etc

     

    dae a ideia é fazer o update de acordo com o dia

     

    vejam o update

     

     

     update janeiro set @data_atual = @TOTAL
     where cidade = @cidade
           

     

    seria para o teste q acabei de fazer  em uma passada do loop

     

      update janeiro set dia13 = 90

      where cidade = Niteroi

     

     

    Eu nao sei se é problema de comit....mas tipo a saída...vem dizendo q uma linha foi alterada, mas qdo eu olho na tabela nao tem registro alterado...vejam:

     

    NITEROI                      
    16
    dia13

    (1 row(s) affected)

     

    mas nao alterou....

     

    Alguem pode me ajudar? q q eu to fazendo errado?

     

     

    SET QUOTED_IDENTIFIER ON
    GO
    SET ANSI_NULLS ON
    GO

    ALTER  procedure [dbo].[sp_Cursor_Relatorio_RDBC]as

     

    DECLARE
           @data_atual AS varchar(5),
           @CIDADE AS VARCHAR(50),
           @TOTAL AS INT


    select @data_atual = 'dia'+convert(varchar(5),day(getdate()))

     

    print @data_atual

     

    DECLARE CRS_ATIVADOS CURSOR FOR

    select cidade, count(*) as Total from
    (select distinct cnpj, cidade,plano from relatorio_wimax_dt
    where replace(data_ativacao_tecnica,' ','') = ''
    and month(convert(datetime,data_cadastro,103)) = month(getdate())
    and year(convert(datetime,data_cadastro,103)) = year(getdate())
    ) A
    group by cidade
    order by cidade

     

    OPEN CRS_ATIVADOS

    FETCH NEXT FROM CRS_ATIVADOS INTO @CIDADE, @TOTAL

     

    WHILE (@@FETCH_STATUS = 0)
    begin
    print @cidade
    print @total
    print @data_atual

     update janeiro set @data_atual = @TOTAL
     where cidade = @cidade
     
    print @data_atual

    FETCH NEXT FROM CRS_ATIVADOS INTO @CIDADE, @TOTAL

    end

     

    CLOSE CRS_ATIVADOS
    DEALLOCATE CRS_ATIVADOS

     

    commit

     

    GO
    SET QUOTED_IDENTIFIER OFF
    GO
    SET ANSI_NULLS ON
    GO

     

    quinta-feira, 13 de novembro de 2008 21:56

Respostas

  • Olá,

     

    Não vou entrar nos méritos da otimização da tua stored procedure (otimização do tipo de cursor utilizado - leia sobre FAST_FORWARD -, assim como a real necessidade de utilizá-lo), mas só para sanar esta tua dúvida, o SQL não consegue formar um statement dinamicamente, do modo que você está tentando fazer:

    Code Snippet

    update janeiro set @data_atual = @TOTAL

    where cidade = @cidade

     

     

    O que ele está fazendo neste caso, é atribuindo o valor contido na variável @TOTAL, para a variável @data_atual. O "1 row(s) affected" que aparece, é porque realmente existe um registro na tabela, que poderia ser alterado.

     

    Faça o seguinte para resolver o problema desta query:

    Lá em cima, junto com as outras, declare uma nova variável:

    Code Snippet

    DECLARE @sql_stmt NVARCHAR(300)

     

     

    Depois altere o codigo do update, para o código abaixo:

    Code Snippet

    SET @sql_stmt = 'update janeiro set ' + @data_atual + ' = ' + CONVERT(VARCHAR, @TOTAL) + ' where cidade = ''' + @cidade + ''''

    --// PRINT @sql_stmt -- para testar como ficará o resultado do update

    EXEC (@sql_stmt)

     

     

    Procure aqui mesmo no fórum, uns posts sobre FAST_FORWARD. Tem um bem recente do Gustavo, falando sobre isso.

    Veja se isso resolve, e qualquer coisa, poste novamente.


    Um abraço,

    Raul Santos

    sexta-feira, 14 de novembro de 2008 12:57
  • Olá,

     

    Para resolver o espaçamento na variável @cidade, use as funções RTRIM() e LTRIM(), vide exemplo abaixo.

    Code Snippet

    RTRIM(LTRIM(@cidade))

     

     

    Sobre o cursor FAST_FORWARD, a sintaxe está abaixo, mas dê uma lida na net para entender melhor suas características.

    Code Snippet

    DECLARE NOME_DO_CURSOR CURSOR FAST_FORWARD FOR

    SELECT ...

     

     

    Sobre o COMMIT, o SQL Server possui um modo de AUTOCOMMIT, cuja opção já vem habilitada por padrão. Ou seja, você não precisa "commitar" os statements após sua execução. Você só precisa usar o COMMIT, caso queira trabalhar com transações.

     

    No teu caso, você precisa controlar todos estes updates, e dar um ROLLBACK caso algo dê errado? Se sim, você precisará ler um pouco mais sobre transações e tratamentos de erro, para poder trabalhar com COMMITs e ROLLBACKs.

     

    Um abraço,
    Raul Santos

     

    sexta-feira, 14 de novembro de 2008 14:19
  • Olá, Tenta isso aqui:

     

    Code Snippet

    SET @sql = 'select cidade, count(*) as total from

    ( select distinct cnpj,plano,cidade from ' + @tabela +

    ' where ltrim(rtrim((data_ativacao_tecnica)) <> ' + char(39) + CHAR(39) +

    ' and ltrim(rtrim((data_desativacao) = ' + CHAR(39) + CHAR(39) +

    ' and month(convert(datetime,data_ativacao_tecnica,103)) = month(getdate()) ' +

    ' and year(convert(datetime,data_ativacao_tecnica,103)) = year(getdate()) ' +

    ' ) A ' +

    ' group by cidade' +

    ' order by cidade'

     

     

    Para testar é sempre bom usar um select. Exemplo

     

    Code Snippet

    declare @tabela varchar(max)

    set @tabela = 'tab'

    select 'select cidade, count(*) as total from

    ( select distinct cnpj,plano,cidade from ' + @tabela +

    ' where ltrim(rtrim((data_ativacao_tecnica)) <> ' + char(39) + CHAR(39) +

    ' and ltrim(rtrim((data_desativacao) = ' + CHAR(39) + CHAR(39) +

    ' and month(convert(datetime,data_ativacao_tecnica,103)) = month(getdate()) ' +

    ' and year(convert(datetime,data_ativacao_tecnica,103)) = year(getdate()) ' +

    ' ) A ' +

    ' group by cidade' +

    ' order by cidade'

     

    Resulta em:

    select

    cidade, count(*) as total

    from

    (

    select distinct cnpj,plano,cidade

    from tab

    where

    ltrim(rtrim((data_ativacao_tecnica)) <> ''

    and ltrim(rtrim((data_desativacao) = ''

    and month(convert(datetime,data_ativacao_tecnica,103)) = month(getdate())

    and year(convert(datetime,data_ativacao_tecnica,103)) = year(getdate())

    ) A

    group by cidade order by cidade

     

     

    Abraços;
    sexta-feira, 14 de novembro de 2008 19:56

Todas as Respostas

  • Boa Noite,

     

    Seu SQL Server é 2005 ?

     

    [ ]s,

     

    Gustavo

     

    quinta-feira, 13 de novembro de 2008 23:07
  • Fala ae Gustavo!

    SQLServer 2000.

     

    att

    Daniel Esquerdo

     

     

    obs.: O campo dia13  , dia14 etc sao do tipo int na tabela Janeiro

     

    Obs.: Gustavo, qq coisa se precisar tenho disponibilidade de ligar para qq lugar do Brasil...

    sexta-feira, 14 de novembro de 2008 11:47
  • Olá,

     

    Não vou entrar nos méritos da otimização da tua stored procedure (otimização do tipo de cursor utilizado - leia sobre FAST_FORWARD -, assim como a real necessidade de utilizá-lo), mas só para sanar esta tua dúvida, o SQL não consegue formar um statement dinamicamente, do modo que você está tentando fazer:

    Code Snippet

    update janeiro set @data_atual = @TOTAL

    where cidade = @cidade

     

     

    O que ele está fazendo neste caso, é atribuindo o valor contido na variável @TOTAL, para a variável @data_atual. O "1 row(s) affected" que aparece, é porque realmente existe um registro na tabela, que poderia ser alterado.

     

    Faça o seguinte para resolver o problema desta query:

    Lá em cima, junto com as outras, declare uma nova variável:

    Code Snippet

    DECLARE @sql_stmt NVARCHAR(300)

     

     

    Depois altere o codigo do update, para o código abaixo:

    Code Snippet

    SET @sql_stmt = 'update janeiro set ' + @data_atual + ' = ' + CONVERT(VARCHAR, @TOTAL) + ' where cidade = ''' + @cidade + ''''

    --// PRINT @sql_stmt -- para testar como ficará o resultado do update

    EXEC (@sql_stmt)

     

     

    Procure aqui mesmo no fórum, uns posts sobre FAST_FORWARD. Tem um bem recente do Gustavo, falando sobre isso.

    Veja se isso resolve, e qualquer coisa, poste novamente.


    Um abraço,

    Raul Santos

    sexta-feira, 14 de novembro de 2008 12:57
  • Fala Raul!

     

    Brigadao mano...FUNCIONOU!

     

    So fiquei com uma duvida....

    Veja como ficou o PRINT    

     

    update janeiro set dia14 = 16 where cidade = 'NITEROI                       '

     

    sera q esse espaço todo nao pode dar problema na hora do teste do where nao?  isso é fruto do tamanho da variavel @cidade....bem...nao pareceu ter problema...so fiquei com duvida mesmo...

     

    Raul e sobre o commit , esta bem localizado na procedure....?

     

    Como eu disse to comecando a montar ela ainda...e vou ler a sua sugestao sobre o tal FAST_FORWARD .


    Dae qualquer coisa a gente se fala...

     

    valeu pela ajuda !

     

     

    sexta-feira, 14 de novembro de 2008 13:19
  • Olá,

     

    Para resolver o espaçamento na variável @cidade, use as funções RTRIM() e LTRIM(), vide exemplo abaixo.

    Code Snippet

    RTRIM(LTRIM(@cidade))

     

     

    Sobre o cursor FAST_FORWARD, a sintaxe está abaixo, mas dê uma lida na net para entender melhor suas características.

    Code Snippet

    DECLARE NOME_DO_CURSOR CURSOR FAST_FORWARD FOR

    SELECT ...

     

     

    Sobre o COMMIT, o SQL Server possui um modo de AUTOCOMMIT, cuja opção já vem habilitada por padrão. Ou seja, você não precisa "commitar" os statements após sua execução. Você só precisa usar o COMMIT, caso queira trabalhar com transações.

     

    No teu caso, você precisa controlar todos estes updates, e dar um ROLLBACK caso algo dê errado? Se sim, você precisará ler um pouco mais sobre transações e tratamentos de erro, para poder trabalhar com COMMITs e ROLLBACKs.

     

    Um abraço,
    Raul Santos

     

    sexta-feira, 14 de novembro de 2008 14:19
  •  

    Beleza Raul. Eu tinha achado ja como usar o tal cursor, valeu pelo rtrim..vou tentar aqui...

     

    Sobre comit e rollback eu entendo , so nao estou muito familiarizado com o sql server e tem tempo q nao monto um DTS ..cheio de "borogodó" ...dae tenho q desenferrujar...

     

     

    cara aproveitando... me tira mais uma duvida mano...

     

    eu to mexendo no update..to acrescentando mais coisas....

     

     

    tipo no final do update eu coloquei:

     

    SET @sql_stmt = 'update janeiro set ' + @data_atual + ' = ' + CONVERT(VARCHAR, @TOTAL) + ' where cidade = ''' + @cidade + ''''  +  ' and status = ' + ' ativados'

     

     

    tipo nao to conseguindo ajustar o and do update....  to tentando colocar  

     

    and status = 'ativados'  mas nao to conseguindo....da p ajudar?  ja tentei varias possibilidades mas ainda nao consegui...

     

     

    pq ta dando erro 

    dizendo "invalid column name 'ativados'

     

     

     

    Bem fui tentar colocar uns parametros na procedure e montar mais um sql e estou me enrolando todo...

     

    Alguem pode me dar um help de como controlar bem os famosos plics ( ' ) ????

     

    Nao posso fazer isso?

     

    SET @sql = 'select cidade, count(*) as total  from
    ( select distinct cnpj,plano,cidade from '
    + @tabela + '
    where replace(data_ativacao_tecnica,' ','') <> ''
    and replace(data_desativacao,' ','') = ''
    and month(convert(datetime,data_ativacao_tecnica,103)) = month(getdate())
    and year(convert(datetime,data_ativacao_tecnica,103)) = year(getdate())
    ) A
    group by cidade
    order by cidade'

     

    ta dando monte de erro pessoal...desculpa a ignorancia....

    sexta-feira, 14 de novembro de 2008 17:48
  • Olá, Tenta isso aqui:

     

    Code Snippet

    SET @sql = 'select cidade, count(*) as total from

    ( select distinct cnpj,plano,cidade from ' + @tabela +

    ' where ltrim(rtrim((data_ativacao_tecnica)) <> ' + char(39) + CHAR(39) +

    ' and ltrim(rtrim((data_desativacao) = ' + CHAR(39) + CHAR(39) +

    ' and month(convert(datetime,data_ativacao_tecnica,103)) = month(getdate()) ' +

    ' and year(convert(datetime,data_ativacao_tecnica,103)) = year(getdate()) ' +

    ' ) A ' +

    ' group by cidade' +

    ' order by cidade'

     

     

    Para testar é sempre bom usar um select. Exemplo

     

    Code Snippet

    declare @tabela varchar(max)

    set @tabela = 'tab'

    select 'select cidade, count(*) as total from

    ( select distinct cnpj,plano,cidade from ' + @tabela +

    ' where ltrim(rtrim((data_ativacao_tecnica)) <> ' + char(39) + CHAR(39) +

    ' and ltrim(rtrim((data_desativacao) = ' + CHAR(39) + CHAR(39) +

    ' and month(convert(datetime,data_ativacao_tecnica,103)) = month(getdate()) ' +

    ' and year(convert(datetime,data_ativacao_tecnica,103)) = year(getdate()) ' +

    ' ) A ' +

    ' group by cidade' +

    ' order by cidade'

     

    Resulta em:

    select

    cidade, count(*) as total

    from

    (

    select distinct cnpj,plano,cidade

    from tab

    where

    ltrim(rtrim((data_ativacao_tecnica)) <> ''

    and ltrim(rtrim((data_desativacao) = ''

    and month(convert(datetime,data_ativacao_tecnica,103)) = month(getdate())

    and year(convert(datetime,data_ativacao_tecnica,103)) = year(getdate())

    ) A

    group by cidade order by cidade

     

     

    Abraços;
    sexta-feira, 14 de novembro de 2008 19:56
  • Fala ae Demetrio..valeu pela ajuda..aprendi mais uma com o  CHAR(39)

     

    Postei uma outra duvida ...de sobre como eu coloco um select variavel dentro de um cursor....

     

    se souber da um help ae mano...

     

    abração

     

    sábado, 15 de novembro de 2008 13:36