Pessoal, parece loucura mas devido a estrutra das tabelas existentes no nosso sistema preciso fazer uma gambiarra assim:
Tenho a tabela funcionarios, onde nessa tabela existe um campo chamado cd_empresa, que identifica a empresa onde o funcionário trabalha.
Possuimos apenas mais de uma razão social, mas a estrutura em si é uma só.
Então para cadastrarmos um funcionário novo o pessoal hoje está cadastrando ele em uma empresa e depois cadastrando o mesmo nas outras duas (são 3 empresas ao todo), pois são feitas configurações diferentes para cada funcionário e por isso não pode ser um cadastro único. Porém como são muitos campos a serem preenchidos esse processo está custando muito tempo.
O que quero é que, ao inserir um novo funcionário (sempre será inserido na empresa 1), essa trigger replique o cadastro copiando esse registro, mudanod apenas a chave primaria (cd_funcionario que é uma sequence) e o campo cd_empresa, para 2 e 3 respectivamente.
To quebrando a cabeça, hehe pois já tentei uma trigger que atualiza a propria tabela, porem me retorna um erro de tabela mutante....
Se alguém tiver uma idéia de que rumo devo tomar....
Obrigado desde já
Trigger para "triplicar" registros ao serem inseri
-
- Moderador
- Mensagens: 1396
- Registrado em: Sex, 01 Fev 2008 2:06 pm
- Localização: Rio de Janeiro - RJ
- Contato:
Sim, na trigger eu tento né, rsrs , fazer um select na tabela onde o registro está sendo inserido, porém ele me retorna erro de tabela mutante.
Possivelmente, se não certamente, pelo fato da table estar sendo alterada e a trigger não ter a visao completa da tabela.
Meu problema é como sair disso, rsrs.
Vlw.
Possivelmente, se não certamente, pelo fato da table estar sendo alterada e a trigger não ter a visao completa da tabela.
Meu problema é como sair disso, rsrs.
Vlw.
-
- Moderador
- Mensagens: 1396
- Registrado em: Sex, 01 Fev 2008 2:06 pm
- Localização: Rio de Janeiro - RJ
- Contato:
a minha pergunta era..
qual dado você precisa buscar via select na tabela?
você não teria esses dados atraves das proprias variaveis da trigger
:NEW ou :OLD ?
qual dado você precisa buscar via select na tabela?
você não teria esses dados atraves das proprias variaveis da trigger
:NEW ou :OLD ?
Como eu preciso duplicar o registro, eu estou pegando todos os campos.a minha pergunta era..
qual dado você precisa buscar via select na tabela?
você não teria esses dados atraves das proprias variaveis da trigger
:NEW ou :OLD ?
select * from funcionario where cd_func = :new.cd_func
Estou empacado nessa parte. Depois que eu conseguir selecionar, eu farei um cursor ou algo parecido para inserir na tabbela esses dados, mudando apenas a cahve primaria onde incrementarei a sequence e informando a empresa, 2 e em seguida 3 no outro registro.
-
- Moderador
- Mensagens: 1396
- Registrado em: Sex, 01 Fev 2008 2:06 pm
- Localização: Rio de Janeiro - RJ
- Contato:
você não tem todos os campos atraves do :NEW ??
dai você não vai precisar do select e então seu insert vai dar certo sem erro mutante
não é simples assim?
dai você não vai precisar do select e então seu insert vai dar certo sem erro mutante
não é simples assim?
Deixa ver se entendi.você não tem todos os campos atraves do :NEW ??
dai você não vai precisar do select e então seu insert vai dar certo sem erro mutante
não é simples assim?
Você está sugerindo que eu insira os dados na tabela utilizando somente o :new?
Tipo assim:
insert into funcionario
values(:new.campo1, :new.campo2, :new.campo3, ....) ??
Isso?
Cara, testei daquela forma ali que postei acima e não obtive sucesso.
Persiste o erro da tabela mutante, agora na linha da inserção.
Acredito que isso deva acontecer porque minha trigger é for each row.
Porém se não for assim eu não tenho mais o :new e :old certo?
Ou eu posso obter os valores de :new e :old sem que a trigger seja for each row?
Persiste o erro da tabela mutante, agora na linha da inserção.
Acredito que isso deva acontecer porque minha trigger é for each row.
Porém se não for assim eu não tenho mais o :new e :old certo?
Ou eu posso obter os valores de :new e :old sem que a trigger seja for each row?
-
- Moderador
- Mensagens: 1396
- Registrado em: Sex, 01 Fev 2008 2:06 pm
- Localização: Rio de Janeiro - RJ
- Contato:
sim..
não funciona?
não funciona?
-
- Moderador
- Mensagens: 1396
- Registrado em: Sex, 01 Fev 2008 2:06 pm
- Localização: Rio de Janeiro - RJ
- Contato:
tendi..
então você vai ter que partir para a solução de mudar a sua trigger para uma instead OF
então você vai ter que partir para a solução de mudar a sua trigger para uma instead OF
não sei como utilizar essas triggers instead of, até já vi mas não compreendi mutio bem a lógica delas?
Você por acaso teria um exemplo?
Você por acaso teria um exemplo?
-
- Rank: DBA Pleno
- Mensagens: 232
- Registrado em: Sex, 30 Mar 2007 7:26 pm
- Localização: Londrina - PR
Rafael O. Genaro
Triggers instead of são válidas apenas para views.
Como no exemplo do tópico que o Victor postou, você pode realizar isto da seguinte forma:
1) Criar uma package com uma plsqltable para armazenar as chaves dos registros que foram inseridos;
2) Criar uma trigger before insert na tabela, limpando a plsqltable (trigger before insert);
3) Criar uma outra trigger sobre a tabela, before insert *para cada linha*, adicionando na plsqltable a chave do registro atual (trigger before insert for each row)
4) Criar uma terceira trigger sobre a tabela, after insert, percorrendo a plsqltable, por fim executando o código de sua trigger atual para cada registro recuperado.
Dá uma olhada novamente no tópico, pois o exemplo que o fsitja postou lá (no 7º post do tópico) atende perfeitamente a sua situação.
Como no exemplo do tópico que o Victor postou, você pode realizar isto da seguinte forma:
1) Criar uma package com uma plsqltable para armazenar as chaves dos registros que foram inseridos;
2) Criar uma trigger before insert na tabela, limpando a plsqltable (trigger before insert);
3) Criar uma outra trigger sobre a tabela, before insert *para cada linha*, adicionando na plsqltable a chave do registro atual (trigger before insert for each row)
4) Criar uma terceira trigger sobre a tabela, after insert, percorrendo a plsqltable, por fim executando o código de sua trigger atual para cada registro recuperado.
Dá uma olhada novamente no tópico, pois o exemplo que o fsitja postou lá (no 7º post do tópico) atende perfeitamente a sua situação.
Bom dia, desculpe a demora, mas só hoje retomei isso, rsrs...
Estive vendo outros casos e achei mais simples criar uma tabela temporária na trigger.
Com isso terei duas triggers.
A triger for each row armazena o rowid da linha que foi inserida.
E a after statement insere nessa mesma tabela os dados onde o rowid = ao rowid salvo na temoraria.
Ao fim disso limpo a tabela temporária.
Mas vlw pela ajuda.
Abraço.
Estive vendo outros casos e achei mais simples criar uma tabela temporária na trigger.
Com isso terei duas triggers.
A triger for each row armazena o rowid da linha que foi inserida.
E a after statement insere nessa mesma tabela os dados onde o rowid = ao rowid salvo na temoraria.
Ao fim disso limpo a tabela temporária.
Mas vlw pela ajuda.
Abraço.
- fsitja
- Rank: OraSauro
- Mensagens: 611
- Registrado em: Seg, 19 Jan 2009 4:29 pm
- Localização: Gaúcho no Rio de Janeiro - RJ
"The scars exist to remind us that the past was real"
Campanha: Como fazer uma pergunta e obter uma resposta.
http://tkyte.blogspot.com/2005/06/how-t ... tions.html
OCA & OCP Developer — OCE SQL Expert — OCS Data Warehousing Specialist
Campanha: Como fazer uma pergunta e obter uma resposta.
http://tkyte.blogspot.com/2005/06/how-t ... tions.html
OCA & OCP Developer — OCE SQL Expert — OCS Data Warehousing Specialist
Olá,
Não sei exatamente como você implementou, mas acho que pode dar erro se dois usuários de forma simultânea tentarem executar o processo, pois a tabela temporária vai estar sendo usada pelos dois ao mesmo tempo.
Não sei exatamente como você implementou, mas acho que pode dar erro se dois usuários de forma simultânea tentarem executar o processo, pois a tabela temporária vai estar sendo usada pelos dois ao mesmo tempo.
fsitja, realmente não previ isso.
Funcionou até agora porque geralmente há apenas um usuário alterando a tabela.
O processo todo em si leva cerca de 0.1s, e não temos muitos usuarios na base, mas mesmo assim não é?, uma hora pode acontecer.
Há alguma forma de bloquear a tabela durante o processo?
de forma que não seja possivel realizar alterações na mesma enquanto esse processo de duplicação não for encerrado?
Vlw pela dica.
Funcionou até agora porque geralmente há apenas um usuário alterando a tabela.
O processo todo em si leva cerca de 0.1s, e não temos muitos usuarios na base, mas mesmo assim não é?, uma hora pode acontecer.
Há alguma forma de bloquear a tabela durante o processo?
de forma que não seja possivel realizar alterações na mesma enquanto esse processo de duplicação não for encerrado?
Vlw pela dica.
- fsitja
- Rank: OraSauro
- Mensagens: 611
- Registrado em: Seg, 19 Jan 2009 4:29 pm
- Localização: Gaúcho no Rio de Janeiro - RJ
"The scars exist to remind us that the past was real"
Campanha: Como fazer uma pergunta e obter uma resposta.
http://tkyte.blogspot.com/2005/06/how-t ... tions.html
OCA & OCP Developer — OCE SQL Expert — OCS Data Warehousing Specialist
Campanha: Como fazer uma pergunta e obter uma resposta.
http://tkyte.blogspot.com/2005/06/how-t ... tions.html
OCA & OCP Developer — OCE SQL Expert — OCS Data Warehousing Specialist
Se seu ambiente possui pouca concorrência de usuários, não deve ser um problema "serializar" o acesso à tabela, usando um LOCK TABLE em modo exclusivo.
Nesse caso, o primeiro usuário que chegar (mesmo que seja por 0.000001 seg) bloqueia a tabela, e o próximo é forçado a esperar pelo commit ou rollback dele para utilizá-la. Nesse caso você faria o commit apenas após limpar a tabela temporária. A intenção é que o segundo usuário não leia a "sujeira" do primeiro usuário e acabe replicando dados que não são seus.
http://download.oracle.com/docs/cd/E118 ... s_9015.htm
Nesse caso, o primeiro usuário que chegar (mesmo que seja por 0.000001 seg) bloqueia a tabela, e o próximo é forçado a esperar pelo commit ou rollback dele para utilizá-la. Nesse caso você faria o commit apenas após limpar a tabela temporária. A intenção é que o segundo usuário não leia a "sujeira" do primeiro usuário e acabe replicando dados que não são seus.
LOCK TABLE tab_temporaria IN EXCLUSIVE MODE;
Vlw, consegui.
Claro que por haver pouca concorrência não mudou nada aparentemente, mas com isso já será possivel eliminar esse erro.
Obrigado.
Claro que por haver pouca concorrência não mudou nada aparentemente, mas com isso já será possivel eliminar esse erro.
Obrigado.
-
- Rank: Estagiário Sênior
- Mensagens: 9
- Registrado em: Ter, 28 Set 2010 3:23 pm
- Localização: Serra-ES
Eu iria sugerir uma mudança um pouco mais radical. Já que cada funcionário precisará ser cadastrado nas 3 empresas. porque não criar uma nova tabela EMPRESA_FUNC, assim toda vez que cadastrar um funcionário na tabela funcionário, você só precisaria informar quais as empresas que este trabalhará. Hoje sua empresa tem 3 "filiais" e cada funcionário obrigatoriamente trabalha nas 3, mas se mudar a quantidade de empresas ou a obrigatoriedade de 3, você terá que alterar o trigger, dessa forma que estou sugerindo não.
Exemplificando.
EMPRESA -> EMPRESA_FUNC <- FUNC
um vinculo n para n.
Qualquer dúvida de como fazer isso, pode postar.
Abraços
Exemplificando.
EMPRESA -> EMPRESA_FUNC <- FUNC
um vinculo n para n.
Qualquer dúvida de como fazer isso, pode postar.
Abraços
É que na verdade eu tenoh acesso somente ao banco de dados e não aos fontes do software.
Compramos esse software de gestao aqui para a empresa e para solicitarmos a troca, além de a diretoria achar caro o valor de implementação, é muito demorado o processo, até termos um retorno.
Ralmente essa seria a melhor opção, mas a estrutura atual do sitema não me permite isso.
MAs obrigado pela dica mesmo assim, vlw.
Compramos esse software de gestao aqui para a empresa e para solicitarmos a troca, além de a diretoria achar caro o valor de implementação, é muito demorado o processo, até termos um retorno.
Ralmente essa seria a melhor opção, mas a estrutura atual do sitema não me permite isso.
MAs obrigado pela dica mesmo assim, vlw.
-
- Informação
-
Quem está online
Usuários navegando neste fórum: Nenhum usuário registrado e 1 visitante