Jump to content
Vinicius Dezem

IF se existe na tabela

Recommended Posts

Boa tarde pessoa,

 

Estou com o seguinte problema : 

 

Tenho uma trigger com IF e nele preciso verificar se o new.campo existe em outra tabela para executar o insert

 

Da seguinte forma :

  IF( :new.tpfis=6 or :new.icard in (select titular from controle_aux))then
  insert into telessvr.controle_aux
  values
    (:new.icard,
     :new.titular,
     :new.grupo,
     :new.grupo1,
     :new.grupo2,
     :new.grupo3,
     :new.grupo_sab,
     :new.grupo_dom,
     :new.grupo_fer);
end if;

Porem sei que dessa forma não é possível fazer, como poderia estar fazendo esta checagem ?

Procurei por cursor ou array, porem não consegui entender muito bem como funciona.

 

Obrigado desde já.

 

 

Share this post


Link to post
Share on other sites

Use a tabela de Metadata DBA_TAB_COLUMNS , requer GRANT , se a tabela e do próprio OWNER (user) pode ser usada a USER_TAB_COLUMNS

 

https://docs.oracle.com/cd/B19306_01/server.102/b14237/statviews_4146.htm#REFRN23277

 

Um exemplo com ALL_TAB_COLUMNS (outro sinônimo)

 

https://dba.stackexchange.com/questions/93137/oracle-alter-column-if-exists

 

Share this post


Link to post
Share on other sites

Bom dia Motta, obrigado pela resposta vou ver com o metodo que você falou.

 

Eu "consegui" fazer mas com um cursor .. porem chega uma hora que ele se embaralha e a tabela fica enorme.

 

Trigger criada : ela alimenta o que foi inserido na tabela controle para a tabela controle_aux, porem apenas se ela atender as condições do IF :

create or replace trigger titular
  after insert or update on telessvr.controle
  for each row
declare
  --v_titular integer;

  CURSOR c_titular IS
    select titular from controle_aux where titular is not null;
  /* DECLARANDO A VARIAVEL QUE RECEBERÁ OS REGISTROS DA TABELA */
  r_tit char(12);

begin
 
  /*ABRE CURSOR*/
  OPEN c_titular;
  LOOP
    /*LÊ UM REGISTRO DO CURSOR*/
    FETCH c_titular
      into r_tit;
    /* SAI DO LOOP CASO SEJA O FINAL DO CURSOR */

    IF (:new.tpfis = 6 or :new.icard IN (r_tit)) then
      insert into telessvr.controle_aux
      values
        (:new.icard,
         :new.titular,
         :new.grupo,
         :new.grupo1,
         :new.grupo2,
         :new.grupo3,
         :new.grupo_sab,
         :new.grupo_dom,
         :new.grupo_fer);
    end if;
    EXIT WHEN c_titular%NOTFOUND;
  END LOOP;

  /* FECHA O CURSOR */

  CLOSE C_titular;
 
  
END;

SE eu tentar fazer uma trigger para atualizar a controle de volta, irá dar erro de tabela mutante, resolvi criar uma procedure que irá rodar a cada alguns segundos  "interval : (sysdate)+0,05/(1440)" ..

 

CREATE OR REPLACE PROCEDURE SP_PERMPROVISORIO IS

vicard            telessvr.controle.icard%type;
vtitular          telessvr.controle.titular%type;
vgrupo            telessvr.controle.grupo%type;
vgrupo1           telessvr.controle.grupo1%type;
vgrupo2           telessvr.controle.grupo2%type;
vgrupo3           telessvr.controle.grupo3%type;
vgrupo_sab        telessvr.controle.grupo_sab%type;
vgrupo_dom        telessvr.controle.grupo_dom%type;
vgrupo_fer        telessvr.controle.grupo_fer%type;
vcontador         integer;
 
BEGIN
      SELECT COUNT(*) INTO VCONTADOR FROM CONTROLE_AUX;
    dbms_output.put_line('CONTADOR: ' || vcontador);

                              dbms_output.put_line('vicard : ' || vicard);
                              dbms_output.put_line('vtitular : ' || vtitular);
                              dbms_output.put_line('vgrupo : ' || vgrupo);
                              dbms_output.put_line('vgrupo1 : ' || vgrupo1);
                              dbms_output.put_line('vgrupo2 : ' || vgrupo2);
                              dbms_output.put_line('vgrupo3 : ' || vgrupo3);
                              dbms_output.put_line('vgrupo_sab : ' || vgrupo_sab);
                              dbms_output.put_line('vgrupo_dom : ' || vgrupo_dom);
                              dbms_output.put_line('vgrupo_fer : ' || vgrupo_fer);

    IF(vcontador > 0) then
      SELECT A.ICARD,
             B.ICARD,
             B.GRUPO,
             B.GRUPO1,
             B.GRUPO2,
             B.GRUPO3,
             B.GRUPO_SAB,
             B.GRUPO_DOM,
             B.GRUPO_FER
        INTO vicard,
             vtitular,
             vgrupo,
             vgrupo1,
             vgrupo2,
             vgrupo3,
             vgrupo_sab,
             vgrupo_dom,
             vgrupo_fer
        FROM TELESSVR.CONTROLE_AUX A
       INNER JOIN CONTROLE_AUX B ON A.TITULAR = B.ICARD
       WHERE ROWNUM = 1;

    END IF;

        UPDATE CONTROLE
           SET grupo     = vgrupo,
               grupo1    = vgrupo1,
               grupo2    = vgrupo2,
               grupo3    = vgrupo3,
               grupo_sab = vgrupo_sab,
               grupo_dom = vgrupo_dom,
               grupo_fer = vgrupo_fer
         WHERE ICARD = VICARD;

        COMMIT;
        
        DELETE FROM CONTROLE_AUX WHERE ICARD= VICARD OR icard = vtitular;
        
        COMMIT;
END;

 

Quando é inserido na controle as outras trigger atualizam duas vezes nela que gera 2 registros na controle_aux: (3 por causa desse if, não sei o porque)

 

image.png.64389862e75a4683381928a454bb7ff4.png

 

Eu preciso atualizar o ICARD na controle os valores das colunas grupos do numero vinculado pelo TITULAR (onde é igual do icard da segunda linha), para que os dois fiquem iguais.

Desse forma que eu fiz, onde eu errei ? ou esse realmente não é um método recomendado ?

 

Obrigado

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Similar Content

    • By Pedro Vinicius Miguel Dias
      Pessoal, estou estudando o Banco de Dados Oracle e estou tendo um problema pra criar uma nova conexão.
      Durante o curso, o instrutor pede que eu crie duas conexoes, a TESTE com a senha: teste e a PRATICA com a senha :pratica... cada uma com uma senha e etc e elas funcionam.
      Eu por minha conta quis criar outra conexão com outro nome e outra senha, Ex. (User TESTE2 e senha: teste2) e ao testar, o Banco não conecta. Erro ORA-01017.
       
      Alguém consegue me ajudar?
    • By Matsuura
      Estou tentando criar o usuário o Scott, e na internet encontro bastante tutoriais para instalação do HR, para o scott dois que me referenciei foram:
      https://www.profissionaloracle.com.br/swillians/forums/topic/usuario-scott-tiger-banco-oracle-10g-express-edition-xe/
      https://docs.oracle.com/database/121/COMSC/installation.htm#COMSC00007
       
      no primeiro link que tentei seguir não encontrei após a intalação o arquivo "demobld.sql"estou enviando a imagem com nome "sql1" e "sql2" que mostram a minha tentativa de instalação, com as mensagens de erros que me retornaram, no segundo link mostra as instalações de schemas, mas não mostra especificamente o Scott. 
      Espero que possam me ajudar, estou a mais de duas semanas tentando sem exito.


    • By NaPraia
      Buenas,
       
      alguém já gerou arquivo em pdf?
       
      eu já usei utl_file e text_io para gerar excel mas para pdf não sei se dá, sabem?
      tenho pesquisado e falam do BI Publisher, já usaram?
    • By Mvc
      Olá,
      Gostaria de fazer uma query mas o retorno ou vem ou não vem dados. Vou citar exemplos.
       
      Me ajudem PF se o melhor caso é union ou outro?
       
      1) Tabela 1 e tabela 2 com campos distintos e um campo em comum com Join no campo card.
      Resultado: No meu select qdo tem dados nas 2 tabelas então retornam todos em comum em uma única linha.
       
      Tabela 1(id, card)
      1, xxx
      2, yyy
      3, zzz
      Tabela 2 (id, card, fraude)
      1, xxx, sim 
      2, yyy, sim
      3, zzz, pendente
       
      Select a.id, a.card, b.card, b.fraude
      from t1 a,t2 b
      where  a.card=b.card;
       
      Retorno:
      Id,Card,Card,fraude
      1, xxx,xxx,sim
      2, yyy,yyy,sim
      3, zzz,zzz,pendente
       
      O problema é qdo na tabela 2 não tem o dado:
      2)Tabela 1 e tabela 2 com campos distintos e um campo em comum com Join no campo card.
      Resultado: No meu select qdo tem dados na tabela 1 e não tiver dado na tabela 2 então retornam linha que só tem na tabela 1.
       
       
      Tabela 1(id, card)
      1, xxx
      2, yyy
      3, zzz
      4,xyz
       
      Tabela 2 (id, card, fraude)
      1, xxx, sim 
      2, yyy, sim
      3, zzz, pendente
       
      Select a.id, a.card, b.card, b.fraude
      from t1 a,t2 b
      where  a.card=b.card;
       
      Retorno:
      Id,Card,Card,fraude
      Nenhuma linha
      Ou não estou certo, retorna igual ao exemplo1:
      1, xxx,xxx,sim
      2, yyy,yyy,sim
      3, zzz,zzz,pendente
       
      Pergunto, neste exemplo 2 como faço pra retornar somente todas as linhas e se não tiver a linha na tabela 2 ficar com estes campos null? 
       
      Desta forma;
       
      Retorno:
      Id,Card,Card,fraude
      1, xxx,xxx,sim
      2, yyy,yyy,sim
      3, zzz,zzz,pendente
      4,xyz,null,null
      Ou no lugar de null, ficar vazia as colunas REF a tabela 2.
       
      Na vdd são exemplos, mas a qtd de Join é mais complexos
      Muito obrigado!!!!
       
       
       
       
    • By NaPraia
      buenas
       
      no sistema eu tenho uma tabela A com um campo que é do tipo NUMBER
      um outro sistema, tem uma tabela B que se relaciona com esse campo da tabela A, é que é do tipo NUMBER(19,2)
      Se relacionam corretamente mas não foi possível criar a constraint de FK
       
      não estou pensando em alter table pois pode gerar um caos no sistema
       
      verificar por trigger se já existe?
       
      obrigado
×

Important Information

Ao usar o fórum, você concorda com nossos Terms of Use.