O documento discute tipos de dados em PL/SQL, incluindo escalares como números, caracteres e datas, além de compostos como registros e objetos. Ele também apresenta uma refatoração de uma package que detecta fraudes para melhorar o uso de tipos, com a introdução de subtipos para CPF e período.
2. Tipos de Dados
● Constantes, Variáveis, Parâmetros
● Necessitam da definição de um tipo
○ Formato de armazenamento
○ Valores válidos
○ Operações permitidas
○ Entendimento do negócio a ser implementado
● PL/SQL
○ Escalar
○ Composto
3. Tipo de Dado Escalar
● Armazenam valores únicos
● Quatro grupos
○ Numérico
○ Caractere
○ Booleano
○ Data
● Utilizam tipos de dados comuns, nativos do SQL (Oracle)
○ NUMBER
○ VARCHAR2
○ DATE
● Tipos exclusivos do PL/SQL
○ BOOLEAN
○ PLS_INTEGER
4. Tipo de Dado Escalar
● Numérico
○ Aplicado para números reais, inteiros, ponto flutuante
○ NUMBER, INTEGER, FLOAT, DOUBLE, PLS_INTEGER
● Caractere
○ Valores alfanuméricos
○ CHAR, VARCHAR2, ROWID
● Booleano
○ Operações lógicas em IFs, Cases, Loops
○ True, False, Null
● Data
○ Representação de Datas, Data e Hora, Intervalos
○ DATE, TIMESTAMP, INTERVAL
5. Tipo de Dado Escalar
● Subtipos nativos
○ Tipo de dado que é subconjunto de um outro tipo
○ NUMBER
■ DECIMAL, FLOAT, INTEGER
○ PLS_INTEGER
■ POSITIVE, SIGNTYPE, SIMPLE_INTEGER
● Subtipo próprio a partir de um tipo
○ Gera melhor entendimento do negócio
○ Implementação mais legível
6. Tipo de Dado Composto
● ROWTYPE
○ Registro definido a partir de uma tabela, visão ou cursor
● Record Type (PL/SQL)
○ Registro definido com campos de vários tipos
○ Escopo de bloco PL/SQL
● Object Type (SQL)
○ Escopo do banco de dados
○ Reconhecido no SQL, por exemplo, pode ser uma coluna de uma tabela
○ Orientação a Objetos no PL/SQL
● Collection
○ Listas populadas com registros
○ Não será o foco de hoje
7. Cenário de Exemplo
● Implementar solução para detectar fraudes
○ Criar package
■ Definir métodos, parâmetros e retornos
■ Verificar tipos de dados utilizados
○ Refatorar código
■ Utilizar novos tipos para dar clareza ao código
■ Evidenciar ganhos
8. Especificação da Package
create or replace package detector_fraudes_pkg as
function houve_fraude(p_cpf Varchar2, p_ini Date, p_fim Date)
return number;
function busca_ultima_fraude(p_cpf Varchar2, p_ini Date, p_fim Date)
return tb_fraude%rowtype;
end;
9. Package Body
create or replace package body detector_fraudes_pkg as
function houve_fraude(p_cpf Varchar2, p_ini Date, p_fim Date) return number is
begin
if p_cpf is null then
raise_application_error(-20200, 'CPF não pode ser vazio');
end if;
if length(p_cpf) > 11 then
raise_application_error(-20201, 'CPF inválido');
end if;
if p_ini is null or p_fim is null then
raise_application_error(-20202, 'Período inválido');
end if;
if trunc(p_ini) > trunc(p_fim) then
raise_application_error(-20203, 'Período inicial maior que final');
end if;
-- logica para verificar fraude --
return 0;
end;
10. Package Body
function busca_ultima_fraude(p_cpf Varchar2, p_ini Date, p_fim Date) return tb_fraude%rowtype is
l_fraude tb_fraude%rowtype;
begin
if length(p_cpf) > 11 then
raise_application_error(-20201, 'CPF inválido');
end if;
if p_ini is null or p_fim is null then
raise_application_error(-20202, 'Período inválido');
end if;
if trunc(p_ini) > trunc(p_fim) then
raise_application_error(-20203, 'Período inicial maior que final');
end if;
select f.*
into l_fraude
from tb_fraude f
where f.cpf = p_cpf and f.detectada_em between p_ini and p_fim;
return l_fraude;
end;
end;
11. Função Houve_Fraude
function houve_fraude(p_cpf Varchar2, p_ini Date, p_fim Date) return number is
begin
if p_cpf is null then
raise_application_error(-20200, 'CPF não pode ser vazio');
end if;
if length(p_cpf) > 11 then
raise_application_error(-20201, 'CPF inválido');
end if;
if p_ini is null or p_fim is null then
raise_application_error(-20202, 'Período inválido');
end if;
if trunc(p_ini) > trunc(p_fim) then
raise_application_error(-20203, 'Período inicial maior que final');
end if;
-- lógica para verificar fraude --
return 0;
end;
12. Função Houve_Fraude
function houve_fraude(p_cpf Varchar2, p_ini Date, p_fim Date) return number is
begin
if p_cpf is null then
raise_application_error(-20200, 'CPF não pode ser vazio');
end if;
if length(p_cpf) > 11 then
raise_application_error(-20201, 'CPF inválido');
end if;
if p_ini is null or p_fim is null then
raise_application_error(-20202, 'Período inválido');
end if;
if trunc(p_ini) > trunc(p_fim) then
raise_application_error(-20203, 'Período inicial maior que final');
end if;
-- lógica para verificar fraude --
return 0;
end;
13. Função Houve_Fraude
function houve_fraude(p_cpf Varchar2, p_ini Date, p_fim Date) return number is
begin
if p_cpf is null then
raise_application_error(-20200, 'CPF não pode ser vazio');
end if;
if length(p_cpf) != 11 then
raise_application_error(-20201, 'CPF inválido');
end if;
if p_ini is null or p_fim is null then
raise_application_error(-20202, 'Período inválido');
end if;
if trunc(p_ini) > trunc(p_fim) then
raise_application_error(-20203, 'Período inicial maior que final');
end if;
-- lógica para verificar fraude --
return 0;
end;
14. Função Houve_Fraude
function houve_fraude(p_cpf Varchar2, p_ini Date, p_fim Date) return number is
begin
if p_cpf is null then
raise_application_error(-20200, 'CPF não pode ser vazio');
end if;
if length(p_cpf) != 11 then
raise_application_error(-20201, 'CPF inválido');
end if;
if p_ini is null or p_fim is null then
raise_application_error(-20202, 'Período inválido');
end if;
if trunc(p_ini) > trunc(p_fim) then
raise_application_error(-20203, 'Período inicial maior que final');
end if;
-- lógica para verificar fraude --
return 0;
end;
15. Função Houve_Fraude
function houve_fraude(p_cpf Varchar2, p_ini Date, p_fim Date) return number is
begin
if p_cpf is null then
raise_application_error(-20200, 'CPF não pode ser vazio');
end if;
if length(p_cpf) != 11 then
raise_application_error(-20201, 'CPF inválido');
end if;
if p_ini is null or p_fim is null then
raise_application_error(-20202, 'Período inválido');
end if;
if trunc(p_ini) > trunc(p_fim) then
raise_application_error(-20203, 'Período inicial maior que final');
end if;
-- lógica para verificar fraude --
return 0;
end;
0 ou 1
16. Função Houve_Fraude
function houve_fraude(p_cpf Varchar2, p_ini Date, p_fim Date) return varchar2 is
begin
if p_cpf is null then
raise_application_error(-20200, 'CPF não pode ser vazio');
end if;
if length(p_cpf) != 11 then
raise_application_error(-20201, 'CPF inválido');
end if;
if p_ini is null or p_fim is null then
raise_application_error(-20202, 'Período inválido');
end if;
if trunc(p_ini) > trunc(p_fim) then
raise_application_error(-20203, 'Período inicial maior que final');
end if;
-- lógica para verificar fraude --
return ‘N’;
end;
‘1’ ou ‘0’
‘S’ ou ‘N’
‘Y’ ou ‘N’
‘S’ ou ‘N’ ou ‘P’
‘Sim’ ou ‘Não’
17. Função Houve_Fraude
function houve_fraude(p_cpf Varchar2, p_ini Date, p_fim Date) return boolean is
begin
if p_cpf is null then
raise_application_error(-20200, 'CPF não pode ser vazio');
end if;
if length(p_cpf) != 11 then
raise_application_error(-20201, 'CPF inválido');
end if;
if p_ini is null or p_fim is null then
raise_application_error(-20202, 'Período inválido');
end if;
if trunc(p_ini) > trunc(p_fim) then
raise_application_error(-20203, 'Período inicial maior que final');
end if;
-- lógica para verificar fraude --
return false;
end;
18. Função Houve_Fraude
function houve_fraude(p_cpf Varchar2, p_ini Date, p_fim Date) return boolean is
begin
if p_cpf is null then
raise_application_error(-20200, 'CPF não pode ser vazio');
end if;
if length(p_cpf) != 11 then
raise_application_error(-20201, 'CPF inválido');
end if;
if p_ini is null or p_fim is null then
raise_application_error(-20202, 'Período inválido');
end if;
if trunc(p_ini) > trunc(p_fim) then
raise_application_error(-20203, 'Período inicial maior que final');
end if;
-- lógica para verificar fraude --
return false;
end;
19. Função Houve_Fraude
function houve_fraude(p_cpf Varchar2, p_ini Date, p_fim Date) return boolean is
begin
if p_cpf is null then
raise_application_error(-20200, 'CPF não pode ser vazio');
end if;
if length(p_cpf) != 11 then
raise_application_error(-20201, 'CPF inválido');
end if;
if p_ini is null or p_fim is null then
raise_application_error(-20202, 'Período inválido');
end if;
if trunc(p_ini) > trunc(p_fim) then
raise_application_error(-20203, 'Período inicial maior que final');
end if;
-- lógica para verificar fraude --
return false;
end;
Tamanho?
Formato?
20. Função Houve_Fraude
function houve_fraude(p_cpf Cpf, p_ini Date, p_fim Date) return boolean is
begin
if p_cpf is null then
raise_application_error(-20200, 'CPF não pode ser vazio');
end if;
if length(p_cpf) != 11 then
raise_application_error(-20201, 'CPF inválido');
end if;
if p_ini is null or p_fim is null then
raise_application_error(-20202, 'Período inválido');
end if;
if trunc(p_ini) > trunc(p_fim) then
raise_application_error(-20203, 'Período inicial maior que final');
end if;
-- lógica para verificar fraude --
return false;
end;
21. Função Houve_Fraude
function houve_fraude(p_cpf Cpf, p_ini Date, p_fim Date) return boolean is
begin
if p_cpf is null then
raise_application_error(-20200, 'CPF não pode ser vazio');
end if;
if length(p_cpf) != 11 then
raise_application_error(-20201, 'CPF inválido');
end if;
if p_ini is null or p_fim is null then
raise_application_error(-20202, 'Período inválido');
end if;
if trunc(p_ini) > trunc(p_fim) then
raise_application_error(-20203, 'Período inicial maior que final');
end if;
-- lógica para verificar fraude --
return false;
end;
22. Função Houve_Fraude
function houve_fraude(p_cpf Cpf, p_ini Date, p_fim Date) return boolean is
begin
if p_cpf is null then
raise_application_error(-20200, 'CPF não pode ser vazio');
end if;
if length(p_cpf) != 11 then
raise_application_error(-20201, 'CPF inválido');
end if;
if p_ini is null or p_fim is null then
raise_application_error(-20202, 'Período inválido');
end if;
if trunc(p_ini) > trunc(p_fim) then
raise_application_error(-20203, 'Período inicial maior que final');
end if;
-- lógica para verificar fraude --
return false;
end;
Período
23. Função Houve_Fraude
function houve_fraude(p_cpf Cpf, p_periodo Periodo_rt) return boolean is
begin
if p_cpf is null then
raise_application_error(-20200, 'CPF não pode ser vazio');
end if;
if length(p_cpf) != 11 then
raise_application_error(-20201, 'CPF inválido');
end if;
if p_ini is null or p_fim is null then
raise_application_error(-20202, 'Período inválido');
end if;
if trunc(p_ini) > trunc(p_fim) then
raise_application_error(-20203, 'Período inicial maior que final');
end if;
-- lógica para verificar fraude --
return false;
end;
24. Função Houve_Fraude
function houve_fraude(p_cpf Cpf, p_periodo Periodo_rt) return boolean is
begin
if p_cpf is null then
raise_application_error(-20200, 'CPF não pode ser vazio');
end if;
if length(p_cpf) != 11 then
raise_application_error(-20201, 'CPF inválido');
end if;
if p_ini is null or p_fim is null then
raise_application_error(-20202, 'Período inválido');
end if;
if trunc(p_ini) > trunc(p_fim) then
raise_application_error(-20203, 'Período inicial maior que final');
end if;
-- lógica para verificar fraude --
return false;
end;
25. Especificação da Package
create or replace package detector_fraudes_pkg as
function houve_fraude(p_cpf Varchar2, p_ini Date, p_fim Date)
return number;
function busca_ultima_fraude(p_cpf Varchar2, p_ini Date, p_fim Date)
return tb_fraude%rowtype;
end;
26. Especificação da Package
create or replace package detector_fraudes_pkg as
subtype Cpf is Varchar2(11);
function houve_fraude(p_cpf Varchar2, p_ini Date, p_fim Date)
return number;
function busca_ultima_fraude(p_cpf Varchar2, p_ini Date, p_fim Date)
return tb_fraude%rowtype;
end;
27. Especificação da Package
create or replace package detector_fraudes_pkg as
subtype Cpf is Varchar2(11) not null;
function houve_fraude(p_cpf Varchar2, p_ini Date, p_fim Date)
return number;
function busca_ultima_fraude(p_cpf Varchar2, p_ini Date, p_fim Date)
return tb_fraude%rowtype;
end;
28. Especificação da Package
create or replace package detector_fraudes_pkg as
subtype Cpf is Varchar2(11) not null;
type Periodo_rt is record (
inicio Date
,fim Date
);
function houve_fraude(p_cpf Varchar2, p_ini Date, p_fim Date)
return number;
function busca_ultima_fraude(p_cpf Varchar2, p_ini Date, p_fim Date)
return tb_fraude%rowtype;
end;
29. Especificação da Package
create or replace package detector_fraudes_pkg as
subtype Cpf is Varchar2(11) not null;
type Periodo_rt is record (
inicio Date Default Sysdate
,fim Date Default Sysdate+1
);
function houve_fraude(p_cpf Varchar2, p_ini Date, p_fim Date)
return number;
function busca_ultima_fraude(p_cpf Varchar2, p_ini Date, p_fim Date)
return tb_fraude%rowtype;
end;
30. Especificação da Package Alterada
create or replace package detector_fraudes_pkg as
subtype Cpf is Varchar2(11) not null;
type Periodo_rt is record (
inicio Date Default Sysdate
,fim Date Default Sysdate+1
);
function houve_fraude(p_cpf Cpf, p_periodo Periodo_rt)
return boolean;
function busca_ultima_fraude(p_cpf Varchar2, p_ini Date, p_fim Date)
return tb_fraude%rowtype;
end;
31. Função Houve_Fraude
function houve_fraude(p_cpf Cpf, p_periodo Periodo_rt) return boolean is
begin
if p_cpf is null then
raise_application_error(-20200, 'CPF não pode ser vazio');
end if;
if length(p_cpf) > 11 then
raise_application_error(-20201, 'CPF inválido');
end if;
if p_ini is null or p_fim is null then
raise_application_error(-20202, 'Período inválido');
end if;
if trunc(p_ini) > trunc(p_fim) then
raise_application_error(-20203, 'Período inicial maior que final');
end if;
-- logica para verificar fraude --
return false;
end;
32. Função Houve_Fraude
function houve_fraude(p_cpf Cpf, p_periodo Periodo_rt) return boolean is
begin
if p_cpf is null then
raise_application_error(-20200, 'CPF não pode ser vazio');
end if;
if length(p_cpf) > 11 then
raise_application_error(-20201, 'CPF inválido');
end if;
if p_ini is null or p_fim is null then
raise_application_error(-20202, 'Período inválido');
end if;
if trunc(p_ini) > trunc(p_fim) then
raise_application_error(-20203, 'Período inicial maior que final');
end if;
-- logica para verificar fraude --
return false;
end;
33. Função Houve_Fraude
function houve_fraude(p_cpf Cpf, p_periodo Periodo_rt) return boolean is
begin
if p_cpf is null then
raise_application_error(-20200, 'CPF não pode ser vazio');
end if;
if length(p_cpf) > 11 then
raise_application_error(-20201, 'CPF inválido');
end if;
if p_ini is null or p_fim is null then
raise_application_error(-20202, 'Período inválido');
end if;
if trunc(p_ini) > trunc(p_fim) then
raise_application_error(-20203, 'Período inicial maior que final');
end if;
-- logica para verificar fraude --
return false;
end;
34. Função Houve_Fraude
function houve_fraude(p_cpf Cpf, p_periodo Periodo_rt) return boolean is
begin
if p_cpf is null then
raise_application_error(-20200, 'CPF não pode ser vazio');
end if;
if length(p_cpf) > 11 then
raise_application_error(-20201, 'CPF inválido');
end if;
if p_ini is null or p_fim is null then
raise_application_error(-20202, 'Período inválido');
end if;
if trunc(p_ini) > trunc(p_fim) then
raise_application_error(-20203, 'Período inicial maior que final');
end if;
-- logica para verificar fraude --
return false;
end;
35. Função Houve_Fraude
function houve_fraude(p_cpf Cpf, p_periodo Periodo_rt) return boolean is
begin
if p_cpf is null then
raise_application_error(-20200, 'CPF não pode ser vazio');
end if;
if length(p_cpf) > 11 then
raise_application_error(-20201, 'CPF inválido');
end if;
if p_ini is null or p_fim is null then
raise_application_error(-20202, 'Período inválido');
end if;
if trunc(p_ini) > trunc(p_fim) then
raise_application_error(-20203, 'Período inicial maior que final');
end if;
-- logica para verificar fraude --
return false;
end;
36. Função Houve_Fraude
function houve_fraude(p_cpf Cpf, p_periodo Periodo_rt) return boolean is
begin
if p_cpf is null then
raise_application_error(-20200, 'CPF não pode ser vazio');
end if;
if length(p_cpf) > 11 then
raise_application_error(-20201, 'CPF inválido');
end if;
if p_ini is null or p_fim is null then
raise_application_error(-20202, 'Período inválido');
end if;
if trunc(p_ini) > trunc(p_fim) then
raise_application_error(-20203, 'Período inicial maior que final');
end if;
-- logica para verificar fraude --
return false;
end;
37. Função Houve_Fraude
function houve_fraude(p_cpf Cpf, p_periodo Periodo_rt) return boolean is
begin
if p_cpf is null then
raise_application_error(-20200, 'CPF não pode ser vazio');
end if;
if length(p_cpf) > 11 then
raise_application_error(-20201, 'CPF inválido');
end if;
if p_periodo.inicio is null or p_periodo.fim is null then
raise_application_error(-20202, 'Período inválido');
end if;
if trunc(p_ini) > trunc(p_fim) then
raise_application_error(-20203, 'Período inicial maior que final');
end if;
-- logica para verificar fraude --
return false;
end;
38. Função Houve_Fraude
function houve_fraude(p_cpf Cpf, p_periodo Periodo_rt) return boolean is
begin
if p_cpf is null then
raise_application_error(-20200, 'CPF não pode ser vazio');
end if;
if length(p_cpf) > 11 then
raise_application_error(-20201, 'CPF inválido');
end if;
if p_periodo.inicio is null or p_periodo.fim is null then
raise_application_error(-20202, 'Período inválido');
end if;
if trunc(p_ini) > trunc(p_fim) then
raise_application_error(-20203, 'Período inicial maior que final');
end if;
-- logica para verificar fraude --
return false;
end;
39. Função Houve_Fraude
function houve_fraude(p_cpf Cpf, p_periodo Periodo_rt) return boolean is
begin
if p_cpf is null then
raise_application_error(-20200, 'CPF não pode ser vazio');
end if;
if length(p_cpf) > 11 then
raise_application_error(-20201, 'CPF inválido');
end if;
if p_periodo.inicio is null or p_periodo.fim is null then
raise_application_error(-20202, 'Período inválido');
end if;
if trunc(p_periodo.inicio) > trunc(p_periodo.fim) then
raise_application_error(-20203, 'Período inicial maior que final');
end if;
-- logica para verificar fraude --
return false;
end;
40. Função Houve_Fraude Refatorada
function houve_fraude(p_cpf Cpf, p_periodo Periodo_rt) return boolean is
begin
if p_periodo.inicio is null or p_periodo.fim is null then
raise_application_error(-20202, 'Período inválido');
end if;
if trunc(p_periodo.inicio) > trunc(p_periodo.fim) then
raise_application_error(-20203, 'Período inicial maior que final');
end if;
-- logica para verificar fraude --
return false;
end;
41. Refatoração em Andamento
● Foi possível alterar três tipos de dados
○ Criação de um subtipo e um tipo no escopo da package
○ Novo tipo no retorno de função
● Código estruturado
● Tipos podem ser utilizados em novos métodos no escopo da package
● Possibilidade de melhoria
○ Compartilhar os tipos criados para demais packages, funções e procedimentos de um
Schema do banco de dados
○ Criar objetos para CPF e Período no banco de dados
42. Criação de tipo para CPF no Banco de Dados
create or replace TYPE CPF_T AS OBJECT (
numero Varchar2(11)
);
43. Criação de tipo para CPF no Banco de Dados
create or replace TYPE CPF_T AS OBJECT (
numero Varchar2(11)
);
● Tipo do parâmetro CPF muda
function houve_fraude(p_cpf CPF_T, … ) …
44. Criação de tipo para CPF no Banco de Dados
create or replace TYPE CPF_T AS OBJECT (
numero Varchar2(11)
);
● Tipo do parâmetro CPF muda
function houve_fraude(p_cpf CPF_T, … ) …
● Garantir mesmas validações do subtipo
● Criar funções de validação dentro do Type CPF_T
45. Criação de tipo para CPF no Banco de Dados
create or replace TYPE CPF_T AS OBJECT (
numero Varchar2(11)
,Constructor Function CPF_T(numero Varchar2) Return Self as Result
);
create or replace TYPE BODY CPF_T AS
Constructor Function CPF_T(numero Varchar2) Return Self as Result as
begin
if numero is null then
raise_application_error(-20200, 'CPF não pode ser vazio');
end if;
if length(numero) > 11 then
raise_application_error(-20201, 'CPF inválido');
end if;
self.numero := numero;
RETURN;
end;
end;
46. Criação de tipo para CPF no Banco de Dados
create or replace TYPE CPF_T AS OBJECT (
numero Varchar2(11)
,Constructor Function CPF_T(numero Varchar2) Return Self as Result
);
create or replace TYPE BODY CPF_T AS
Constructor Function CPF_T(numero Varchar2) Return Self as Result as
begin
if numero is null then
raise_application_error(-20200, 'CPF não pode ser vazio');
end if;
if length(numero) > 11 then
raise_application_error(-20201, 'CPF inválido');
end if;
self.numero := numero;
RETURN;
end;
end;
47. Criação de tipo para CPF no Banco de Dados
create or replace TYPE CPF_T AS OBJECT (
numero Varchar2(11)
,Constructor Function CPF_T(numero Varchar2) Return Self as Result
);
create or replace TYPE BODY CPF_T AS
Constructor Function CPF_T(numero Varchar2) Return Self as Result as
begin
if numero is null then
raise_application_error(-20200, 'CPF não pode ser vazio');
end if;
if length(numero) > 11 then
raise_application_error(-20201, 'CPF inválido');
end if;
self.numero := numero;
RETURN;
end;
end;
48. Criação de tipo para CPF no Banco de Dados
create or replace TYPE CPF_T AS OBJECT (
numero Varchar2(11)
,Constructor Function CPF_T(numero Varchar2) Return Self as Result
);
create or replace TYPE BODY CPF_T AS
Constructor Function CPF_T(numero Varchar2) Return Self as Result as
begin
if numero is null then
raise_application_error(-20200, 'CPF não pode ser vazio');
end if;
if length(numero) > 11 then
raise_application_error(-20201, 'CPF inválido');
end if;
self.numero := numero;
RETURN;
end;
end;
49. Criação de tipo para CPF no Banco de Dados
create or replace TYPE CPF_T AS OBJECT (
numero Varchar2(11)
,Constructor Function CPF_T(numero Varchar2) Return Self as Result
,Member Function formatado Return Varchar2
);
create or replace TYPE BODY CPF_T AS
(...)
Member Function formatado Return Varchar2 is
begin
return Utl_lms.format_message('%s.%s.%s-%s'
, substr(self.numero, 1, 3)
, substr(self.numero, 4, 3)
, substr(self.numero, 7, 3)
, substr(self.numero, 10, 2)
);
end;
end;
50. Criação de tipo para CPF no Banco de Dados
● Construtor garantindo as validações
● É possível criar mais funções conforme a necessidade
● Propiciar a refatoração na função Houve_Fraude
51. Especificação da Package
create or replace package detector_fraudes_pkg as
subtype Cpf is Varchar2(11) not null;
type Periodo_rt is record (
inicio Date Default Sysdate
,fim Date Default Sysdate+1
);
function houve_fraude(p_cpf Cpf, p_periodo Periodo_rt)
return boolean;
function busca_ultima_fraude(p_cpf Varchar2, p_ini Date, p_fim Date)
return tb_fraude%rowtype;
end;
52. Especificação da Package
create or replace package detector_fraudes_pkg as
subtype Cpf is Varchar2(11) not null;
type Periodo_rt is record (
inicio Date Default Sysdate
,fim Date Default Sysdate+1
);
function houve_fraude(p_cpf Cpf, p_periodo Periodo_rt)
return boolean;
function busca_ultima_fraude(p_cpf Varchar2, p_ini Date, p_fim Date)
return tb_fraude%rowtype;
end;
53. Especificação da Package
create or replace package detector_fraudes_pkg as
subtype Cpf is Varchar2(11) not null;
type Periodo_rt is record (
inicio Date Default Sysdate
,fim Date Default Sysdate+1
);
function houve_fraude(p_cpf Cpf, p_periodo Periodo_rt)
return boolean;
function busca_ultima_fraude(p_cpf Varchar2, p_ini Date, p_fim Date)
return tb_fraude%rowtype;
end;
54. Especificação da Package
create or replace package detector_fraudes_pkg as
subtype Cpf is Varchar2(11) not null;
type Periodo_rt is record (
inicio Date Default Sysdate
,fim Date Default Sysdate+1
);
function houve_fraude(p_cpf Cpf, p_periodo Periodo_rt)
return boolean;
function busca_ultima_fraude(p_cpf Varchar2, p_ini Date, p_fim Date)
return tb_fraude%rowtype;
end;
55. Especificação da Package
create or replace package detector_fraudes_pkg as
subtype Cpf is Varchar2(11) not null;
type Periodo_rt is record (
inicio Date Default Sysdate
,fim Date Default Sysdate+1
);
function houve_fraude(p_cpf CPF_T, p_periodo Periodo_rt)
return boolean;
function busca_ultima_fraude(p_cpf Varchar2, p_ini Date, p_fim Date)
return tb_fraude%rowtype;
end;
56. Especificação da Package Alterada
create or replace package detector_fraudes_pkg as
type Periodo_rt is record (
inicio Date Default Sysdate
,fim Date Default Sysdate+1
);
function houve_fraude(p_cpf CPF_T, p_periodo Periodo_rt)
return boolean;
function busca_ultima_fraude(p_cpf Varchar2, p_ini Date, p_fim Date)
return tb_fraude%rowtype;
end;
57. Função Houve_Fraude
function houve_fraude(p_cpf Cpf, p_periodo Periodo_rt) return boolean is
begin
if p_periodo.inicio is null or p_periodo.fim is null then
raise_application_error(-20202, 'Período inválido');
end if;
if trunc(p_periodo.inicio) > trunc(p_periodo.fim) then
raise_application_error(-20203, 'Período inicial maior que final');
end if;
-- logica para verificar fraude --
return false;
end;
58. Função Houve_Fraude Refatorada
function houve_fraude(p_cpf CPF_T, p_periodo Periodo_rt) return boolean is
begin
if p_periodo.inicio is null or p_periodo.fim is null then
raise_application_error(-20202, 'Período inválido');
end if;
if trunc(p_periodo.inicio) > trunc(p_periodo.fim) then
raise_application_error(-20203, 'Período inicial maior que final');
end if;
-- logica para verificar fraude --
return false;
end;
59. Criação de tipo para Período no Banco de Dados
create or replace type PERIODO_T FORCE as Object (
inicio Date
,fim Date
);
60. Criação de tipo para Período no Banco de Dados
create or replace type PERIODO_T FORCE as Object (
inicio Date
,fim Date
);
● Tipo do parâmetro Período muda
function houve_fraude(p_cpf CPF_T, p_periodo PERIODO_T) …
61. Criação de tipo para Período no Banco de Dados
create or replace type PERIODO_T FORCE as Object (
inicio Date
,fim Date
);
● Tipo do parâmetro Período muda
function houve_fraude(p_cpf CPF_T, p_periodo PERIODO_T) …
● Da mesma forma que fizemos para o Type CPF_T
○ Criar as funções de validação do período dentro do Type PERIODO_T
62. Criação de tipo para Período no Banco de Dados
create or replace type PERIODO_T FORCE as Object (
inicio Date
,fim Date
,Constructor Function PERIODO_T(inicio Date, fim Date) Return Self as Result
);
63. Criação de tipo para Período no Banco de Dados
create or replace type PERIODO_T FORCE as Object (
inicio Date
,fim Date
,Constructor Function PERIODO_T(inicio Date, fim Date) Return Self as Result
,Member Function is_valido Return Boolean
,Member Function conflita_com(outro_periodo Periodo_t) Return Boolean
,Member Function periodo_conflitante_com(outro_periodo Periodo_t) Return Periodo_t
,Member Function to_string Return Varchar2
);
64. Criação de tipo para Período no Banco de Dados
create or replace type BODY PERIODO_T as
Constructor Function PERIODO_T(inicio Date, fim Date) Return Self as Result as
begin
self.inicio := trunc(inicio);
self.fim := trunc(fim);
RETURN;
end;
Member Function is_valido Return Boolean is
begin
if (self.inicio is null OR self.fim is null) then
return false;
end if;
return self.inicio <= self.fim;
end;
end;
65. Especificação da Package
create or replace package detector_fraudes_pkg as
type Periodo_rt is record (
inicio Date Default Sysdate
,fim Date Default Sysdate+1
);
function houve_fraude(p_cpf CPF_T, p_periodo Periodo_rt)
return boolean;
function busca_ultima_fraude(p_cpf Varchar2, p_ini Date, p_fim Date)
return tb_fraude%rowtype;
end;
66. Especificação da Package
create or replace package detector_fraudes_pkg as
type Periodo_rt is record (
inicio Date Default Sysdate
,fim Date Default Sysdate+1
);
function houve_fraude(p_cpf CPF_T, p_periodo Periodo_rt)
return boolean;
function busca_ultima_fraude(p_cpf Varchar2, p_ini Date, p_fim Date)
return tb_fraude%rowtype;
end;
67. Especificação da Package
create or replace package detector_fraudes_pkg as
type Periodo_rt is record (
inicio Date Default Sysdate
,fim Date Default Sysdate+1
);
function houve_fraude(p_cpf CPF_T, p_periodo Periodo_rt)
return boolean;
function busca_ultima_fraude(p_cpf Varchar2, p_ini Date, p_fim Date)
return tb_fraude%rowtype;
end;
68. Especificação da Package
create or replace package detector_fraudes_pkg as
type Periodo_rt is record (
inicio Date Default Sysdate
,fim Date Default Sysdate+1
);
function houve_fraude(p_cpf CPF_T, p_periodo Periodo_rt)
return boolean;
function busca_ultima_fraude(p_cpf Varchar2, p_ini Date, p_fim Date)
return tb_fraude%rowtype;
end;
69. Especificação da Package
create or replace package detector_fraudes_pkg as
type Periodo_rt is record (
inicio Date Default Sysdate
,fim Date Default Sysdate+1
);
function houve_fraude(p_cpf CPF_T, p_periodo PERIODO_T)
return boolean;
function busca_ultima_fraude(p_cpf Varchar2, p_ini Date, p_fim Date)
return tb_fraude%rowtype;
end;
70. Especificação da Package Alterada
create or replace package detector_fraudes_pkg as
function houve_fraude(p_cpf CPF_T, p_periodo PERIODO_T)
return boolean;
function busca_ultima_fraude(p_cpf Varchar2, p_ini Date, p_fim Date)
return tb_fraude%rowtype;
end;
71. Função Houve_Fraude
function houve_fraude(p_cpf CPF_T, p_periodo Periodo_rt) return boolean is
begin
if p_periodo.inicio is null or p_periodo.fim is null then
raise_application_error(-20202, 'Período inválido');
end if;
if trunc(p_periodo.inicio) > trunc(p_periodo.fim) then
raise_application_error(-20203, 'Período inicial maior que final');
end if;
-- logica para verificar fraude --
return false;
end;
72. Função Houve_Fraude
function houve_fraude(p_cpf CPF_T, p_periodo PERIODO_T) return boolean is
begin
if p_periodo.inicio is null or p_periodo.fim is null then
raise_application_error(-20202, 'Período inválido');
end if;
if trunc(p_periodo.inicio) > trunc(p_periodo.fim) then
raise_application_error(-20203, 'Período inicial maior que final');
end if;
-- logica para verificar fraude --
return false;
end;
73. Função Houve_Fraude
function houve_fraude(p_cpf CPF_T, p_periodo PERIODO_T) return boolean is
begin
if p_periodo.inicio is null or p_periodo.fim is null then
raise_application_error(-20202, 'Período inválido');
end if;
if trunc(p_periodo.inicio) > trunc(p_periodo.fim) then
raise_application_error(-20203, 'Período inicial maior que final');
end if;
-- logica para verificar fraude --
return false;
end;
74. Função Houve_Fraude
function houve_fraude(p_cpf CPF_T, p_periodo PERIODO_T) return boolean is
begin
if p_periodo.inicio is null or p_periodo.fim is null then
raise_application_error(-20202, 'Período inválido');
end if;
if trunc(p_periodo.inicio) > trunc(p_periodo.fim) then
raise_application_error(-20203, 'Período inicial maior que final');
end if;
-- logica para verificar fraude --
return false;
end;
75. Função Houve_Fraude Refatorada
function houve_fraude(p_cpf CPF_T, p_periodo PERIODO_T) return boolean is
begin
if p_periodo.is_valido() then
raise_application_error(-20203, 'Periodo inválido');
end if;
-- logica para verificar fraude --
return false;
end;
76. Focando na Função Busca_Ultima_Fraude
● Realizar alteração dos tipos dos parâmetros
● Verificar como fica a função
● Analisar melhoria
77. Especificação da Package
create or replace package detector_fraudes_pkg as
function houve_fraude(p_cpf CPF_T, p_periodo PERIODO_T)
return boolean;
function busca_ultima_fraude(p_cpf Varchar2, p_ini Date, p_fim Date)
return tb_fraude%rowtype;
end;
78. Especificação da Package Alterada
create or replace package detector_fraudes_pkg as
function houve_fraude(p_cpf CPF_T, p_periodo PERIODO_T)
return boolean;
function busca_ultima_fraude(p_cpf CPF_T, p_periodo PERIODO_T)
return tb_fraude%rowtype;
end;
79. Tabela TB_FRAUDE
create table tb_fraude (
id number,
cpf varchar2(11),
nome varchar2(30),
detectada_em date,
valor number(15,2)
);
80. Função Busca_Ultima_Fraude
function busca_ultima_fraude(p_cpf Varchar2, p_ini Date, p_fim Date) return tb_fraude%rowtype is
l_fraude tb_fraude%rowtype;
begin
if length(p_cpf) > 11 then
raise_application_error(-20201, 'CPF inválido');
end if;
if p_ini is null or p_fim is null then
raise_application_error(-20202, 'Período inválido');
end if;
if trunc(p_ini) > trunc(p_fim) then
raise_application_error(-20203, 'Período inicial maior que final');
end if;
select f.*
into l_fraude
from tb_fraude f
where f.cpf = p_cpf and f.detectada_em between p_ini and p_fim;
return l_fraude;
end;
81. Função Busca_Ultima_Fraude
function busca_ultima_fraude(p_cpf CPF_T, p_periodo PERIODO_T) return tb_fraude%rowtype is
l_fraude tb_fraude%rowtype;
begin
if length(p_cpf) > 11 then
raise_application_error(-20201, 'CPF inválido');
end if;
if p_ini is null or p_fim is null then
raise_application_error(-20202, 'Período inválido');
end if;
if trunc(p_ini) > trunc(p_fim) then
raise_application_error(-20203, 'Período inicial maior que final');
end if;
select f.*
into l_fraude
from tb_fraude f
where f.cpf = p_cpf and f.detectada_em between p_ini and p_fim;
return l_fraude;
end;
82. Função Busca_Ultima_Fraude
function busca_ultima_fraude(p_cpf CPF_T, p_periodo PERIODO_T) return tb_fraude%rowtype is
l_fraude tb_fraude%rowtype;
begin
if length(p_cpf) > 11 then
raise_application_error(-20201, 'CPF inválido');
end if;
if p_ini is null or p_fim is null then
raise_application_error(-20202, 'Período inválido');
end if;
if trunc(p_ini) > trunc(p_fim) then
raise_application_error(-20203, 'Período inicial maior que final');
end if;
select f.*
into l_fraude
from tb_fraude f
where f.cpf = p_cpf.numero and f.detectada_em between p_periodo.inicio and p_periodo.fim;
return l_fraude;
end;
83. Função Busca_Ultima_Fraude
function busca_ultima_fraude(p_cpf CPF_T, p_periodo PERIODO_T) return tb_fraude%rowtype is
l_fraude tb_fraude%rowtype;
begin
if length(p_cpf) > 11 then
raise_application_error(-20201, 'CPF inválido');
end if;
if p_ini is null or p_fim is null then
raise_application_error(-20202, 'Período inválido');
end if;
if trunc(p_ini) > trunc(p_fim) then
raise_application_error(-20203, 'Período inicial maior que final');
end if;
select f.*
into l_fraude
from tb_fraude f
where f.cpf = p_cpf.numero and f.detectada_em between p_periodo.inicio and p_periodo.fim;
return l_fraude;
end;
84. Função Busca_Ultima_Fraude
function busca_ultima_fraude(p_cpf CPF_T, p_periodo PERIODO_T) return tb_fraude%rowtype is
l_fraude tb_fraude%rowtype;
begin
if length(p_cpf) > 11 then
raise_application_error(-20201, 'CPF inválido');
end if;
if p_ini is null or p_fim is null then
raise_application_error(-20202, 'Período inválido');
end if;
if trunc(p_ini) > trunc(p_fim) then
raise_application_error(-20203, 'Período inicial maior que final');
end if;
select f.*
into l_fraude
from tb_fraude f
where f.cpf = p_cpf.numero and f.detectada_em between p_periodo.inicio and p_periodo.fim;
return l_fraude;
end;
85. Função Busca_Ultima_Fraude Refatorada
function busca_ultima_fraude(p_cpf CPF_T, p_periodo PERIODO_T) return tb_fraude%rowtype is
l_fraude tb_fraude%rowtype;
begin
if p_periodo.is_valido() then
raise_application_error(-20203, 'Periodo inválido');
end if;
select f.*
into l_fraude
from tb_fraude f
where f.cpf = p_cpf.numero and f.detectada_em between p_periodo.inicio and p_periodo.fim;
return l_fraude;
end;
86. Verificar Função Busca_Ultima_Fraude
● Tem garantia das validações dos tipos de dados dos parâmetros
■ CPF_T
■ PERIODO_T
● Restou a consulta e o tipo de retorno
○ ROWTYPE da tabela TB_FRAUDE
■ Representa uma linha da tabela com todos os campos
■ Está sendo usado como o tipo de dado do retorno da função
■ Por consequência, a variável l_fraude é do mesmo tipo
87. Função Busca_Ultima_Fraude
function busca_ultima_fraude(p_cpf CPF_T, p_periodo PERIODO_T) return tb_fraude%rowtype is
l_fraude tb_fraude%rowtype;
begin
if p_periodo.is_valido() then
raise_application_error(-20203, 'Periodo inválido');
end if;
select f.*
into l_fraude
from tb_fraude f
where f.cpf = p_cpf.numero and f.detectada_em between p_periodo.inicio and p_periodo.fim;
return l_fraude;
end;
88. Analisar Melhoria da Função Busca_Ultima_Fraude
● Problema
○ Não está errado
○ É útil verificar a necessidade de se retornar todas as colunas
■ Função acessada por outros sistemas
■ Acoplamento
■ Fragilidade
○ Caso não seja
■ Busca por clareza, organização
■ Facilitar o entendimento do negócio
■ Facilitar a implementação e manutenção do código
■ Reaproveitamento de código
■ Possíveis melhorias de performance
89. Analisar Melhoria da Função Busca_Ultima_Fraude
● Conclusão
○ Vale a pena alterar
■ Criar um tipo de dado composto com os campos necessários
● Apenas os dados interessam
● Não há regra de validação
○ Manter no escopo da package
■ Refatorar a função para ter este novo tipo de dado no retorno
■ Variável l_fraude passará a ser deste novo tipo de dado
90. Especificação da Package
create or replace package detector_fraudes_pkg as
function houve_fraude(p_cpf CPF_T, p_periodo PERIODO_T)
return boolean;
function busca_ultima_fraude(p_cpf CPF_T, p_periodo PERIODO_T)
return tb_fraude%rowtype;
end;
91. Especificação da Package
create or replace package detector_fraudes_pkg as
type Fraude_rt is record (
nome tb_fraude.nome%type
,detectada_em tb_fraude.detectada_em%type default sysdate
,valor tb_fraude.valor%type
);
function houve_fraude(p_cpf CPF_T, p_periodo PERIODO_T)
return boolean;
function busca_ultima_fraude(p_cpf CPF_T, p_periodo PERIODO_T)
return tb_fraude%rowtype;
end;
92. Especificação da Package Alterada
create or replace package detector_fraudes_pkg as
type Fraude_rt is record (
nome tb_fraude.nome%type
,detectada_em tb_fraude.detectada_em%type default sysdate
,valor tb_fraude.valor%type
);
function houve_fraude(p_cpf CPF_T, p_periodo PERIODO_T)
return boolean;
function busca_ultima_fraude(p_cpf CPF_T, p_periodo PERIODO_T)
return Fraude_rt;
end;
93. Função Busca_Ultima_Fraude
function busca_ultima_fraude(p_cpf CPF_T, p_periodo PERIODO_T) return tb_fraude%rowtype is
l_fraude tb_fraude%rowtype;
begin
if p_periodo.is_valido() then
raise_application_error(-20203, 'Periodo inválido');
end if;
select f.*
into l_fraude
from tb_fraude f
where f.cpf = p_cpf.numero and f.detectada_em between p_periodo.inicio and p_periodo.fim;
return l_fraude;
end;
94. Função Busca_Ultima_Fraude
function busca_ultima_fraude(p_cpf CPF_T, p_periodo PERIODO_T) return tb_fraude%rowtype is
l_fraude tb_fraude%rowtype;
begin
if p_periodo.is_valido() then
raise_application_error(-20203, 'Periodo inválido');
end if;
select f.*
into l_fraude
from tb_fraude f
where f.cpf = p_cpf.numero and f.detectada_em between p_periodo.inicio and p_periodo.fim;
return l_fraude;
end;
95. Função Busca_Ultima_Fraude
function busca_ultima_fraude(p_cpf CPF_T, p_periodo PERIODO_T) return Fraude_rt is
l_fraude Fraude_rt;
begin
if p_periodo.is_valido() then
raise_application_error(-20203, 'Periodo inválido');
end if;
select f.*
into l_fraude
from tb_fraude f
where f.cpf = p_cpf.numero and f.detectada_em between p_periodo.inicio and p_periodo.fim;
return l_fraude;
end;
96. Função Busca_Ultima_Fraude Refatorada
function busca_ultima_fraude(p_cpf CPF_T, p_periodo PERIODO_T) return Fraude_rt is
l_fraude Fraude_rt;
begin
if p_periodo.is_valido() then
raise_application_error(-20203, 'Periodo inválido');
end if;
select f.nome as nome
, f.detectada_em as detectada_em
, f.valor as valor_fraudulento
into l_fraude
from tb_fraude f
where f.cpf = p_cpf.numero and f.detectada_em between p_periodo.inicio and p_periodo.fim;
return l_fraude;
end;