Declarando Cursores (SQL) - Carnette Socorro!!!

20/05/2003

1

Boa, pessoal...
Em especial pro mano carnette!

meu problema é:

tenho que fazer um log de uma tabela no sql 6.5, dai fiz uma trigger que faz quase tudo direitinho. Ela ve se a tabela inserted e a deleted contém registros e em caso positivo ela entende que trata-se de uma alteração e copia o conteudo da deleted pra uma tabela de log que tem a estrutura igual a original mais os campos quem, onde e quando, os quais ela poe o nome do usuario, estação de trabalho e data/hora (Suser_Name(),Host_Name(),GetDate()) e depois faz o mesmo pra inserted, dai na auditoria da pra ver o que foi alterado comparando um registro com o próximo. Isso funciona muito bem, só pega quando eu faço uma alteração em bloco, nesse caso, a tabela de log fica com todos os registros deletados e depois todos os registros inseridos (o ideal seria alternados deletado e inserido).
Solução: preciso criar um cursor só que eu NÃO SEI FAZER ISSO!
Por favor, preciso de um exemplo de cursor com um ´while not eof´ pra eu poder, no caso, inserir na tebela de log um registro de cada vez


Responder

Posts

20/05/2003

Carnette

POSTa a tua trigger aqui..pra gente dar uma olhada


Responder

20/05/2003

Flavio Sanches

if exists (select * from sysobjects where id = object_id(´dbo.tr_LogFinanceiro_imob´) and sysstat & 0xf = 8)
drop trigger dbo.tr_LogFinanceiro_imob
GO

CREATE TRIGGER tr_LogFinanceiro_imob ON dbo.Financeiro_imob
FOR INSERT,UPDATE,DELETE
AS

/* Cria o trigger para log das operacoes dos usuarios
Na Tabela Financeiro_Imob
AUTOR : FLÁVIO SANCHES
DATA : 31/01/2003
*/

-- Testa se Tem algum registro na tabela Inserted
If exists(Select inscricao_imob from Inserted)
Begin
-- Testa se Tem algum registro na tabela Deleted
If exists(Select inscricao_imob from deleted)
begin
-- se tem registro em ambas as tabelas entao a operacao e alteracao
-- insere no log o registro antes da operacao

Insert Into lg_Financ_imob (
Usuario ,estacao ,Dia_Hora ,
Operacao ,Inscricao_imob ,chave_ident ,
Ano_Divida ,cod_Divida ,Sub_Divida ,
Cod_Tipo_Moeda ,Parcela ,Vencimento ,
Valor ,Cod_Situacao_Divida ,Num_Termo_Origem ,
Ano_Termo_Origem ,Num_Termo_Destino ,Ano_Termo_Destino ,
TEM_COMPOSICAO ,Qtde_Parc_Agrup )
select Suser_Name() ,Host_Name() ,GetDate() ,
´A´ ,Inscricao_imob ,chave_ident ,
Ano_Divida ,cod_Divida ,Sub_Divida ,
Cod_Tipo_Moeda ,Parcela ,Vencimento ,
Valor ,Cod_Situacao_Divida ,Num_Termo_Origem ,
Ano_Termo_Origem ,Num_Termo_Destino ,Ano_Termo_Destino ,
TEM_COMPOSICAO ,Qtde_Parc_Agrup
from deleted

-- Insere na Tabela o registro Depois da operacao

Insert Into lg_Financ_imob (
Usuario ,estacao ,Dia_Hora ,
Operacao ,Inscricao_imob ,chave_ident ,
Ano_Divida ,cod_Divida ,Sub_Divida ,

Cod_Tipo_Moeda ,Parcela ,Vencimento ,
Valor ,Cod_Situacao_Divida ,Num_Termo_Origem ,
Ano_Termo_Origem ,Num_Termo_Destino ,Ano_Termo_Destino ,
TEM_COMPOSICAO ,Qtde_Parc_Agrup )
select Suser_Name() ,Host_Name() ,GetDate() ,
´A´ ,Inscricao_imob ,chave_ident ,
Ano_Divida ,cod_Divida ,Sub_Divida ,
Cod_Tipo_Moeda ,Parcela ,Vencimento ,
Valor ,Cod_Situacao_Divida ,Num_Termo_Origem ,
Ano_Termo_Origem ,Num_Termo_Destino ,Ano_Termo_Destino ,
TEM_COMPOSICAO ,Qtde_Parc_Agrup

from Inserted
End
Else
Begin
-- Se nao tem registro na tabela deleted entao a operacao e de inclusao
Insert Into lg_Financ_imob (
Usuario ,estacao ,Dia_Hora ,
Operacao ,Inscricao_imob ,chave_ident ,
Ano_Divida ,cod_Divida ,Sub_Divida ,
Cod_Tipo_Moeda ,Parcela ,Vencimento ,
Valor ,Cod_Situacao_Divida ,Num_Termo_Origem ,
Ano_Termo_Origem ,Num_Termo_Destino ,Ano_Termo_Destino ,
TEM_COMPOSICAO ,Qtde_Parc_Agrup )
select Suser_Name() ,Host_Name() ,GetDate() ,
´I´ ,Inscricao_imob ,chave_ident ,
Ano_Divida ,cod_Divida ,Sub_Divida ,
Cod_Tipo_Moeda ,Parcela ,Vencimento ,
Valor ,Cod_Situacao_Divida ,Num_Termo_Origem ,
Ano_Termo_Origem ,Num_Termo_Destino ,Ano_Termo_Destino ,
TEM_COMPOSICAO ,Qtde_Parc_Agrup
from inserted

End
End
Else
Begin

-- Se nao tem registro na tabela Inserted entao a operacao e de exclusao
-- Insere no log o registro apagado
Insert Into lg_Financ_imob (
Usuario ,estacao ,Dia_Hora ,
Operacao ,Inscricao_imob ,chave_ident ,
Ano_Divida ,cod_Divida ,Sub_Divida ,
Cod_Tipo_Moeda ,Parcela ,Vencimento ,
Valor ,Cod_Situacao_Divida ,Num_Termo_Origem ,
Ano_Termo_Origem ,Num_Termo_Destino ,Ano_Termo_Destino ,
TEM_COMPOSICAO ,Qtde_Parc_Agrup )
select Suser_Name() ,Host_Name() ,GetDate() ,
´E´ ,Inscricao_imob ,chave_ident ,
Ano_Divida ,cod_Divida ,Sub_Divida ,
Cod_Tipo_Moeda ,Parcela ,Vencimento ,
Valor ,Cod_Situacao_Divida ,Num_Termo_Origem ,
Ano_Termo_Origem ,Num_Termo_Destino ,Ano_Termo_Destino ,
TEM_COMPOSICAO ,Qtde_Parc_Agrup
from deleted

End
GO


Responder

20/05/2003

Cac2000

Amigo, eu não sou o Carnete, mas eu tenho isso que vc está querendo... vou te dar um exemplo, aí vc adapta pra sua trigger, ok?


create trigger tr_grava_log on tabela1
for insert, update, delete

as
declare @campo1_ins int, @campo2_ins int, @campo3_ins int,
@campo1_del int, @campo2_del int, @campo3_del int

declare cur_ins cursor for
select campo1, campo2, campo3
from inserted

declare cur_del cursor for
select campo1, campo2, campo3
from deleted

fetch cur_ins into @campo1_ins, @campo2_ins, @campo3_ins

fetch cur_del into @campo1_del, @campo2_del, @campo3_del

while @@fetch_status = 0 -- mesmo que WHILE NOT EOF
begin

-- aqui dentro vc grava nas suas tabelas de log, usando as variaveis(@)


fetch cur_ins into @campo1_ins, @campo2_ins, @campo3_ins

fetch cur_del into @campo1_del, @campo2_del, @campo3_del

end


end


Responder

21/05/2003

Flavio Sanches

Obrigado pela resposta, acho que vai resolver.
Desculpe se pareci preferir a resposta do carnette, mas é que temos que reconhecer que o cara é bom pra caraca.

Só mais uma dúvida...
É claro que eu procurei tb em livros por aqui e lá tinha um exemplo parecido com o seu (cac2000), só que ele usava @@fetch_next ou algo parecido e vc usa só @@fetch. Qual seria a diferença? Pelo que eu entendi o fetch next lê o registro atual ponteirado e move o ponteiro automaricamente pro próximo registro. Não seria mais apropriado???

De qq forma, Valeu!!!


Responder

21/05/2003

Aroldo Zanela

[quote:8b3e265ac1=´Flavio Sanches´]Obrigado pela resposta, acho que vai resolver.
Desculpe se pareci preferir a resposta do carnette, mas é que temos que reconhecer que o cara é bom pra caraca.

Só mais uma dúvida...
É claro que eu procurei tb em livros por aqui e lá tinha um exemplo parecido com o seu (cac2000), só que ele usava @@fetch_next ou algo parecido e vc usa só @@fetch. Qual seria a diferença? Pelo que eu entendi o fetch next lê o registro atual ponteirado e move o ponteiro automaricamente pro próximo registro. Não seria mais apropriado???

De qq forma, Valeu!!![/quote:8b3e265ac1]


A instrução FETCH busca uma linha na direção especificada que pode ser NEXT, PRIOR, FIRST, LAST, ABSOLUTE n ou RELATIVE n. A direção default é NEXT. Quando bem sucedida retorna 0 em @@fetch_status.

Peguei um gancho com o exemplo do nosso colega cac2000 e adicionei algumas instruções para não ocorrer erros, no caso de você se esquecer de abrir, fechar e desalocar os cursores:

create trigger tr_grava_log on tabela1
for insert, delete
as
declare @campo1_ins int, @campo2_ins int, @campo3_ins int,
@campo1_del int, @campo2_del int, @campo3_del int

declare cur_ins cursor for
select campo1, campo2, campo3
from inserted

declare cur_del cursor for
select campo1, campo2, campo3
from deleted

/* Abrir os cursores */

open cur_ins
open cur_del

while @@fetch_status = 0 /* Enquanto não percorrer os registros de ambas as tabelas */
begin

     fetch next from cur_ins into @campo1_ins, @campo2_ins, @campo3_ins
     Insert into TabelaLOG values(@campo1_ins, @campo2_ins, @campo3_ins)

     fetch next from cur_del into @campo1_del, @campo2_del, @campo3_del
     Insert into TabelaLOG values(@campo1_del, @campo2_del, @campo3_del)
end

/* Fechar cursores */
close cur_ins
close cur_del

/* Remover a alocação dos cursoses */
deallocate cur_ins
deallocate cur_del

end



Responder

22/05/2003

Flavio Sanches

Brigadão galera,
Zanela...Cac2000...Etc
E o meu camarada carnette que sumiu...

Consegui graças a ajuda de vcs.

abraços


Responder

22/05/2003

Carnette

[quote:7759348a8e=´Flavio Sanches´]Brigadão galera,
Zanela...Cac2000...Etc
E o meu camarada carnette que sumiu...

Consegui graças a ajuda de vcs.

abraços[/quote:7759348a8e]


O Camarada carnette sumiu...Porque ficou pensando pensando pensando.....e só pensando.....Mas, nada melhor do que ter companheiros competentes aqui no forum..que em vez de ficarem só pensando....respondem as questões......tbm agradeço as respostas dos companheiros acima e podem ter certeza que as dicas já estão guardadas....


Responder

22/05/2003

Flavio Sanches

Voltei...
O bagulho ficou legal,
Só que funciona de vez em quando...
Ou seja, no update ele faz umas e não faz outras vezes.

alguém tem alguma idéia de como resolvere isso???

tenho um livro aqui que diz que é possível na mesma trigger, separar os eventos insert,delete e update, será que isso resolve???

minha trigger está assim:

if exists (select * from sysobjects where id = object_id(´dbo.tr_LogFinanceiro_imob´) and sysstat & 0xf = 8)
drop trigger dbo.tr_LogFinanceiro_imob
GO

CREATE TRIGGER tr_LogFinanceiro_imob ON dbo.Financeiro_imob
FOR INSERT,UPDATE,DELETE
AS
/* Cria o trigger para log das operacoes dos usuarios
Na Tabela Financeiro_imob
AUTOR : FLÁVIO SANCHES
DATA : 21/05/2003
*/

-- Declara as variaveis dos campos da tabela onde o trigger atua
Declare
@Inscricao_imob char(6) ,
@chave_ident char(3) ,
@Ano_Divida char(4) ,
@Cod_Divida char(2) ,
@Sub_Divida char(2) ,
@Cod_Tipo_Moeda char(2) ,
@Parcela char(2) ,
@Vencimento DateTime,
@Valor float ,
@Cod_Situacao_Divida char(2) ,
@Num_Termo_Origem char(6) ,
@Ano_Termo_Origem char(4) ,
@Num_Termo_Destino char(6) ,
@Ano_Termo_Destino char(4) ,
@Qtde_Parc_Agrup char(2) ,
@Tem_Composicao char(1)


-- Testa se Tem algum registro na tabela Inserted
If exists(Select inscricao from Inserted)
Begin
-- Testa se Tem algum registro na tabela Deleted
If exists(Select inscricao from deleted)
begin
-- se tem registro em ambas as tabelas entao a operacao e alteracao
-- insere no log o registro antes da operacao

Declare cur_ins Cursor For
Select
Inscricao_imob ,Chave_ident ,Ano_Divida ,Cod_Divida ,
Sub_Divida ,Cod_Tipo_Moeda ,Parcela ,Vencimento ,
Valor ,Cod_Situacao_Divida ,Num_Termo_Origem ,Ano_Termo_Origem ,
Num_Termo_Destino ,Ano_Termo_Destino ,Qtde_Parc_Agrup ,Tem_Composicao
from Inserted

Open cur_ins

Declare cur_del Cursor For
Select
Inscricao_imob ,Chave_ident ,Ano_Divida ,Cod_Divida ,
Sub_Divida ,Cod_Tipo_Moeda ,Parcela ,Vencimento ,
Valor ,Cod_Situacao_Divida ,Num_Termo_Origem ,Ano_Termo_Origem ,
Num_Termo_Destino ,Ano_Termo_Destino ,Qtde_Parc_Agrup ,Tem_Composicao
from deleted

Open cur_del

While (@@Fetch_Status <> -1)
Begin
Fetch Next From cur_del
Into
@Inscricao_imob ,@Chave_ident ,@Ano_Divida ,@Cod_Divida ,
@Sub_Divida ,@Cod_Tipo_Moeda ,@Parcela ,@Vencimento ,
@Valor ,@Cod_Situacao_Divida ,@Num_Termo_Origem ,@Ano_Termo_Origem ,
@Num_Termo_Destino ,@Ano_Termo_Destino ,@Qtde_Parc_Agrup ,@Tem_Composicao

Insert Into Lg_Financ_imob (
Usuario ,estacao ,Dia_Hora ,Operacao ,
Inscricao_imob ,Chave_ident ,Ano_Divida ,Cod_Divida ,
Sub_Divida ,Cod_Tipo_Moeda ,Parcela ,Vencimento ,
Valor ,Cod_Situacao_Divida ,Num_Termo_Origem ,Ano_Termo_Origem ,
Num_Termo_Destino ,Ano_Termo_Destino ,Qtde_Parc_Agrup ,Tem_Composicao
)Values(
Suser_Name() ,Host_Name() ,GetDate() ,´A´ ,
@Inscricao_imob ,@Chave_ident ,@Ano_Divida ,@Cod_Divida ,
@Sub_Divida ,@Cod_Tipo_Moeda ,@Parcela ,@Vencimento ,
@Valor ,@Cod_Situacao_Divida ,@Num_Termo_Origem ,@Ano_Termo_Origem ,
@Num_Termo_Destino ,@Ano_Termo_Destino ,@Qtde_Parc_Agrup ,@Tem_Composicao )

Fetch Next From cur_ins
Into
@Inscricao_imob ,@Chave_ident ,@Ano_Divida ,@Cod_Divida ,
@Sub_Divida ,@Cod_Tipo_Moeda ,@Parcela ,@Vencimento ,
@Valor ,@Cod_Situacao_Divida ,@Num_Termo_Origem ,@Ano_Termo_Origem ,
@Num_Termo_Destino ,@Ano_Termo_Destino ,@Qtde_Parc_Agrup ,@Tem_Composicao

Insert Into Lg_Financ_imob (
Usuario ,estacao ,Dia_Hora ,Operacao ,
Inscricao_imob ,Chave_ident ,Ano_Divida ,Cod_Divida ,
Sub_Divida ,Cod_Tipo_Moeda ,Parcela ,Vencimento ,
Valor ,Cod_Situacao_Divida ,Num_Termo_Origem ,Ano_Termo_Origem ,
Num_Termo_Destino ,Ano_Termo_Destino ,Qtde_Parc_Agrup ,Tem_Composicao
)Values(
Suser_Name() ,Host_Name() ,GetDate() ,´A´ ,
@Inscricao_imob ,@Chave_ident ,@Ano_Divida ,@Cod_Divida ,
@Sub_Divida ,@Cod_Tipo_Moeda ,@Parcela ,@Vencimento ,
@Valor ,@Cod_Situacao_Divida ,@Num_Termo_Origem ,@Ano_Termo_Origem ,
@Num_Termo_Destino ,@Ano_Termo_Destino ,@Qtde_Parc_Agrup ,@Tem_Composicao
)
End

Close cur_del
Deallocate cur_del
Close cur_ins
Deallocate cur_ins

End
Else
Begin
-- Se nao tem registro na tabela deleted entao a operacao e de inclusao
Insert Into lg_Financ_imob (
Usuario ,estacao ,Dia_Hora ,Operacao ,
Inscricao_imob ,Chave_ident ,Ano_Divida ,Cod_Divida ,
Sub_Divida ,Cod_Tipo_Moeda ,Parcela ,Vencimento ,
Valor ,Cod_Situacao_Divida ,Num_Termo_Origem ,Ano_Termo_Origem ,
Num_Termo_Destino ,Ano_Termo_Destino ,Qtde_Parc_Agrup ,Tem_Composicao )
select
Suser_Name() ,Host_Name() ,GetDate() ,´I´ ,
Inscricao_imob ,Chave_ident ,Ano_Divida ,Cod_Divida ,
Sub_Divida ,Cod_Tipo_Moeda ,Parcela ,Vencimento ,
Valor ,Cod_Situacao_Divida ,Num_Termo_Origem ,Ano_Termo_Origem ,
Num_Termo_Destino ,Ano_Termo_Destino ,Qtde_Parc_Agrup ,Tem_Composicao
from inserted

End
End
Else
Begin

-- Se nao tem registro na tabela Inserted entao a operacao e de exclusao
-- Insere no log o registro apagado
Insert Into lg_Financ_imob (
Usuario ,estacao ,Dia_Hora ,Operacao ,
Inscricao_imob ,Chave_ident ,Ano_Divida ,Cod_Divida ,
Sub_Divida ,Cod_Tipo_Moeda ,Parcela ,Vencimento ,
Valor ,Cod_Situacao_Divida ,Num_Termo_Origem ,Ano_Termo_Origem ,
Num_Termo_Destino ,Ano_Termo_Destino ,Qtde_Parc_Agrup ,Tem_Composicao )
select
Suser_Name() ,Host_Name() ,GetDate() ,´I´ ,
Inscricao_imob ,Chave_ident ,Ano_Divida ,Cod_Divida ,
Sub_Divida ,Cod_Tipo_Moeda ,Parcela ,Vencimento ,
Valor ,Cod_Situacao_Divida ,Num_Termo_Origem ,Ano_Termo_Origem ,
Num_Termo_Destino ,Ano_Termo_Destino ,Qtde_Parc_Agrup ,Tem_Composicao
from deleted

End
GO


Responder
×
+1 DevUP
Acesso diário, +1 DevUP
Parabéns, você está investindo na sua carreira