Usuário com melhor resposta
Duvida Update

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
GOALTER 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 cidadeOPEN CRS_ATIVADOS
FETCH NEXT FROM CRS_ATIVADOS INTO @CIDADE, @TOTAL
WHILE (@@FETCH_STATUS = 0)
begin
print @cidade
print @total
print @data_atualupdate janeiro set @data_atual = @TOTAL
where cidade = @cidade
print @data_atualFETCH NEXT FROM CRS_ATIVADOS INTO @CIDADE, @TOTAL
end
CLOSE CRS_ATIVADOS
DEALLOCATE CRS_ATIVADOScommit
GO
SET QUOTED_IDENTIFIER OFF
GO
SET ANSI_NULLS ON
GO
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 Snippetupdate
janeiro set @data_atual = @TOTALwhere
cidade = @cidadeO 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 SnippetDECLARE
@sql_stmt NVARCHAR(300)Depois altere o codigo do update, para o código abaixo:
Code SnippetSET
@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
-
Olá,
Para resolver o espaçamento na variável @cidade, use as funções RTRIM() e LTRIM(), vide exemplo abaixo.
Code SnippetRTRIM
(LTRIM(@cidade))Sobre o cursor FAST_FORWARD, a sintaxe está abaixo, mas dê uma lida na net para entender melhor suas características.
Code SnippetDECLARE
NOME_DO_CURSOR CURSOR FAST_FORWARD FORSELECT
...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 -
Olá, Tenta isso aqui:
Code SnippetSET @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 Snippetdeclare
@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 totalfrom
( 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()) ) Agroup
by cidade order by cidade
Todas as 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 Snippetupdate
janeiro set @data_atual = @TOTALwhere
cidade = @cidadeO 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 SnippetDECLARE
@sql_stmt NVARCHAR(300)Depois altere o codigo do update, para o código abaixo:
Code SnippetSET
@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
-
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 !
-
Olá,
Para resolver o espaçamento na variável @cidade, use as funções RTRIM() e LTRIM(), vide exemplo abaixo.
Code SnippetRTRIM
(LTRIM(@cidade))Sobre o cursor FAST_FORWARD, a sintaxe está abaixo, mas dê uma lida na net para entender melhor suas características.
Code SnippetDECLARE
NOME_DO_CURSOR CURSOR FAST_FORWARD FORSELECT
...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 -
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....
-
Olá, Tenta isso aqui:
Code SnippetSET @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 Snippetdeclare
@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 totalfrom
( 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()) ) Agroup
by cidade order by cidade -