Tem maiúscula? – SQL Server

Boa noite, caros leitores!

Venho-lhes escrever mais uma vez! Hoje um amigo do trabalho, Varley, teve uma necessidade interessante que nos fez pensar em uma função útil a ser feita no SQL Server.

A Necessidade: retornar todos os registros que contivessem alguma letra maiúscula.

Problema: o banco de dados utiliza o collation Latin1_General_CI_AI. Esse collation não faz diferenciação de maiúsculas e minúsculas. Para lembrar um pouco sobre collations leia: https://fredyesmeraldo.wordpress.com/2011/06/10/problemas-para-pesquisar-textos-que-possam-conter-acentos-errados-collations-do-sqlserver-resolverao-seu-problema/

Solução: para conseguir fazer a comparação se é maiúscula ou não, precisamos usar um artifício do SQL Server que converte um collation de uma string. Segue abaixo os códigos para retornar se existe maiúscula e outra função que retorna se existe minúscula. Daí para frente pode-se fazer diversas variações de funções (TodasMaiusculas, TodasMiusculas),

create function dbo.TemMinuscula(@texto varchar(max))
returns bit
as
begin
declare @letras as varchar(100)
declare @i as int
declare @j as int
declare @resultado as bit
declare @saiDoLoop as bit

select
@letras = ‘abcdefghijklmnopqrstuvwxzç’,
@resultado = 0,
@i = 1,
@j = 1,
@saiDoLoop = 0

while ( @i <= LEN(@texto) ) and (@saiDoLoop = 0)
begin
while ( @j <= LEN(@letras)) and (@saiDoLoop = 0)
begin
if SUBSTRING(@texto,@i,1) collate Latin1_General_CS_AI = SUBSTRING(@letras,@j,1) collate Latin1_General_CS_AI
begin
select
@resultado = 1,
@saiDoLoop = 1
end

select @j = @j + 1
end

select @i = @i + 1
select @j = 1
end

return @resultado
end

go

——————————————————–

create function dbo.TemMaiuscula(@texto varchar(max))
returns bit
as
begin
declare @letras as varchar(100)
declare @i as int
declare @j as int
declare @resultado as bit
declare @saiDoLoop as bit

select
@letras = ‘ABCDEFGHIJKLMNOPQRSTUVWXZÇ’,
@resultado = 0,
@i = 1,
@j = 1,
@saiDoLoop = 0

while ( @i <= LEN(@texto) ) and (@saiDoLoop = 0)
begin
while ( @j <= LEN(@letras)) and (@saiDoLoop = 0)
begin
if SUBSTRING(@texto,@i,1) collate Latin1_General_CS_AI = SUBSTRING(@letras,@j,1) collate Latin1_General_CS_AI
begin
select
@resultado = 1,
@saiDoLoop = 1
end

select @j = @j + 1
end

select @i = @i + 1
select @j = 1
end

return @resultado
end

Segue abaixo exemplo de utilização:

select dbo.TemMaiuscula(‘testE’)

Retorna 1
select dbo.TemMinuscula(‘TESTE’)

Retorna 0

 

Espero que possa ter sido útil a ideia e que vocês possam criar mais variações de funções a partir dessas!

Abraço! Boa noite!

#Problemas para #pesquisar textos que possam conter #acentos errados? #Collations do #SQLServer resolverão seu problema

Fazia um bom tempo que não postava, porque estou me preparando para a prova 70-450 ( MCITP SQL Server 2008 – Implementation & Maintenance).

Mas hoje me sobrou algum tempo e decidi postar algo muito útil; porém, ainda pouco utilizado (pelo menos pelos locais onde tenho passado): Collations.

COLLATION

Definindo de uma forma bem básica, é um conjunto de regras sobre um determinado conjunto de caracteres baseado principalmente em idiomas. Para você entender melhor pense na língua portuguesa e suas regras e agora imagine regras na escrita alemã ,ou na japonesa, ou ainda na árabe. São totalmente diferentes e precisam ser tratadas diferentes no armazenamento e na busca. Para que isso seja possível existem os Collations.

Mas não posso ser tão simplista e deixar de comentar que as Collations também podem controlar detalhes da forma de pesquisar, como: sensibilidade à maiúsculas ou não, sensibilidade à acentos ou não, etc).

Para entender melhor como escolher um collation para a coluna do seu banco de dados, vamos analisar como é a nomeclatura dos Collations. Por exemplo, um dos Collations mais utilizados no Brasil: SQL_Latin1_General_CP1_CI_AI.

Para maior didática, vou dividir o nome da Collation da seguinte forma:

SQL_Latin1_General_ -> É o nome

CP1_ ->Significa que vai usar Unicode para codificação e ordenamento (não vou falar muito, pois não será o foco hoje)

CI_ -> Case Insensitive, ou seja, não sensível a maiúsculas e minúsculas. Se aqui tivesse CS, então seria Case Sensitive, ou seja, sensível a maiúsculas e minúsculas

AI_ ->Accent Insensitive, ou seja, não sensível à acentos. Se aqui tivesse AS, então seria Accent Sensitive, ou seja, sensível a acentos

E ainda existem outras partes da nomeclatura, mas para as língua latinas não vão importar; portanto, não vou me alongar nesse assunto.

 

Para examinar outras collations você pode executar a seguinte consulta que vai retornar o nome da Collation e a descrição:

select * from fn_helpcollations()

NA PRÁTICA

Para ficar mais fácil o entendimento sobre Collations vou usar uma solução de um problema recente na empresa em que trabalho.

Os usuários estavam cadastrando nomes de pessoas e colocavam acento no nome e outros não, gerando duplicidade e inconsistência no banco de dados. Por exemplo, um usuário cadastrava “João da Silva” e outro cadastrava “Joao da Silva”. Estamos falando da mesma pessoa; porém dois registros foram inseridos porque a Collation utilizada era a SQL_Latin1_General_CP1_CI_AS, que é sensível à acentos, sendo assim, considera os dois nomes diferentes.

A solução foi alterar a Collation do campo em questão para usar a SQL_Latin1_General_CP1_CI_AI (que não é sensível ao acento). Usei a seguinte query:

ALTER TABLE [dbo].[tb_cliente]
ALTER COLUMN [nm_cliente] varchar(50) collate SQL_Latin1_General_CP1_CI_AI not null

Pronto, agora ninguém mais conseguirá cadastrar “Joao da Silva” e depois “João da Silva”, pois isso ocasionará um erro devido a esse campo ser Unique. E ao consultar, tanto faz escrever “Joao” como “João”, o SQL Server retornará o usuário em questão.

CUIDADOS

Só lembrando dos cuidados que se deve ter ao modificar um collate:

  • verificar se o campo participa de algum índice (clustered ou nonclustered)
  • verificar se a modificação não vai gerar conflito de chave primária ou estrangeira e nestes casos, verificar qual o registro correto e qual pode ser excluído

 

Por hoje é só, caros leitores…

Hoje é sexta e é dia de curtir a esposa e uma boa comida.

Até o próximo post!

Fredy Esmeraldo

Implementation & Maintenance