O SQL Server contém funções do sistema para exibir/atualizar dados de string para maiúsculas e minúsculas, mas não para maiúsculas. Há vários motivos para desejar que essa operação ocorra no SQL Server e não na camada de aplicativo. No meu caso, estávamos realizando uma limpeza de dados durante a consolidação de nossos dados globais de RH de várias fontes.
Se você pesquisar na internet, encontrará várias soluções para essa tarefa, mas muitas parecem ter ressalvas restritivas ou não permitem que exceções sejam definidas na função.
NOTA : Conforme mencionado nos comentários abaixo, o SQL Server NÃO é o local ideal para realizar essa conversão. Outros métodos também foram sugeridos - como CLR, por exemplo. Este post serviu ao seu propósito, na minha opinião - é ótimo ter todos esses pensamentos em um só lugar, em oposição aos petiscos aleatórios disponíveis aqui e ali. Obrigado a todos.
O desafio que você encontrará com essas abordagens é que você perdeu informações. Explique aos usuários de negócios que eles tiraram uma foto borrada e fora de foco e, apesar do que veem na TV, não há como torná-la nítida e focada. Sempre haverá situações em que essas regras não funcionarão e, desde que todos saibam que esse é o caso, faça isso.
Esses são dados de RH, então vou supor que estamos falando sobre obter nomes em um formato de caixa de título consistente porque o mainframe os armazena como AARON BERTRAND e queremos que o novo sistema não grite com eles. Aaron é fácil (mas não é barato). Você e Hannah já identificaram o problema com o Mc/Mac, então ele capitaliza corretamente o Mc/Mac, mas há casos em que é muito agressivo com Mackey/ Maclin /Mackenzie. Mackenzie é um caso interessante - veja como a popularidade dele cresceu como um nome de bebê
Em algum momento, haverá uma pobre criança chamada Mackenzie MacKenzie porque as pessoas são seres horríveis.
Você também vai se deparar com coisas adoráveis como D'Antoni, onde devemos colocar ambas as letras ao redor da marca de verificação. Exceto para d'Autremont onde você só capitaliza a letra após o apóstrofo. Deus te ajude, porém, se você enviar um e-mail para d'Illoni, pois o nome de família deles é D'illoni.
Para contribuir com o código real, a seguir está um método CLR que usamos em uma instância de 2005 para nossos propósitos. Ele geralmente usava o ToTitleCase, exceto pela lista de exceções que construímos, quando basicamente desistimos de tentar codificar as exceções mencionadas.
Agora que tudo isso está claro, vou terminar este lindo livro de poesia de ee cummings
Percebo que você já tem uma boa solução, mas pensei em adicionar uma solução mais simples utilizando uma função Inline-Table-Valued-Function, embora uma que dependa do uso da próxima versão "vNext" do SQL Server, que inclui o
STRING_AGG()
eSTRING_SPLIT()
funções:Testando a função:
Consulte MSDN para documentação sobre STRING_AGG() e STRING_SPLIT()
Tenha em mente que a
STRING_SPLIT()
função não garante a devolução de itens em nenhum pedido específico. Isso pode ser mais irritante. Há um item do Microsoft Feedback solicitando que uma coluna seja adicionada à saída de STRING_SPLIT para indicar a ordem da saída. Considere votar isso aquiSe você deseja viver no limite e deseja usar essa metodologia, ela pode ser expandida para incluir exceções. Eu construí uma função com valor de tabela inline que faz exatamente isso:
Testando isso mostra como funciona:
A melhor solução que encontrei pode ser encontrada aqui .
Alterei um pouco o script: adicionei LTRIM e RTRIM ao valor retornado, pois, em alguns casos, o script estava adicionando espaços após o valor.
Exemplo de uso para visualizar a conversão de dados em MAIÚSCULAS para maiúsculas, com exceções:
O aspecto realmente simples e poderoso desse script é a capacidade de definir exceções dentro da própria chamada de função.
Uma nota de cautela, no entanto:
Como escrito atualmente, o script não lida com os sobrenomes Mc[AZ]%, Mac[AZ]% etc. corretamente. Atualmente estou trabalhando em edições para lidar com esse cenário.
Como alternativa, alterei o parâmetro retornado da função: REPLACE(REPLACE(LTRIM(RTRIM((@ProperCaseText)))),'Mcd','McD'),'Mci','McI'), etc. ...
Este método obviamente requeria conhecimento prévio dos dados e não é o ideal. Tenho certeza de que há uma maneira de resolver isso, mas estou no meio de uma conversão e atualmente não tenho tempo para me dedicar a esse problema irritante.
Aqui está o código: