PAGUE 6 MESES
LEVE 12 MESES
GARANTIR DESCONTO

Fórum Incluir Dinamicamente em tabela #478932

14/05/2014

0

Sempre lidamos em gravar registros e validar os campos (Tipo: CHAR, DATE, NUMBER, VARCHAR2), e se aceita NULL, ou não, Eis uma Package oracle generica para gravar em qualquer tabela. Observar que utilizo o Json por ser mais prático. Chamada:

Dynamic_Insert.Incluir_Registros(<Nome Tabela>, <Objeto Json com os campos>, <Retorno do Erro>);
-- PL/JSON (version 1.0.4)
CREATE OR REPLACE PACKAGE Dynamic_Insert
IS

PROCEDURE ValidaCampo      (Tabela IN VARCHAR2, Campo  IN VARCHAR2,
                            Valor  IN VARCHAR2, Erro  OUT NUMBER);
FUNCTION SString           (Valor  IN VARCHAR2, Coluna IN VARCHAR2)
                           RETURN VARCHAR2;
PROCEDURE Incluir_Registros(Tabela IN VARCHAR2, Obj    IN VARCHAR2,
                            ErroS OUT VARCHAR2);

END;
/


CREATE OR REPLACE PACKAGE BODY Dynamic_Insert
IS

Tipo       VARCHAR2(106);

FUNCTION SString 
       (Valor IN VARCHAR2, Coluna IN VARCHAR2)
       RETURN VARCHAR2
IS

r    VARCHAR2(40) :=NULL;
c    VARCHAR2(1);
n    VARCHAR2(40);

BEGIN

-- Se não Existir Coluna Apenas retorna o to_char
IF (Coluna IS NOT NULL) THEN
    -- Acha os dados do Campo
    BEGIN
      select DISTINCT TRIM(t.DATA_TYPE)
        INTO Tipo
        from user_tab_columns t
       where t.COLUMN_NAME = Coluna;
    EXCEPTION
      WHEN OTHERS THEN
       Tipo:=NULL;
    END;

   -- Modifica o Campo Quando for Numerico
   IF (Tipo = 'NUMBER') THEN
      n:=TO_CHAR(Valor);
      IF (N IS NULL) THEN
         n:='0';
      END IF;
      n:=replace(n,'.',',');
   ELSE
      n:=TO_CHAR(Valor);
   END IF;
ELSE
   n:=TO_CHAR(Valor);
END IF;

 -- Retorna o Campo Convertido
 RETURN n;

END;


PROCEDURE ValidaCampo
       (Tabela IN VARCHAR2, Campo IN VARCHAR2,
        Valor  IN VARCHAR2, Erro  OUT NUMBER)
AS
Obriga     VARCHAR2(1);
TamanhoStr NUMBER;
TamanhoNum NUMBER;
QtdDec     NUMBER;
Data       DATE;
Numero     NUMBER;


BEGIN

-- Acha dados da Tabela
BEGIN
 select t.data_type, t.nullable, t.data_length,
        t.data_precision, t.data_scale
   into Tipo, Obriga, TamanhoStr, TamanhoNum, QtdDec
   from user_tab_columns t
  where t.table_name  = UPPER(Tabela)
    and t.column_name = UPPER(Campo);
EXCEPTION
  WHEN OTHERS THEN
    BEGIN
     Erro:='Campo nao Localizado: '||Campo;
     goto Fim;
    END;
END;

-- Valida Obrigatorio
if (Obriga = 'N') and (Valor IS NULL)then
   Erro:='Campo Obrigatorio: '||Campo;
   goto Fim;
end if;

-- Se Valor for nulo encerra a Critica
if (Valor is null) then
   goto Fim;
end if;

--  Critica Data
begin
if (Tipo = 'DATE') then
   Data:=to_date(Valor);
end if;
exception
 when others then
  begin
   Erro:='Data Invalida: '||Campo;
   goto Fim;
  end;
end;

--  Critica Numero
begin
if (Tipo = 'NUMBER') then
   Numero:=to_number(Valor);
   if (length(Valor) > (TamanhoNum - QtdDec)) then
      Erro:='Valor de Campo Numerico Invalido: '||Campo;
      goto Fim;
   end if;
end if;
exception
 when others then
  begin
   Erro:='Campo Numerico Invalido: '||Campo;
   goto Fim;
  end;
end;

--  Critica Char
begin
if (Tipo = 'CHAR') then
   if (length(Valor) > TamanhoStr) then
      Erro:='Valor de Campo Caracter Invalido: '||Campo;
      goto Fim;
   end if;
end if;
exception
 when others then
  begin
   Erro:='Valor de Campo Caracter Invalido: '||Campo;
   goto Fim;
  end;
end;

--  Critica Varchar2
begin
if (Tipo = 'VARCHAR2') then
   if (length(Valor) > TamanhoStr) then
      Erro:='Valor de Campo Caracter Invalido: '||Campo;
      goto Fim;
   end if;
end if;
exception
 when others then
  begin
   Erro:='Valor de Campo Caracter Invalido: '||Campo;
   goto Fim;
  end;
end;

<<Fim>>

Tipo:=NULL;

END;


PROCEDURE Incluir_Registros 
       (Tabela IN VARCHAR2, Obj IN VARCHAR2, ErroS OUT VARCHAR2)
AS

j_json    json;
Valor     VARCHAR2(4000):=NULL;
sSql      VARCHAR2(2000);
sValue    VARCHAR2(2000);
Erro      VARCHAR2(4000);
vSql      VARCHAR2(4000);
LF        VARCHAR2(2):=CHR(13)||CHR(10);

BEGIN

-- Monta o Sql Inicial
sSql:='INSERT INTO '||TRIM(UPPER(Tabela))||' (';
sValue:='VALUES (';

-- Monta Objeto Json
j_json:=json(Obj);

-- Loop de Validação e Inclusão do Registro
For r in (select t.column_name Campo,
                 t.data_type   Tipo
            from user_tab_columns t
           where t.table_name  = UPPER(Tabela))
 Loop

<<Ler>>

  if (json_ac.object_exist(j_json, r.Campo)) then
     -- Trata o tipo NUMBER para substituir a virgula por ponto
     if (r.Tipo = 'NUMBER') then
        Valor:=SString(json_ext.get_string(j_json, r.Campo), r.Campo);
     else
        Valor:=json_ext.get_string(j_json, r.Campo);
     end if;

     -- Validação Generica do Campo
     ValidaCampo(Tabela, r.Campo, Valor, Erro);

     -- Se Houve Erro Acumula e Volta a Ler
     IF (Erro IS NOT NULL) THEN
        ErroS:=trim(Erro)||LF;
        GOTO Ler;
     END IF;
  ELSE
     GOTO Ler;
  END IF;

  -- Monta o Sql
  sSql:=sSql||r.Campo||',';
  if (r.Tipo IN ('VARCHAR2','CHAR','DATE')) THEN
     sValue:=sValue||''''||Valor||''''||',';
  else
     sValue:=sValue||Valor||',';
  end if;
  
 End Loop;

-- Se Houve Erro Aborta
IF (ErroS IS NOT NULL) THEN
   GOTO Fim;
END IF;

-- Complementa o Sql
sSql:=SUBSTR(sSql,1,length(sSql) - 1)||') ';
sValue:=SUBSTR(sValue,1,length(sValue) - 1)||')';
vSql:=TRIM(sSql)||TRIM(sValue);

-- Executa a Inclusão
BEGIN
 execute immediate vSql;
exception
 when others then
   Erro:=ErroS||LF||SQLERRM;
end;


<<Fim>>

sSql:=NULL;

END;

END;
/

Lourival Queiroz

Lourival Queiroz

Responder

Utilizamos cookies para fornecer uma melhor experiência para nossos usuários, consulte nossa política de privacidade.

Aceitar