segunda-feira, 20 de fevereiro de 2012

Função para validar NIT PIS PASEP em MS SQL Server 2005 / 2008



Como não encontrei nada na net, para validar NIT PIS PASEP em MS SQL Server 2005 / 2008, e diante da necessidade, verificando o algoritmo para validação do NIT PIS PASEP, resolvi desenvolver uma função em T-SQL para validar esse troço.

Na verdade só testei com o MS SQL Server 2008, não tive tempo de testar no 2005, mas acho que deva funcionar em ambas. Fica por conta e risco nas dua versões.

O moído é o seguinte:

-- Nome Artefato/Programa..: usf_valida_nit_pis_pasep.sql
-- Autor(es)...............: Emerson Hermann (emersonhermann [at] gmail.com) O Peregrino (http://www.emersonhermann.blogspot.com) 
-- Data Inicio ............: 19/02/2012
-- 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 numero de NIT PIS PASEP
-- OBS.....................: A entrada é um varchar e o retorno é um bit, 1 para válido, 0 para inválido e null para nulos 
-- ........................: 
--
IF EXISTS (
            SELECT * 
              FROM sys.objects 
             WHERE object_id = OBJECT_ID(N'[dbo].[usf_valida_nit_pis_pasep]') 
               AND type IN (N'FN')
           )
 DROP FUNCTION usf_valida_nit_pis_pasep;
GO

CREATE FUNCTION usf_valida_nit_pis_pasep(@number varchar(max)) RETURNS bit AS
BEGIN
 DECLARE @weight  varchar (10)
 DECLARE @total  int
 DECLARE @c   int
 DECLARE @rest       int
 DECLARE @result  int
 DECLARE @r   bit 
 /*
 FORMATO : NNNNNNNNNND 
 ONDE:
 NNNNNNNNN - Numero do Identificador
 D   - Digito Verificador

 a) Multiplicar os 11 ultimos algarismos pelos pesos conforme descrito abaixo:
 PESOS:  3, 2, 9, 8, 7, 6, 5, 4, 3, 2
 ALGORISMO: NNNNNNNNN  
 CALCULO:  
 3 * N = X1
 2 * N = X2
 9 * N = X3
 8 * N = X4
 7 * N = X5
 6 * N = X6
 5 * N = X7
 4 * N = X8
 3 * N = X9
 2 * N = X10
 D (posicao do digito)
 */

 SET @weight = '3298765432'  -- peso estabelecido para gerar NIT PIS PASEP 
 SET @total = 0 
 SET @c  = 1 
    
 --fazendo um uma pre-validação do NIT PIS PASEP, validação 1 se é nulo
 IF @number IS NULL BEGIN
     SET @r = NULL
     RETURN (@r)  
 END 

 --fazendo um uma pre-validação do PIS PASEP, validação 2 se o tamanho é diferente de 11 digitos 
 IF LEN(@number) <> 11  BEGIN
     SET @r = 0
     RETURN (@r)
 END  --fim_se
    
 --fazendo um uma pre-validação do PIS PASEP, validação 3 se não for nulo e for mair que 11, ainda pode ser uma string 
 IF (SELECT CASE WHEN patindex('%[^0-9]%', @number) > 0 THEN 1 ELSE 0 END) = 1 BEGIN 
     SET @r = 0
     RETURN (@r)
 END --fim_se 
    
 --fazendo um uma pre-validação do PIS PASEP, validação 4 se está vindo c/ 11 dig zerados
 IF CAST(@number AS bigint)=0 BEGIN
     SET @r = 0
     RETURN (@r)
 END  --fim_se
    
 /*
 b) Somar todos os produtos obtidos no item "a". 
 SOMA = X1 + X2 + X3 + X4 + X5 + X6 + X7 + X8 + X9 + X10
 */

 WHILE (@c<=10) BEGIN
     SET @result = CAST (SUBSTRING(@number, @c, 1) AS INT) * CAST(SUBSTRING(@weight,@c, 1) AS INT) 
     SET @total  = @total + @result
     SET @c = @c + 1 
 END -- fim_enquanto, neste caso, while simulando for 
 
 /*
 c) Dividir o somatório do item "b" por 11.
 DIVISAO = SOMA / 11    
 */ 
 -- dividindo, não é necessário, já vai ser feito direto no resto da divisao, apenas para acompanhar o algoritmo 
 SET @result = @total / 11 
 -- calculando resto da divisao
 SET @rest = @total % 11
 
 /*
 d) Subtrair de 11 o resto da divisao do item "c".
 RESULTADO = 11 - RESTO_DA_DIVISAO
 
 O resultado sera o digito verificador. 
 Caso o resultado da subtracao seja 10 ou 11, o digito verificador sera 0.    
 */

 SET @rest = 11 - @rest

 IF @rest = 10 OR @rest = 11 BEGIN
     SET @rest = 0 
 END --fim_se
  
 IF (@rest <> CAST (SUBSTRING(@number, 11, 1) AS INT)) BEGIN
     SET @r = 0  -- numero invalido
 END ELSE BEGIN
     SET @r = 1  -- numero valido 
 END --fim_se
    
 RETURN (@r)
    
END; 
GO

-- Fazendo chamada da function, exemplo:

SELECT dbo.usf_valida_nit_pis_pasep('12511508690'); -- retorna 1 pois é valido 
GO

-- Checando na tabela colaborador todos os NITs inválidos no campo nit, exemplo:

SELECT * 
  FROM colaborador 
 WHERE dbo.usf_valida_nit_pis_pasep(nit)=1;
GO

-- Pode se ainda implementar direto na tabela colaborador para validar o campo nit, por exemplo:

ALTER TABLE colaborador
  ADD CONSTRAINT ck_colaborador_usf_valida_nit_pis_pasep 
CHECK (dbo.usf_valida_nit_pis_pasep(nit)=1); 

GO
Mais uma vez, espero ter ajudado!
O Peregrino.

3 comentários: