Comparando text / ntext
Posted in Erros $#$%!, Vida Real on August 18th, 2008 by Silas Mendes – Be the first to comment
No SQL Server 2005 temos os novos campos do tipo VAR…(MAX) que vieram aliviar o trabalho de muita gente. Um dos problemas mais comuns na versão anterior (2000) é quando precisamos comparar dados de campos do tipo text ou ntext, aí nos deparamos com um erro do tipo:
Server: Msg 306, Level 16, State 1, Line 1
The text, ntext, and image data types cannot be compared or sorted, except when using IS NULL or LIKE operator.
Eu já vivi essa situação algumas vezes e deixo aqui a forma como tentei resolver (Se tiverem outras sugestões fiquem a vontade para expor, ok?).
(Não fiz testes de perfomance nessa solução, o foco está somente em comparar as colunas tipo text / ntext.)
Imagine que eu tenha duas tabelas:
CREATE TABLE #tb_msg_tela
(id INT IDENTITY(1,1), texto TEXT)
GO
CREATE TABLE #tb_msg_impressao
(id INT IDENTITY(1,1), texto TEXT)
Com os seguintes dados:
INSERT INTO #tb_msg_tela VALUES (NULL)
INSERT INTO #tb_msg_tela VALUES (‘Campo text’)
INSERT INTO #tb_msg_tela VALUES (‘Teste comparação‘)
INSERT INTO #tb_msg_tela VALUES (‘Se caísse para o exterior, para o limite do universo, encontraria uma perto e pôsteres que indicassem BECO SEM SAÍDA?’)
INSERT INTO #tb_msg_impressao VALUES (”)
INSERT INTO #tb_msg_impressao VALUES (‘Campo text’)
INSERT INTO #tb_msg_impressao VALUES (‘Teste comparacao‘)
INSERT INTO #tb_msg_impressao VALUES (‘Se caisse para o esterior, p/ o limite do universo, encontraria uma perto e pôsteres que indicassem BECO SEM SAÍDA?’)
Observe que existem diferenças em alguns textos (em vermelho).
Para realizar o relacionamento das duas tabelas e encontrar os campos diferentes não podemos simplesmente utilizar:
SELECT * FROM #tb_msg_tela a, #tb_msg_impressao b
WHERE a.id = b.id AND a.texto <> b.texto
Essa consulta retornará um erro porque estamos comparando os campos text utilizando o <>.
Então o primeiro passo é encontrar o maior texto nessa coluna, para isso podemos usar as funções DATALENGHT e MAX:
SELECT MAX(DATALENGTH(texto)) FROM #tb_msg_tela
SELECT MAX(DATALENGTH(texto)) FROM #tb_msg_impressao
O resultado será:
———–
658
———–
656
Então sabemos que o maior texto dessa coluna não ultrapassa 700 caracteres, logo, podemos utilizar esse número como apoio no próximo passo, onde utilizaremos a função SUBSTRING:
SELECT
*
FROM
#tb_msg_tela a,
#tb_msg_impressao b
WHERE
a.id = b.id
AND ISNULL(SUBSTRING(a.texto, 0, 700),”) <> ISNULL(SUBSTRING(b.texto, 0, 700),”)
A função ISNULL é importante pois sem ela os campos Nulos serão ignorados.
Veja que a consulta só ira retornar os campos com as diferenças.
É um processo simples, mas que pode dar dor de cabeça por conta das limitações do tipo de dados. Pra quem ta iniciando o desenvolvimento utilizando o SQL Server 2005 a recomendação é: substitua os datatypes ntext, text, image por nvarchar(Max), varchar(Max) e varbinary(Max). Além de outras vantagens, com os novos datatypes não existem as antigas diferenças entre varchar e text.