Em alguns casos encontramos o erro informando que o Collate X não pode ser usado pelo Collate Y, isso acontece porque o Collate do servidor não é o mesmo do banco. Para correção precisamos sempre colocar o Collate do banco igual ao Collate do Servidor.

Para ajustar o collate do banco, se faz necessário algumas coisas:

  1. Remover todos os índices do banco
  2. Remover os campos calculados
  3. Mudar o banco para Single User
  4. Ajustar o Collate do banco para o mesmo do servidor
  5. Ajustar o Collate de todos os campos nas tabelas para o mesmo do servidor
  6. Voltar o banco para multi user
  7. Recriar os campos calculados
  8. Recriar os índices

Remover todos os índices

Podemos usar o DBDIC para recriar todos os índices, mas se estivermos usando um cliente que tem índices customizados ou com otimizações feitas direto no banco de dados, vamos perder isso, para isso podemos montar um script que contenha a criação de todos os índices, podemos criar esse script rodando o seguinte comando no banco de dados do cliente

Script para criar os índices

SELECT ' CREATE ' +
       CASE 
            WHEN I.is_unique = 1 THEN ' UNIQUE '
            ELSE ''
       END +
       I.type_desc COLLATE DATABASE_DEFAULT + ' INDEX [' +
       I.name + '] ON ' +
       SCHEMA_NAME(T.schema_id) + '.' + T.name + ' ( ' +
       KeyColumns + ' )  ' +
       ISNULL(' INCLUDE (' + IncludedColumns + ' ) ', '') +
       ISNULL(' WHERE  ' + I.filter_definition, '') + ' WITH ( ' +
       CASE 
            WHEN I.is_padded = 1 THEN ' PAD_INDEX = ON '
            ELSE ' PAD_INDEX = OFF '
       END + ',' +
       'FILLFACTOR = ' + CONVERT(
           CHAR(5),
           CASE 
                WHEN I.fill_factor = 0 THEN 100
                ELSE I.fill_factor
           END
       ) + ',' +
       -- default value 
       'SORT_IN_TEMPDB = OFF ' + ',' +
       CASE 
            WHEN I.ignore_dup_key = 1 THEN ' IGNORE_DUP_KEY = ON '
            ELSE ' IGNORE_DUP_KEY = OFF '
       END + ',' +
       CASE 
            WHEN ST.no_recompute = 0 THEN ' STATISTICS_NORECOMPUTE = OFF '
            ELSE ' STATISTICS_NORECOMPUTE = ON '
       END + ',' +
       ' ONLINE = OFF ' + ',' +
       CASE 
            WHEN I.allow_row_locks = 1 THEN ' ALLOW_ROW_LOCKS = ON '
            ELSE ' ALLOW_ROW_LOCKS = OFF '
       END + ',' +
       CASE 
            WHEN I.allow_page_locks = 1 THEN ' ALLOW_PAGE_LOCKS = ON '
            ELSE ' ALLOW_PAGE_LOCKS = OFF '
       END + ' ) ON [' +
       DS.name + ' ] ;' [CreateIndexScript]
FROM   sys.indexes I
       JOIN sys.tables T
            ON  T.object_id = I.object_id
       JOIN sys.sysindexes SI
            ON  I.object_id = SI.id
            AND I.index_id = SI.indid
       JOIN (
                SELECT *
                FROM   (
                           SELECT IC2.object_id,
                                  IC2.index_id,
                                  STUFF(
                                      (
                                          SELECT ' , ' + C.name + CASE 
                                                                       WHEN MAX(CONVERT(INT, IC1.is_descending_key)) 
                                                                            = 1 THEN 
                                                                            ' DESC '
                                                                       ELSE 
                                                                            ' ASC '
                                                                  END
                                          FROM   sys.index_columns IC1
                                                 JOIN sys.columns C
                                                      ON  C.object_id = IC1.object_id
                                                      AND C.column_id = IC1.column_id
                                                      AND IC1.is_included_column = 
                                                          0
                                          WHERE  IC1.object_id = IC2.object_id
                                                 AND IC1.index_id = IC2.index_id
                                          GROUP BY
                                                 IC1.object_id,
                                                 C.name,
                                                 index_id
                                          ORDER BY
                                                 MAX(IC1.key_ordinal) 
                                                 FOR XML PATH('')
                                      ),
                                      1,
                                      2,
                                      ''
                                  ) KeyColumns
                           FROM   sys.index_columns IC2 
                                  --WHERE IC2.Object_id = object_id('Person.Address') --Comment for all tables
                           GROUP BY
                                  IC2.object_id,
                                  IC2.index_id
                       ) tmp3
            )tmp4
            ON  I.object_id = tmp4.object_id
            AND I.Index_id = tmp4.index_id
       JOIN sys.stats ST
            ON  ST.object_id = I.object_id
            AND ST.stats_id = I.index_id
       JOIN sys.data_spaces DS
            ON  I.data_space_id = DS.data_space_id
       JOIN sys.filegroups FG
            ON  I.data_space_id = FG.data_space_id
       LEFT JOIN (
                SELECT *
                FROM   (
                           SELECT IC2.object_id,
                                  IC2.index_id,
                                  STUFF(
                                      (
                                          SELECT ' , ' + C.name
                                          FROM   sys.index_columns IC1
                                                 JOIN sys.columns C
                                                      ON  C.object_id = IC1.object_id
                                                      AND C.column_id = IC1.column_id
                                                      AND IC1.is_included_column = 
                                                          1
                                          WHERE  IC1.object_id = IC2.object_id
                                                 AND IC1.index_id = IC2.index_id
                                          GROUP BY
                                                 IC1.object_id,
                                                 C.name,
                                                 index_id 
                                                 FOR XML PATH('')
                                      ),
                                      1,
                                      2,
                                      ''
                                  ) IncludedColumns
                           FROM   sys.index_columns IC2 
                                  --WHERE IC2.Object_id = object_id('Person.Address') --Comment for all tables
                           GROUP BY
                                  IC2.object_id,
                                  IC2.index_id
                       ) tmp1
                WHERE  IncludedColumns IS NOT NULL
            ) tmp2
            ON  tmp2.object_id = I.object_id
            AND tmp2.index_id = I.index_id
WHERE  I.is_primary_key = 0
       AND I.is_unique_constraint = 0

Feito isso salve os comandos em um arquivo txt para ser usado depois

Depois que salvamos os índices, vamos apaga-los com o seguinte comando

Scriipt para apagar os índices

SELECT ' DROP INDEX [' +
       I.name + '] ON ' +
       SCHEMA_NAME(T.schema_id) + '.' + T.name + ';' [DropIndexScript]
FROM   sys.indexes I
       JOIN sys.tables T
            ON  T.object_id = I.object_id
       JOIN sys.sysindexes SI
            ON  I.object_id = SI.id
            AND I.index_id = SI.indid
       JOIN (
                SELECT *
                FROM   (
                           SELECT IC2.object_id,
                                  IC2.index_id,
                                  STUFF(
                                      (
                                          SELECT ' , ' + C.name + CASE 
                                                                       WHEN MAX(CONVERT(INT, IC1.is_descending_key)) 
                                                                            = 1 THEN 
                                                                            ' DESC '
                                                                       ELSE 
                                                                            ' ASC '
                                                                  END
                                          FROM   sys.index_columns IC1
                                                 JOIN sys.columns C
                                                      ON  C.object_id = IC1.object_id
                                                      AND C.column_id = IC1.column_id
                                                      AND IC1.is_included_column = 
                                                          0
                                          WHERE  IC1.object_id = IC2.object_id
                                                 AND IC1.index_id = IC2.index_id
                                          GROUP BY
                                                 IC1.object_id,
                                                 C.name,
                                                 index_id
                                          ORDER BY
                                                 MAX(IC1.key_ordinal) 
                                                 FOR XML PATH('')
                                      ),
                                      1,
                                      2,
                                      ''
                                  ) KeyColumns
                           FROM   sys.index_columns IC2 
                                  --WHERE IC2.Object_id = object_id('Person.Address') --Comment for all tables
                           GROUP BY
                                  IC2.object_id,
                                  IC2.index_id
                       ) tmp3
            )tmp4
            ON  I.object_id = tmp4.object_id
            AND I.Index_id = tmp4.index_id
       JOIN sys.stats ST
            ON  ST.object_id = I.object_id
            AND ST.stats_id = I.index_id
       JOIN sys.data_spaces DS
            ON  I.data_space_id = DS.data_space_id
       JOIN sys.filegroups FG
            ON  I.data_space_id = FG.data_space_id
       LEFT JOIN (
                SELECT *
                FROM   (
                           SELECT IC2.object_id,
                                  IC2.index_id,
                                  STUFF(
                                      (
                                          SELECT ' , ' + C.name
                                          FROM   sys.index_columns IC1
                                                 JOIN sys.columns C
                                                      ON  C.object_id = IC1.object_id
                                                      AND C.column_id = IC1.column_id
                                                      AND IC1.is_included_column = 
                                                          1
                                          WHERE  IC1.object_id = IC2.object_id
                                                 AND IC1.index_id = IC2.index_id
                                          GROUP BY
                                                 IC1.object_id,
                                                 C.name,
                                                 index_id 
                                                 FOR XML PATH('')
                                      ),
                                      1,
                                      2,
                                      ''
                                  ) IncludedColumns
                           FROM   sys.index_columns IC2 
                                  --WHERE IC2.Object_id = object_id('Person.Address') --Comment for all tables
                           GROUP BY
                                  IC2.object_id,
                                  IC2.index_id
                       ) tmp1
                WHERE  IncludedColumns IS NOT NULL
            ) tmp2
            ON  tmp2.object_id = I.object_id
            AND tmp2.index_id = I.index_id
WHERE  I.is_primary_key = 0
       AND I.is_unique_constraint = 0

Pegue todo o conteúdo do Script e rode no management Studio ou no DBeaver

Remover os campos calculados

Para essa operação eu levantei alguns campos calculados da versão atual e monte o seguinte script

Remover campos Calculados

alter table saidas drop column tipo_cod_operacao;
alter table entradas drop column tipo_cod_operacao;
alter table transferencias drop column tipo_cod_operacao;
alter table lotes drop column lote_null_to_z;
alter table lancamentos drop column DUPL_COMPLETA_COBREBEM_S_DIGITO;
alter table lancamentos drop column TIT_BANCO_SEM_DIGITO;
alter table lancamentos drop column  DUPLICATA_SEM_DIGITO;
alter table geradores drop column TRIM_CNPJ ;

Nota: Nas versões mais antigas, alguns desses campos não existe e existe ainda a TRIM_CNPJ na tabela iclientes, basta usar o mesmo comando da tabela geradores mudando para iclientes

Mudar o banco para Single User

Execute o seguinte comando 

ALTER DATABASE NOMEDOBANCO SET SINGLE_USER WITH ROOLBACK IMMEDIATE

Onde NOMEDOBANCO é o nome do banco de dados que vamos ajustar

Ajustar o Collate do banco para o mesmo do servidor

Antes de fazermos isso precisamos achar o collate do servidor, para isso abra o Management Studio e clieque com o botão direito no nome do servidor e vá em propriedades (ou Properties) e na janela que abrir anote a ordenação que está configurada no servidor.

E execute então o seguinte comando

ALTER DATABASE NOMEDOBANCO COLLATE ORDENADAO

Onde NOMEDOBANCO é o nome do banco de dados que vamos ajustar e ORDENACAO é a ordenação que pegamos acima, guarde o nome da ordenação que vamos utilizá-la outras vezes

Ajustar o Collate de todos os campos nas tabelas para o mesmo do servidor

Agora que já ajustamos o banco, vamos ajustar as tabelas, rodando o seguinte script mudando o que está na palavra ORDENACAO para o nome que pegamos acima

Ajusta tabelas

select 
  comando = 'ALTER TABLE ' +table_schema+'.'+table_name+' ALTER COLUMN '+COLUMN_NAME+' '+DATA_TYPE+'('+case when CHARACTER_MAXIMUM_LENGTH=-1 then 'max' else cast(CHARACTER_MAXIMUM_LENGTH as varchar(5)) end+') COLLATE ORDENACAO;'
into #comandos
FROM information_schema.COLUMNS 
WHERE collation_name<>'ORDENACAO';

Declare @ComandoAtual VarChar(500) = '';

While (Select Count(*) From #Comandos) > 0
Begin
  Select top 1 @ComandoAtual = Comando From #Comandos
  Exec (@ComandoAtual)
  Delete #Comandos Where (Comando = @ComandoAtual)
End;

drop table #comandos;;

Voltar o banco para multi user

Execute o seguinte comando 

ALTER DATABASE NOMEDOBANCO SET MULTI_USER

Onde NOMEDOBANCO é o nome do banco de dados que vamos ajustar

Recriar os campos calculados

Recria campos calculados

alter table saidas add tipo_cod_operacao as (CONVERT([varchar](8000),[TIPO_OPERACAO_S])+CONVERT([varchar](8000),[SAIDA]));
alter table entradas add tipo_cod_operacao as (CONVERT([varchar](8000),[TIPO_OPERACAO_E])+CONVERT([varchar](8000),[ENTRADA]));
alter table transferencias add tipo_cod_operacao as (CONVERT([varchar](8000),[TIPO_OPERACAO_T])+CONVERT([varchar](8000),[TRANSFERENCIA]));
alter table lotes add LOTE_NULL_TO_Z as (coalesce(CONVERT([varchar](8000),[LOTE]),CONVERT([varchar](254),'')));
alter table lancamentos add DUPL_COMPLETA_COBREBEM_S_DIGITO as (substring([DUPLICATA_COMPLETA_COBREBEM],(1),(19)))
alter table lancamentos add TIT_BANCO_SEM_DIGITO as (substring([TIT_BANCO],(1),(19)))
alter table lancamentos add DUPLICATA_SEM_DIGITO as (substring([DUPLICATA],(1),(19)))
alter table geradores add TRIM_CNPJ as (CONVERT([varchar](20),Trim([CNPJ])))

alter table iclientes add TRIM_CNPJ as (CONVERT([varchar](20),Trim([CNPJ])))


Recriar os índices

Agora pegue o txt que foi salvo com todos os índices e rode-o aqui

  • Sem rótulos