E ai pessoas, revisando o script de validação de CPF e CNPJ em T-SQL que adaptei em 2009, encontrei algumas melhorias pra deixá-lo mais limpo, espero que gostem:
DECLARE @TEXTO VARCHAR(20) = '02.841.834/0001-55' DECLARE @CPF_CNPJ VARCHAR(20) = '' ;WITH SPLIT AS ( SELECT 1 AS ID, SUBSTRING(@TEXTO, 1, 1) AS LETRA UNION ALL SELECT ID + 1, SUBSTRING(@TEXTO, ID + 1, 1) FROM SPLIT WHERE ID < LEN(@TEXTO) ) SELECT @CPF_CNPJ += LETRA FROM SPLIT WHERE LETRA LIKE '[0-9]' OPTION(MAXRECURSION 0) IF LEN(@CPF_CNPJ) NOT IN (11, 14) BEGIN SELECT 'Inválido' RETURN END DECLARE @I INT, @J INT = 1, @N INT = LEN(@CPF_CNPJ), @DIGITO1 INT = SUBSTRING(@CPF_CNPJ, LEN(@CPF_CNPJ) - 1, 1), @DIGITO2 INT = SUBSTRING(@CPF_CNPJ, LEN(@CPF_CNPJ), 1), @TOTAL_TMP INT, @COEFICIENTE_TMP INT, @DIGITO_TMP INT, @VALOR_TMP INT, @VALOR1 INT, @VALOR2 INT WHILE @J <= 2 BEGIN SELECT @TOTAL_TMP = 0, @COEFICIENTE_TMP = 2, @I = @N + @J - 3 WHILE @I >= 0 BEGIN SELECT @DIGITO_TMP = SUBSTRING(@CPF_CNPJ, @I, 1), @TOTAL_TMP += @DIGITO_TMP * @COEFICIENTE_TMP, @COEFICIENTE_TMP = @COEFICIENTE_TMP + 1, @I -= 1 IF @COEFICIENTE_TMP > 9 AND @N = 14 SET @COEFICIENTE_TMP = 2 END SET @VALOR_TMP = 11 - (@TOTAL_TMP % 11) IF (@VALOR_TMP >= 10) SET @VALOR_TMP = 0 IF @J = 1 SET @VALOR1 = @VALOR_TMP ELSE SET @VALOR2 = @VALOR_TMP SET @J += 1 END SELECT CASE WHEN @VALOR1 = @DIGITO1 AND @VALOR2 = @DIGITO2 THEN 'Válido' ELSE 'Inválido' END
E o script para criar uma função de validação de CPF e CNPJ:
CREATE FUNCTION [dbo].[UDF_ValidaCpfCnpj] (@TEXTO VARCHAR(20)) RETURNS BIT AS BEGIN DECLARE @CPF_CNPJ VARCHAR(20) = '' ;WITH SPLIT AS ( SELECT 1 AS ID, SUBSTRING(@TEXTO, 1, 1) AS LETRA UNION ALL SELECT ID + 1, SUBSTRING(@TEXTO, ID + 1, 1) FROM SPLIT WHERE ID < LEN(@TEXTO) ) SELECT @CPF_CNPJ += LETRA FROM SPLIT WHERE LETRA LIKE '[0-9]' OPTION(MAXRECURSION 0) IF LEN(@CPF_CNPJ) NOT IN (11, 14) BEGIN RETURN 0 END DECLARE @I INT, @J INT = 1, @N INT = LEN(@CPF_CNPJ), @DIGITO1 INT = SUBSTRING(@CPF_CNPJ, LEN(@CPF_CNPJ) - 1, 1), @DIGITO2 INT = SUBSTRING(@CPF_CNPJ, LEN(@CPF_CNPJ), 1), @TOTAL_TMP INT, @COEFICIENTE_TMP INT, @DIGITO_TMP INT, @VALOR_TMP INT, @VALOR1 INT, @VALOR2 INT WHILE @J <= 2 BEGIN SELECT @TOTAL_TMP = 0, @COEFICIENTE_TMP = 2, @I = @N + @J - 3 WHILE @I >= 0 BEGIN SELECT @DIGITO_TMP = SUBSTRING(@CPF_CNPJ, @I, 1), @TOTAL_TMP += @DIGITO_TMP * @COEFICIENTE_TMP, @COEFICIENTE_TMP = @COEFICIENTE_TMP + 1, @I -= 1 IF @COEFICIENTE_TMP > 9 AND @N = 14 SET @COEFICIENTE_TMP = 2 END SET @VALOR_TMP = 11 - (@TOTAL_TMP % 11) IF (@VALOR_TMP >= 10) SET @VALOR_TMP = 0 IF @J = 1 SET @VALOR1 = @VALOR_TMP ELSE SET @VALOR2 = @VALOR_TMP SET @J += 1 END RETURN CASE WHEN @VALOR1 = @DIGITO1 AND @VALOR2 = @DIGITO2 THEN 1 ELSE 0 END END GO SELECT CASE WHEN [dbo].[UDF_ValidaCpfCnpj] ('02.841.834/0001-55') = 1 THEN 'Válido' ELSE 'Inválido' END
E um segundo script para criar uma função de validação de CPF e CNPJ, considerando que o CPF ou CNPJ que a função vai receber nunca terá caracteres especiais ou mais/menos dígitos que um CPF ou CNPJ possui:
CREATE FUNCTION [dbo].[UDF_ValidaCpfCnpj] (@CPF_CNPJ VARCHAR(20)) RETURNS BIT AS BEGIN DECLARE @I INT, @J INT = 1, @N INT = LEN(@CPF_CNPJ), @DIGITO1 INT = SUBSTRING(@CPF_CNPJ, LEN(@CPF_CNPJ) - 1, 1), @DIGITO2 INT = SUBSTRING(@CPF_CNPJ, LEN(@CPF_CNPJ), 1), @TOTAL_TMP INT, @COEFICIENTE_TMP INT, @DIGITO_TMP INT, @VALOR_TMP INT, @VALOR1 INT, @VALOR2 INT WHILE @J <= 2 BEGIN SELECT @TOTAL_TMP = 0, @COEFICIENTE_TMP = 2, @I = @N + @J - 3 WHILE @I >= 0 BEGIN SELECT @DIGITO_TMP = SUBSTRING(@CPF_CNPJ, @I, 1), @TOTAL_TMP += @DIGITO_TMP * @COEFICIENTE_TMP, @COEFICIENTE_TMP = @COEFICIENTE_TMP + 1, @I -= 1 IF @COEFICIENTE_TMP > 9 AND @N = 14 SET @COEFICIENTE_TMP = 2 END SET @VALOR_TMP = 11 - (@TOTAL_TMP % 11) IF (@VALOR_TMP >= 10) SET @VALOR_TMP = 0 IF @J = 1 SET @VALOR1 = @VALOR_TMP ELSE SET @VALOR2 = @VALOR_TMP SET @J += 1 END RETURN CASE WHEN @VALOR1 = @DIGITO1 AND @VALOR2 = @DIGITO2 THEN 1 ELSE 0 END END GO SELECT CASE WHEN [dbo].[UDF_ValidaCpfCnpj] ('02841834000155') = 1 THEN 'Válido' ELSE 'Inválido' END
Quem tiver alguma dica ou sugestão pra melhorar este script, fique a vontade para deixar seu comentário.
Artigos relacionados:
FUNÇÕES: Validação de CNPJ e CPF com T-SQL
Muito bom!! me ajudou na validação de uma tabela!
Obrigado, me ajudou muito.
Vou deixar minha contribuição!
.
Para evitar resultados positivos quando houver:
00000000000
11111111111
…
CPF e CNPJ
.
Ajustei o terceiro exemplo, como se segue:
.
Declare
…
@lVld BIT
…
END
SET @I =0
SET @lVld =1
WHILE @I < 10 AND @lVld =1
BEGIN
IF @CPF_CNPJ = REPLICATE(STR(@I, 1), LEN(@CPF_CNPJ))
SET @lVld =0
SET @I = @I + 1
END
SELECT
CASE WHEN @VALOR1 = @DIGITO1 AND @VALOR2 = @DIGITO2 AND @lVld = 1
THEN 1
ELSE 0
END
Sensacional, parabéns pelo bom trabalho. Obrigado.
Pingback: (TSQL) VALIDAR CPF | Alex Souza