Trigger: No disparo, ocorre erro na aplicação!
Olá!
Se você puder me ajudar numa dúvida sobre trigger, eu ficarei muito agradecida!
Eu criei uma aplicação delphi 7 + SQL Server Express 2005
Utilizo componentes ADO e ClientDataSet.
Tenho uma tabela de cliente e uma tabela de pedido.
Criei uma trigger para a tabela cliente que exclui todos os pedidos do cliente excluido:
create trigger ExclusaoCliente
on Cliente for delete
as
delete from Pedido
where Id_Cliente in (select Id_Cliente from deleted)
GO
Quando clico no botão excluir para deletar o cliente e o cliente tem apenas um pedido, a tabela do banco de dados é
atualizada, mas quando o cliente tem mais de um pedido, ocorre o seguinte erro no applyUpdates:
´Update affects more than 1 record´
Quando eu crio uma new Query para excluir todos os pedidos de um cliente(diretamente do banco de dados, isto é, fora da
aplicação Delphi) esse problema não ocorre.
O que pode estar errado?
Obrigada pela atenção.
Até mais amigo(a)!
Se você puder me ajudar numa dúvida sobre trigger, eu ficarei muito agradecida!
Eu criei uma aplicação delphi 7 + SQL Server Express 2005
Utilizo componentes ADO e ClientDataSet.
Tenho uma tabela de cliente e uma tabela de pedido.
Criei uma trigger para a tabela cliente que exclui todos os pedidos do cliente excluido:
create trigger ExclusaoCliente
on Cliente for delete
as
delete from Pedido
where Id_Cliente in (select Id_Cliente from deleted)
GO
Quando clico no botão excluir para deletar o cliente e o cliente tem apenas um pedido, a tabela do banco de dados é
atualizada, mas quando o cliente tem mais de um pedido, ocorre o seguinte erro no applyUpdates:
´Update affects more than 1 record´
Quando eu crio uma new Query para excluir todos os pedidos de um cliente(diretamente do banco de dados, isto é, fora da
aplicação Delphi) esse problema não ocorre.
O que pode estar errado?
Obrigada pela atenção.
Até mais amigo(a)!
Athena
Curtidas 0
Respostas
Emerson Nascimento
29/11/2006
tem certeza que o erro ocorre por conta de apagar mais de 1 pedido?
me parece que o caso está em apagar mais de 1 cliente ao mesmo tempo.
me parece que o caso está em apagar mais de 1 cliente ao mesmo tempo.
GOSTEI 0
Emerson Nascimento
29/11/2006
veja se essa alteração resolve o seu problema:
create trigger ExclusaoCliente on Cliente for delete as begin // variável que guardará o id do cliente declare @id_cliente int // cursor local para varrer os registros deletados. // como pode haver mais de 1 cliente deletado // ao mesmo tempo, esse cursor se faz necessário // para que não apareça a msg informando que // "a alteração afetará mais de 1 registro" declare cursor_cliente cursor local for select Id_Cliente from deleted // abre o cursor open cursor_cliente // posiciona no primeiro registro deletado // e pega seu id fetch next from cursor_cliente into @id_Cliente // enquanto conseguir "rolar" os registros while @@FETCH_STATUS = 0 begin // apaga os pedidos do cliente "selecionado" delete from Pedido where Id_Cliente = @id_cliente // vai para o proximo cliente excluido fetch next from cursor_cliente into @id_Cliente end // fecha o cursor close cursor_cliente end
GOSTEI 0
Athena
29/11/2006
Oi, obrigada pela atenção!
Então, eu apaguei a trigger que eu fiz e criei uma nova com o código que você me passou. Não ocorreu nenhum erro de sintaxe.
Então executei a minha aplicação delphi selecionei um cliente e cliquei em excluir, porém o erro ´Update affected more than 1 records´ persiste.
Você perguntou se eu tenho certeza que estou excluindo apenas um cliente e não vários de uma vez, então tenho sim. O código do botão excluir no delphi está assim:
procedure TfrmPrincipal.btExcluirClick(Sender: TObject);
var
Id_Cliente: Integer;
Consulta: string;
begin
if (conexao.cdsCliente.RecordCount>0) then
begin
if (MessageDlg(´Deseja excluir o registro atual? ´, mtConfirmation, mbYesNoCancel, 0) = mrYes) then
begin
Id_Cliente:=conexao.cdsCliente.FieldByName(´Id_Cliente´).AsInteger;
conexao.cdsCliente.ReadOnly:=False;
conexao.cdsCliente.Filtered:=False;
conexao.cdsCliente.Locate(´Id_Cliente´, Id_Cliente, [loCaseInsensitive]);
conexao.cdsCliente.Delete;
conexao.cdsCliente.ApplyUpdates(0);
conexao.cdsCliente.Filtered:=True;
conexao.cdsCliente.ReadOnly:=True;
end;
end;
end;
Eu posiciono o cursor do grid no registro do cliente que quero apagar e clico no botão excluir.
Obs: O grid está ligado ao ClientDataSet que está ligado com o DataSetProvider que está ligado a uma consulta select simples na tabela
cliente: ´Select * from Cliente´
Só isso mesmo.
Eu, realmente não sei o que pode estar havendo, só se eu pudesse conhecer os bastidores do resultado de uma trigger, talvez se pudesse depurar, algum recurso a mais...
Obrigada!
Então, eu apaguei a trigger que eu fiz e criei uma nova com o código que você me passou. Não ocorreu nenhum erro de sintaxe.
Então executei a minha aplicação delphi selecionei um cliente e cliquei em excluir, porém o erro ´Update affected more than 1 records´ persiste.
Você perguntou se eu tenho certeza que estou excluindo apenas um cliente e não vários de uma vez, então tenho sim. O código do botão excluir no delphi está assim:
procedure TfrmPrincipal.btExcluirClick(Sender: TObject);
var
Id_Cliente: Integer;
Consulta: string;
begin
if (conexao.cdsCliente.RecordCount>0) then
begin
if (MessageDlg(´Deseja excluir o registro atual? ´, mtConfirmation, mbYesNoCancel, 0) = mrYes) then
begin
Id_Cliente:=conexao.cdsCliente.FieldByName(´Id_Cliente´).AsInteger;
conexao.cdsCliente.ReadOnly:=False;
conexao.cdsCliente.Filtered:=False;
conexao.cdsCliente.Locate(´Id_Cliente´, Id_Cliente, [loCaseInsensitive]);
conexao.cdsCliente.Delete;
conexao.cdsCliente.ApplyUpdates(0);
conexao.cdsCliente.Filtered:=True;
conexao.cdsCliente.ReadOnly:=True;
end;
end;
end;
Eu posiciono o cursor do grid no registro do cliente que quero apagar e clico no botão excluir.
Obs: O grid está ligado ao ClientDataSet que está ligado com o DataSetProvider que está ligado a uma consulta select simples na tabela
cliente: ´Select * from Cliente´
Só isso mesmo.
Eu, realmente não sei o que pode estar havendo, só se eu pudesse conhecer os bastidores do resultado de uma trigger, talvez se pudesse depurar, algum recurso a mais...
Obrigada!
GOSTEI 0
Athena
29/11/2006
Olha só, eu descobri o que era depois de mandar a resposta acima:
Quando eu criei minha primeira trigger(semana passada) eu copiei de uma apostila e quando se cria uma nova trigger existe uns códigos existentes, pois é, aí foi meu erro: Eu apaguei tudo e coloquei só o código do exemplo da apostila.
Então agora pouco dei um New Trigger e comecei a ler os códigos preexistente com comentários em inglês. Me atentei para este:
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
Não entendi direito o que quer dizer acima mas achei que tinha alguma coisa haver com prevenção de erros quando a consulta resulta em conjuntos de resultados.
Então ficou assim:
create trigger ExclusaoCliente
on Cliente for delete
AS
BEGIN
SET NOCOUNT ON;
delete from Pedido
where Id_Cliente in (select Id_Cliente from deleted)
END
E agora funcionou!
Obrigada amigo!
Quando eu criei minha primeira trigger(semana passada) eu copiei de uma apostila e quando se cria uma nova trigger existe uns códigos existentes, pois é, aí foi meu erro: Eu apaguei tudo e coloquei só o código do exemplo da apostila.
Então agora pouco dei um New Trigger e comecei a ler os códigos preexistente com comentários em inglês. Me atentei para este:
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;
Não entendi direito o que quer dizer acima mas achei que tinha alguma coisa haver com prevenção de erros quando a consulta resulta em conjuntos de resultados.
Então ficou assim:
create trigger ExclusaoCliente
on Cliente for delete
AS
BEGIN
SET NOCOUNT ON;
delete from Pedido
where Id_Cliente in (select Id_Cliente from deleted)
END
E agora funcionou!
Obrigada amigo!
GOSTEI 0