Skip to content

Instantly share code, notes, and snippets.

@hevertonfreitas
Created November 14, 2016 19:53
Show Gist options
  • Save hevertonfreitas/21e6242907af65d1e2daeefa2d9ae5f0 to your computer and use it in GitHub Desktop.
Save hevertonfreitas/21e6242907af65d1e2daeefa2d9ae5f0 to your computer and use it in GitHub Desktop.
Utilidades CPF/CNPJ
CREATE OR REPLACE FUNCTION verifica_cnpj(text)
RETURNS boolean AS
$BODY$
-- se o tamanho for 14 prossiga com o cálculo
-- senão retorne falso
SELECT CASE WHEN LENGTH($1) = 14
THEN
(
-- verifica se os dígitos coincidem com os especificados
SELECT SUBSTR($1, 13, 1) = CAST(digit1 AS TEXT) AND
SUBSTR($1, 14, 1) = CAST(digit2 AS TEXT)
FROM
(
-- calcula o segundo dígito verificador (digit2)
SELECT
-- se o resultado do módulo for 0 ou 1 temos 0
-- senão temos a subtração de 11 pelo resultado do módulo
CASE res2
WHEN 0
THEN 0
WHEN 1
THEN 0
ELSE 11 - res2
END AS digit2,
digit1
FROM
(
-- soma da multiplicação dos primeiros 9 dígitos por 11, 10, ..., 4, 3
-- obtemos o módulo da soma por 11
SELECT
MOD(SUM(res2) + digit1 * 2, 11) AS res2,
digit1
FROM
(
SELECT SUM(m * CAST(SUBSTR($1, 7 - m, 1) AS INTEGER)) AS res2
FROM
(
SELECT generate_series(6, 2, -1) AS m
) AS m11
UNION ALL
SELECT SUM(m * CAST(SUBSTR($1, 15 - m, 1) AS INTEGER)) AS res2
FROM
(
SELECT generate_series(9, 3, -1) AS m
) AS m12
) AS m2,
(
-- calcula o primeiro dígito verificador (digit1)
SELECT
-- se o resultado do módulo for 0 ou 1 temos 0
-- senão temos a subtração de 11 pelo resultado do módulo
CASE res1
WHEN 0
THEN 0
WHEN 1
THEN 0
ELSE 11 - res1
END AS digit1
FROM
(
-- soma da multiplicação dos primeiros 12 dígitos por 5, 4, 3, 2, 9, 8, 7, ..., 3, 2
-- obtemos o módulo da soma por 11
SELECT MOD(SUM(res1), 11) AS res1
FROM
(
SELECT SUM(n * CAST(SUBSTR($1, 6 - n, 1) AS INTEGER)) AS res1
FROM
(
SELECT generate_series(5, 2, -1) AS n
) AS m11
UNION ALL
SELECT SUM(n * CAST(SUBSTR($1, 14 - n, 1) AS INTEGER)) AS res1
FROM
(
SELECT generate_series(9, 2, -1) AS n
) AS m12
) AS m1
) AS sum1
) AS first_digit
GROUP BY digit1
) AS sum2
) AS first_sec_digit
)
ELSE FALSE END;
$BODY$
LANGUAGE sql IMMUTABLE STRICT
COST 100;
CREATE OR REPLACE FUNCTION verifica_cpf(text)
RETURNS boolean AS
$BODY$
-- se o tamanho for 11 prossiga com o cálculo
-- senão retorne falso
SELECT CASE WHEN LENGTH($1) = 11
THEN
(
-- verifica se os dígitos coincidem com os especificados
SELECT SUBSTR($1, 10, 1) = CAST(digit1 AS TEXT) AND
SUBSTR($1, 11, 1) = CAST(digit2 AS TEXT)
FROM
(
-- calcula o segundo dígito verificador (digit2)
SELECT
-- se o resultado do módulo for 0 ou 1 temos 0
-- senão temos a subtração de 11 pelo resultado do módulo
CASE res2
WHEN 0
THEN 0
WHEN 1
THEN 0
ELSE 11 - res2
END AS digit2,
digit1
FROM
(
-- soma da multiplicação dos primeiros 9 dígitos por 11, 10, ..., 4, 3
-- obtemos o módulo da soma por 11
SELECT
MOD(SUM(m * CAST(SUBSTR($1, 12 - m, 1) AS INTEGER)) + digit1 * 2, 11) AS res2,
digit1
FROM
generate_series(11, 3, -1) AS m,
(
-- calcula o primeiro dígito verificador (digit1)
SELECT
-- se o resultado do módulo for 0 ou 1 temos 0
-- senão temos a subtração de 11 pelo resultado do módulo
CASE res1
WHEN 0
THEN 0
WHEN 1
THEN 0
ELSE 11 - res1
END AS digit1
FROM
(
-- soma da multiplicação dos primeiros 9 dígitos por 10, 9, ..., 3, 2
-- obtemos o módulo da soma por 11
SELECT MOD(SUM(n * CAST(SUBSTR($1, 11 - n, 1) AS INTEGER)), 11) AS res1
FROM generate_series(10, 2, -1) AS n
) AS sum1
) AS first_digit
GROUP BY digit1
) AS sum2
) AS first_sec_digit
)
ELSE FALSE END;
$BODY$
LANGUAGE sql IMMUTABLE STRICT
COST 100;
CREATE OR REPLACE FUNCTION texto_vazio_nulo(text)
RETURNS text AS
$BODY$
SELECT CASE WHEN TRIM(BOTH FROM $1) = ''
THEN NULL
ELSE $1 END;
$BODY$
LANGUAGE sql VOLATILE
COST 100;
CREATE DOMAIN cnpj
AS character varying(14)
COLLATE pg_catalog."default"
CONSTRAINT check_cnpj CHECK (verifica_cnpj(VALUE::text) OR texto_vazio_nulo(VALUE::text) IS NULL);
CREATE DOMAIN cpf
AS character varying(11)
COLLATE pg_catalog."default"
CONSTRAINT check_cpf CHECK (verifica_cpf(VALUE::text) OR texto_vazio_nulo(VALUE::text) IS NULL);
CREATE OR REPLACE FUNCTION mascara_cnpj(cnpj)
RETURNS text AS
$BODY$
SELECT substr(cnpj, 1, 2) || '.' || SUBSTR(cnpj, 3, 3) || '.' ||
substr(cnpj, 6, 3) || '/' || SUBSTR(cnpj, 9, 4) || '-' ||
substr(cnpj, 13) AS cnpj
FROM (SELECT CAST($1 AS VARCHAR) AS cnpj) a;
$BODY$
LANGUAGE sql;
CREATE OR REPLACE FUNCTION mascara_cpf(cpf)
RETURNS text AS
$BODY$
SELECT substr(cpf, 1, 3) || '.' ||
substr(cpf, 4, 3) || '.' ||
substr(cpf, 7, 3) || '-' ||
substr(cpf, 10) as cpf
FROM (SELECT CAST($1 AS VARCHAR) AS cpf) a;
$BODY$
LANGUAGE sql;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment