Array
(
)

Trigger: No disparo, ocorre erro na aplicação!

Athena
   - 29 nov 2006

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)!

Emerson
   - 30 nov 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.

Emerson
   - 30 nov 2006

veja se essa alteração resolve o seu problema:
#Código

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


Athena
   - 30 nov 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!

Athena
   - 30 nov 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!