Fórum Problema para gerar um exception em uma trigger? #58396
13/06/2007
0
Olhe a trigger
CREATE TRIGGER RESTRUCAO FOR FOLHA ACTIVE BEFORE INSERT POSITION 0 AS begin /* Trigger text */ if ( Exists(Select * from folha WHERE id_sal = NEW.id_sal and funcionario = new.funcionario and data = new.data and descricao = new.descricao and valor = new.valor and P_D = new.P_D ) ) then Exception RESTRICAO ´Atenção Usuário!!! Dados já consta cadastrado no Banco de Dados!´; end
O que esta errado nesta trigger?
Queria fazer uma unique mais nao estou conseguindo
Fiz assim a unique
alter table FOLHA add constraint UNQ1_FOLHA unique (ID_SAL,FUNCIONARIO,DATA,DESCRICAO,VALOR,P_D)
Mais acusa o seguinte erro
[color=red:8843f2a55f]Invalid insert or update value(s): object columns are
constrained - no 2 table rows can have duplicate column values.
attempt to store duplicate value (visible to active transactions) in unique index ´UNQ1_FOLHA´.
[/color:8843f2a55f]
Por isso fiz uma trigger
Estou usando firebird 2.0
Adriano_servitec
Curtir tópico
+ 0Posts
13/06/2007
Adriano_servitec
procedure TFcalculo.BTrasnportarDadosClick(Sender: TObject); var ibx : integer; begin dm.qHolerith.close; dm.qHolerith.SQL.Clear; dm.qHolerith.SQL.Add(´Select select * from holerith A where Exists(select * from holerith B where B.id_sal = A.id_sal and B.funcionario = A.funcionario and B.data = A.data and B.descricao = A.descricao)´); dm.qHolerith.open; if dm.qHolerith.Bof and dm.qHolerith.Eof Then showmessage(´Atenção Usuário! Dados já cadastrados´) else For ibx :=0 to m3.Items.Count-1 do //começo for listbox1 begin dm.qHolerith.Append; dm.qHolerith.fieldByName(´id_sal´).value:=dm.qfuncionariosid_sal.Value; dm.qHolerith.fieldByName(´funcionario´).AsString:=dm.qfuncionariosnome.asString; dm.qHolerith.fieldByName(´data´).AsString:=mdata.Text; dm.qHolerith.fieldByName(´id_formula´).value:=lb1.Items[ibx]; dm.qHolerith.fieldByName(´descricao´).AsString := m3.Items[ibx]; dm.qHolerith.fieldByName(´valor´).AsString := m2.Items[ibx]; dm.qHolerith.Post; end; //final do for listbox1 For ibx :=0 to lb2.Items.Count-1 do //começo for listbox2 begin dm.qHolerith.Append; dm.qHolerith.fieldByName(´id_sal´).value:=dm.qfuncionariosid_sal.Value; dm.qHolerith.fieldByName(´funcionario´).AsString:=dm.qfuncionariosnome.asString; dm.qHolerith.fieldByName(´data´).AsString:=mdata.Text; dm.qHolerith.fieldByName(´id_formula´).value:=lb2.Items[ibx]; dm.qHolerith.fieldByName(´descricao´).AsString := d1.Items[ibx]; dm.qHolerith.fieldByName(´valor´).AsString := d3.Items[ibx]; dm.qHolerith.Post; end; //final do for do listbox2 end;
Ou seja se ja tiver no banco de dados nao grava, grava apenas os que nao tem no banco de dados, entao resolvi unir a mesma tabela em dois selects com a funçao EXISTS, mais esta acusando erro na SQL.
Tambem fiz um teste na propriedade SQL do Query assim
select * from holerith A where exists(select * from holerith B where B.id_sal = A.id_sal and B.funcionario = A.funcionario and B.data = A.data and B.descricao = A.descricao)
E consegui ativar esta query, mais preciso que seja feito diretamente na unit e nao na propriedade SQL do Query.
Gostei + 0
14/06/2007
Emerson Nascimento
alter table FOLHA add constraint UNQ1_FOLHA unique (ID_SAL,FUNCIONARIO,DATA,DESCRICAO,VALOR,P_D)
Você não consegue criar a trigger porque já há valores duplicados na tabela. Exclua as duplicidades e tente criar a unique novamente.
Gostei + 0
14/06/2007
Adriano_servitec
Explico:
Tenho listbox que vao jogar valores para a tabela, entao se a unique estiver ativa, nao vai deixar repetir dados, no caso preciso excluir os dados para jogar os novos dados, por isso estou querendo fazer do jeito que mostei acima.
Entao achei o correto fazer assim, mais nao estou conseguindo.
[b:ac9f71d888]Obs. Esse delete fiz a zoio, mais a ideia seria deletar conforme a condiçao where para nao excluir os demais que nao seja aquele.[/b:ac9f71d888]
Obrigado pela ajuda.
Gostei + 0
14/06/2007
Adriano_servitec
Olhem como estava antes
Olhem o correto
dm.qHolerith.close; dm.qHolerith.SQL.Clear; dm.qHolerith.SQL.Add(´select * from holerith where Exists(select * from holerith B where B.id_sal = id_sal and B.funcionario = funcionario and B.data = data and B.descricao = descricao)´); dm.qHolerith.open;
Erro no script do SQL :oops:
Gostei + 0
14/06/2007
Adriano_servitec
SET TERM ^ ; CREATE PROCEDURE UPD_INS_HOLERITH ( id_sal integer, funcionario varchar(70), data date, descricao varchar(60), valor numeric(15,2), p_d char(1)) as begin if (exists( select id_sal, funcionario, data, descricao, valor, p_d from holerith where (id_sal = :id_sal and funcionario = :funcionario and data = :data and descricao = :descricao and valor = :valor and p_d = :p_d) )) then update holerith set funcionario = :funcionario, data = :data, descricao = :descricao, valor = :valor, p_d = :p_d where (id_sal=:id_sal); else insert into holerith ( id_sal, funcionario, data, descricao, valor, p_d) values ( GEN_ID(gen_holerith_id,1), :funcionario, :data, :descricao, :valor, :p_d); end^ SET TERM ; ^ GRANT SELECT,INSERT,UPDATE ON HOLERITH TO PROCEDURE UPD_INS_HOLERITH; GRANT EXECUTE ON PROCEDURE UPD_INS_HOLERITH TO SYSDBA;
Mais ao passar a SP pelo componente StoredProc, verifiquei na tabela e nada, continua repetindo os dados.
procedure TFcalculo.Button19Click(Sender: TObject); var ibx :integer; begin For ibx :=0 to m3.Items.Count-1 do //começo for listbox1 begin dm.spInsUpdHol.Close; dm.spInsUpdHol.Params[0].Value := dm.qfuncionariosid_sal.Value; dm.spInsUpdHol.Params[1].Value := dm.qfuncionariosnome.asString; dm.spInsUpdHol.Params[2].Value := mdata.Text; dm.spInsUpdHol.Params[3].Value := m3.Items[ibx]; dm.spInsUpdHol.Params[4].Value := m2.Items[ibx]; dm.spInsUpdHol.Params[5].Value := ´P´; dm.spInsUpdHol.ExecProc; end; For ibx :=0 to d1.Items.Count-1 do //começo for listbox2 begin dm.spInsUpdHol.Close; dm.spInsUpdHol.Params[0].Value := dm.qfuncionariosid_sal.Value; dm.spInsUpdHol.Params[1].Value := dm.qfuncionariosnome.asString; dm.spInsUpdHol.Params[2].Value := mdata.Text; dm.spInsUpdHol.Params[3].Value := d1.Items[ibx]; dm.spInsUpdHol.Params[4].Value := d3.Items[ibx]; dm.spInsUpdHol.Params[5].Value := ´D´; dm.spInsUpdHol.ExecProc; end; end;
Sera que eh por causa que estou jogando os valores de listbox para o banco de dados? Pq as vezes sao mais de um valor soh que o campo ID_SAL eh o que uso para fazer o update, mais nao posso deixa-lo como PK pois vai reperir esse campo varias vezes na tabela
Exemplo
id_sal----------funcionario----------data--------descricao----valor----pd
1---------------adriano---------------31/05/07--salario------1.000,00--p
1---------------adriano---------------31/05/07--inss------------80,00---d
2---------------pedro-----------------31/05/07--salario--------600,00--p
2---------------pedro-----------------30/06/07--salario--------600,00--p
...
...
Entao, se eu quiser arrumar o funcionario adriano no mes 31/05/07 deve fazer um update dos dados, e nao esta fazendo isso e sim repetindo os valores e jogando na tabela.
Pois acho eu que o correto seria uma SP, assim ao selecionar os dados da tabela ele pode tanto fazer um update se ja tiver na tabela ou incluir dados novos caso nao tenha.
Alguem pode me ajudar?
Grato
Adriano.
Gostei + 0
14/06/2007
Emerson Nascimento
select id_sal, funcionario, data, descricao, valor, p_d from holerith where (id_sal = :id_sal and funcionario = :funcionario and data = :data and descricao = :descricao and valor = :valor and p_d = :p_d)
com os parâmetros passados na stored procedure, há resultset?
Gostei + 0
14/06/2007
Adriano_servitec
O correto deste SP ficou assim
SET TERM ^ ; CREATE PROCEDURE UPD_INS_HOLERITH ( id_sal integer, funcionario varchar(70), data date, descricao varchar(60), valor numeric(15,2), p_d char(1)) as begin if (exists( select id_sal, funcionario, data, descricao, valor, p_d from holerith where (id_sal = :id_sal and funcionario = :funcionario and data = :data and descricao = :descricao) )) then update holerith set id_sal = :id_sal, funcionario = :funcionario, data = :data, descricao = :descricao, valor = :valor, p_d = :p_d where (id_sal = :id_sal and funcionario = :funcionario and data = :data and descricao = :descricao); else insert into holerith ( id_sal, funcionario, data, descricao, valor, p_d) values ( :id_sal, :funcionario, :data, :descricao, :valor, :p_d); end^ SET TERM ; ^ GRANT SELECT,INSERT,UPDATE ON HOLERITH TO PROCEDURE UPD_INS_HOLERITH; GRANT EXECUTE ON PROCEDURE UPD_INS_HOLERITH TO SYSDBA;
Agora esta funcionando corretamente, bom assim espero, pelo menos nos testes que fiz aqui.
:D
Valeu
Obrigado amigo.
Gostei + 0
Clique aqui para fazer login e interagir na Comunidade :)