Ir para conteúdo

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

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á.

 

 

Compartilhar este post


Link para o post
Compartilhar em outros 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

 

Compartilhar este post


Link para o post
Compartilhar em outros 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

Compartilhar este post


Link para o post
Compartilhar em outros sites

  • Conteúdo Similar

    • Por mateus.andriollo
      Existe uma forma de fazer um IF na select e comparar com Array de dados?
       
      algo como
       
      Select if( in_array(idCliente,'1,2,3,4,5')=true,'Tem','Não') ) as cliente Não consigo usar inner ou where pois esse array é algo q tem varias regras...
       
      Precisava saber se existe uma função assim em MySQL
    • Por mateus.andriollo
      Existe uma forma de fazer um IF na select e comparar com Array de dados?
       
      algo como
       
      Select if( in_array(idCliente,'1,2,3,4,5')=true,'Tem','Não') ) as cliente Não consigo usar inner ou where pois esse resultado do array é algo q tem varias regras...
       
      Precisava saber se existe uma função assim em MySQL
    • Por Rodrigo Bigas
      Olá colegas, 
      Desenvolvi um sistema simples de boletim escolar. Conforme os dados são inseridos nas textfields ao clicar no botão Resultado, deverá mostrar em uma JTable. O problema é que a última coluna (resultado) da JTable tem que estar dentro de uma condição if/else para setar se o aluno está "aprovado", "em recuperação" ou "reprovado conforme a condição". Estou com dificuldades em descobrir qual é o método correto que seta este resultado de forma dinâmica. Segue os prints:
       
      Conforme o código e o print acima, o sistema funciona somente para a primeira linha, porque está setando de forma estática, obtendo os valores do índice e coluna, qual seria o método para setar o valor de forma dinâmica do índice e coluna?
    • Por dfoliveira82
      Bom dia senhores,
       
      sou novo no Oracle, antes trabalhava com SQL SERVER, e me deparei com algo que ja estou a horas tentando solucionar mas nao consegui.
      Nessa Trigger que vou postar, quando mando compilar ela, fala que esta faltando uma virgula, apos o values, mas nao precisa dela e nao acho onde pode ser essa virgula faltante.
      CREATE OR REPLACE TRIGGER JOBS_CL_INSERE_USUARIO AFTER INSERT OR UPDATE OF EXPORTADA_AVA ON SITE_USUARIOS REFERENCING NEW AS NEW BEGIN INSERT INTO BLACKBEAN.TBL_USERS VALUES (NULL, 'INSERT', NULL, 'db', '0', '0', '0', TO_CHAR(:NEW.CPF), MD5(:NEW.CPF||'port@l'), TO_CHAR(:NEW.CPF), SUBSTRING(:NEW.NOME, 1, INSTR(:NEW.NOME, ' ')-1), SUBSTRING(:NEW.NOME, INSTR(:NEW.NOME, ' ')+1, LEN(:NEW.NOME)), 'email@email.com', NULL, NULL, DATE_TO_UNIX_TS(SYSDATE), NULL, NULL); END; / Se alguem puder me ajudar agradeceria.
    • Por asacap1000
      Olá galera estou quebrando a cabeça aqui e não sei mais o que fazer. Estamos migrando nossa intranet que estava desatualizada demais e estamos colocando toda ela em php7.3.
      Dentro desse sistema temos varias consultas que são realizadas no Oracle. As consultas estão ocorrendo 100% mas ao chegar na plataforma de relatórios travou tudo. Não consegui acertar o meio de consultar por período, já utilizei "to_date, to_char, trunc" e nada. Interessante que no PLSQL o to_date funciona certo
      SELECT DISTINCT TO_DATE(IO.TIME_ARRIVAL)
        FROM IN_OUT IO
       WHERE TO_DATE(IO.TIME_ARRIVAL) BETWEEN '01/11/2021' AND '23/11/2021'
       
      1    04/11/2021
      2    18/11/2021
      3    17/11/2021
      4    14/11/2021
      5    22/11/2021
      6    08/11/2021
      7    11/11/2021
      8    13/11/2021
      9    09/11/2021
      10    10/11/2021
      11    05/11/2021
      12    19/11/2021
      13    15/11/2021
      14    03/11/2021
      15    06/11/2021
      16    23/11/2021
      17    01/11/2021
      18    02/11/2021
      19    16/11/2021
      20    20/11/2021
      21    12/11/2021
      22    21/11/2021
       
      Se eu utilizar ele ignora a data que estabeleci para a consulta
       TO_CHAR(IO.TIME_ARRIVAL,'DD/MM/YYYY') BETWEEN '01/11/2021' AND '23/11/2021'
       
      1    03/07/2013
      2    05/07/2013
      3    18/06/2013
      4    21/05/2013
      5    20/05/2013
      6    12/08/2013
      7    21/08/2013
      8    23/08/2013
      9    02/09/2013
      10    12/09/2013
       
      Isso no PLSQL, no caso do PHP o to_date não funciona nem gera o relatório, e no to_char funciona mas ignorando as datas apontadas.
       
      O que dá pra  fazer pra resolver isso, tenho que finalizar essa migração até final de Dezembro e estou começando a ficar preocupado com o tempo
       
      Agradeço qualquer ajuda que vier
×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.