terça-feira, 27 de março de 2012

Validar CPF em SQL

Como validar CPF em SQL Server, store function para validar CPF em T-SQL.

Esta store function, foi desenvolvida pensando no armazenamento do CPF em BIGINT, mas pode ser usada facilmente sem adaptações com CPF tipo VARCHAR(11) sem mascaras ou formatações.

Recomendável persistência do CPF em BIGINT por motivo principal de desempenho.

Segue function....




IF EXISTS (
            SELECT * 
              FROM sys.objects 
             WHERE object_id = OBJECT_ID(N'[dbo].[usf_valida_cpf]') 
               AND type IN (N'FN')
           )
 DROP FUNCTION dbo.usf_valida_cpf;
GO

CREATE FUNCTION dbo.usf_valida_cpf(@cpf varchar(max)) RETURNS bit 
AS
-- Nome Artefato/Programa..: usf_valida_cpf.sql
-- Autor(es)...............: Emerson Hermann (emersonhermann [at] gmail.com) O Peregrino (http://www.emersonhermann.blogspot.com) baseado em Script feito por:
-- ........................: Cristiano Martins Alves em http://www.devmedia.com.br
-- Data Inicio ............: 19/05/2011
-- Data Atualizacao........: 21/02/2012
-- Versao..................: 0.02
-- Compilador/Interpretador: T-SQL (Transact SQL) 
-- Sistemas Operacionais...: Windows
-- SGBD....................: MS SQL Server 2005/2008
-- Kernel..................: Nao informado!
-- Finalidade..............: Store Procedure (Function) para validar o numero do CPF
-- OBS.....................: A entrada é um varchar e o retorno é um bit, 1 para válido, 0 para inválido e null para nulos 
-- ........................: 
--  
BEGIN
  DECLARE @index   int,
          @sumx    int,
          @dig1    int,
          @dig2    int,
          @cpf_temp   varchar(11),
          @cpfx             varchar(11), 
          @dig_equal  bit,  --0 para negativa e 1 para afirmativa
          @r    bit

  -- Pre-validacao 1, se e nulo, entao retorna nulo
  IF @cpf IS NULL BEGIN
     SET @r = NULL
     RETURN (@r)  
  END --fim_se      

  -- Pre-validacao 2, se e maior que 11 digitos , entao retorna 0 
  IF LEN(@cpf) > 11 BEGIN
     SET @r = 0 
     RETURN (@r)
  END --fim_se
  
  
  -- Pre-validacao 3, se e tem alguma letra no cpf, entao retorna 0 
  IF (SELECT CASE WHEN patindex('%[^0-9]%', @cpf) > 0 THEN 1 ELSE 0 END) = 1 BEGIN
     SET @r = 0
     RETURN (@r)
  END --fim_se  
  
  -- Pre-validacao 4, se e menor que 11 digitos , pode ser oriundo de bigint, então fazer tratamento de zeros 
  SET @cpfx = @cpf
  IF LEN(@cpf) < 11 BEGIN
     SET @cpfx = REPLICATE('0',11-LEN(@cpf))+@cpf
  END --fim se
   
  /*
  -- Pre-validcao 5, se a sequencia tem numeros iguais, entao retorna 0 
     Verificando se os digitos sao iguais.
     A Principio CPF com todos os numeros iguais sao invalidos,
      apesar de validar o calculo do digito verificador
     EX: O CPF 00000000000 é inválido, mas pelo calculo seria valido
  */

  SET @cpf_temp = SUBSTRING(@cpfx,1,1)

  SET @index = 1
  SET @dig_equal = 1

  WHILE (@index <= 11) BEGIN
     IF SUBSTRING(@cpfx,@index,1) <> @cpf_temp BEGIN
        SET @dig_equal = 0
     END 
     SET @index = @index + 1
  END;

  --Caso os digitos nao sejam todos iguais, comeca o calculo dos digitos
  IF @dig_equal = 0 BEGIN

     --Calculo do 1º digito
     SET @sumx = 0
     SET @index = 1
     
     WHILE (@index <= 9) BEGIN   
        SET @sumx = @sumx + CONVERT(int,SUBSTRING(@cpfx,@index,1)) * (11 - @index)       
        SET @index = @index + 1      
     END

     SET @dig1 = 11 - (@sumx % 11)

     IF @dig1 > 9 BEGIN     
        SET @dig1 = 0       
     END 

     -- Calculo do 2º digito
     SET @sumx = 0
     SET @index = 1
     
     WHILE (@index <= 10) BEGIN   
        SET @sumx = @sumx + CONVERT(int,SUBSTRING(@cpfx,@index,1)) * (12 - @index)     
        SET @index = @index + 1 
     END  --fim_enquanto 

     SET @dig2 = 11 - (@sumx % 11)

     IF @dig2 > 9 BEGIN    
        SET @dig2 = 0     
     END 

     -- Validando
     IF (@dig1 = SUBSTRING(@cpfx,LEN(@cpfx)-1,1)) AND (@dig2 = SUBSTRING(@cpfx,LEN(@cpfx),1)) BEGIN
        SET @r = 1 
     END ELSE BEGIN  --senao   
       SET @r = 0       
     END --fim_se
     
  END ELSE BEGIN --senao 

     SET @r = 0  -- invalido
    
  END --fim_se
  
  RETURN (@r) 
  
END;
GO

-- chamada da function 

--SELECT dbo.usf_valida_cpf('80481604472');  -- retorna 1
-- ou 
--SELECT dbo.usf_valida_cpf(80481604472); -- retorna 1 
-- ou 
--SELECT dbo.usf_valida_cpf('05413714793'); -- retorna 1
-- ou 
--SELECT dbo.usf_valida_cpf(05413714793); -- retorna 1



5 comentários:

  1. Tem uma API para fazer consulta cpf no site da RFB ? At

    ResponderExcluir
  2. Olá Thiago, infelizmente não tenho, seria fácil se não tivesse o captcha conforme site do RFB abaixo:
    http://www.receita.fazenda.gov.br/Aplicacoes/ATCTA/CPF/ConsultaPublica.asp

    ResponderExcluir
  3. Obrigado pelo crédito Emerson! Grande abraço!

    ResponderExcluir