Problemas na alteração de Collate

Um dia desses tive um problema para alterar o collate de um banco de dados aqui da empresa. Vou demonstrar o cenário que eu possuía e como consegui resolver o problema.

Collation é uma propriedade que define como o SQL Server irá interpretar caracteres, validando acentuação ou não, caracteres maiúsculos e minúsculos, etc.

Para obtermos uma descrição dos collates podemos consultar a function fn_helpcollations, conforme abaixo:

 

SELECT name, description FROM sys.fn_helpcollations()

 

Para realização do teste eu vou criar um banco de dados com um collate que distingue caracteres maiúsculos de minúsculos, confirmo a configuração escolhida. Na sequência vou criar dois objetos (procedures) com o mesmo nome, entretanto com case diferente.

 

-- Criação do Banco de Dados de exemplo
CREATE DATABASE CollateTest_db COLLATE Latin1_General_BIN;

USE CollateTest_db;

-- Validando a configuração do banco 
SELECT database_id, name, collation_name 
FROM sys.databases WHERE DB_NAME(database_id) = 'CollateTest_db'

-- Criação das procedures para os testes
CREATE PROCEDURE retornadata_sp
AS
SELECT GETDATE();

CREATE PROCEDURE RetornaData_SP
AS 
SELECT GETDATE();

-- Validando os objetos criados
SELECT * FROM sys.objects WHERE type = 'P'

 

Até aqui, tudo bem. O banco de dados foi criado normalmente e foi possível criar dois objetos com o mesmo nome mas com cases diferentes, de acordo com a configuração escolhida para o collate.

O problema ocorre quando eu tento alterar o collate deste banco para um collate que NÃO considera o case dos caracteres. Neste caso, para o banco de dados, minhas duas procedures seriam o mesmo objeto. Para gerar o erro foi executado o seguinte script:

 

-- Tentativa de alteração do collate
ALTER DATABASE CollateTest_db COLLATE SQL_Latin1_General_CP1_CI_AI

 

E o erro gerado foi este:

 

Msg 1505, Level 16, State 1, Line 1
The CREATE UNIQUE INDEX statement terminated because a duplicate key was found for the object 
name 'sys.sysschobjs' and the index name 'nc1'. The duplicate key value is (0, 1, RetornaData_SP).
Msg 5072, Level 16, State 1, Line 1
ALTER DATABASE failed. The default collation of database 'CollateTest_db' cannot be set to SQL_Latin1_General_CP1_CI_AI.
The statement has been terminated.

 

Se você tentar fazer um SELECT na tabela em questão (sys.sysschobjs) você receberá o seguinte erro:

 

Msg 208, Level 16, State 1, Line 1
Invalid object name 'sys.sysschobjs'.

 

Isto ocorre pois é uma tabela de sistema com acesso restrito. Entretanto nós conseguimos analisar os índices desta tabela executando a procedure sp_helpindex:

 

-- Validando o índice da tabela que ocorreu o erro
SP_HELPINDEX [sys.sysschobjs]

 

Afinal de contas, como o problema foi resolvido?!? Depois de identificado que haviam objetos ondes seus nomes iriam conflitar com o Collate escolhido, percebemos que os objetos “duplicados” eram desnecessários. Apagamos os objetos do banco e com esta ação conseguimos realizar a alteração do collate do banco de dados.

Espero que a dica seja útil. Até mais!