Artigo "Novidades do Firebird 2.5": Character Sets e Collates

Posted on in artigo, firebird

No Firebird, diferentes tabelas ou até mesmo diferentes colunas de uma mesma tabela podem usar diferentes character sets e collates. Isto permite uma grande flexibilidade mas pode causar problemas caso o desenvolvedor ou DBA não se atente às necessidades da aplicação. Por isso, um banco de dados pode ter um character set default, que é automaticamente usado quando não é especificado um character set durante a definição de uma coluna de tipo string. Algo semelhante não existia para collates, sendo que o collate default de cada character set é o modo de comparação binária dos bytes que compõem uma string.

Na nova versão foi introduzido o comando ALTER CHARACTER SET, permitindo a alteração do collate padrão de um character set. Além do comando ALTER CHARACTER SET, agora o collate padrão do character set padrão do banco pode ser definido no momento da criação do banco de dados. A listagem 1 mostra a criação de um banco de dados usando o character set padrão WIN1252 e definindo seu collate padrão para WIN_PTBR. Em seguida o collate padrão do character set UTF8 é alterado para UNICODE_CI_AI.


Listagem 1. Exemplos de alteração de collate padrão.

CREATE DATABASE 'TEST.FDB'
  DEFAULT CHARACTER SET WIN1252
  COLLATION WIN_PTBR;

ALTER CHARACTER SET UTF8
  SET DEFAULT COLLATION UNICODE_CI_AI;



A listagem 2 mostra o banco operando com o character set default WIN1252 e o collate WIN_PTBR (case-insensitive).

Listagem 2. Comparação de strings usando o collate WIN_PTBR.

CREATE TABLE PESSOAS (NOME VARCHAR(20));

INSERT INTO PESSOAS VALUES ('Fulano');
INSERT INTO PESSOAS VALUES ('Beltrano');

-- Localiza Fulano (= FULANO)
SELECT * FROM PESSOAS WHERE NOME = 'FULANO';


Outra necessidade comumente encontrada em aplicações é a gravação de códigos alfanuméricos. Até o Firebird 2.1 a ordenação de campos do tipo string era sempre feita no modo de comparação de texto. Isto quer dizer que um código “A10” é listado antes de “A2” caso ordenado por esta coluna. A listagem 3 mostra um exemplo desta situação.

Listagem 3. Ordenação de códigos alfanuméricos usando o collate UNICODE.

CREATE TABLE DOCUMENTOS (
  CODIGO VARCHAR(10) CHARACTER SET UTF8 COLLATE UNICODE
);

INSERT INTO DOCUMENTOS VALUES ('A1');
INSERT INTO DOCUMENTOS VALUES ('A2');
INSERT INTO DOCUMENTOS VALUES ('A10');
INSERT INTO DOCUMENTOS VALUES ('A11');
INSERT INTO DOCUMENTOS VALUES ('A100');
INSERT INTO DOCUMENTOS VALUES ('B1');
INSERT INTO DOCUMENTOS VALUES ('B10');

-- Resultado: A1, A10, A100, A11, A2, B1, B10
SELECT CODIGO FROM DOCUMENTOS ORDER BY CODIGO;



O Firebird 2.5 permite que collates sejam configuráveis, e uma das opções do collate UNICODE permite que números sejam ordenados por ordem numérica. A listagem 4 mostra a criação do collate UNICODE_NUM com o uso da opção NUMERIC-SORT e a ordenação usando este collate.

Listagem 4. Ordenação usando a opção NUMERIC-SORT do collate UNICODE.

CREATE COLLATION UNICODE_NUM FOR UTF8 FROM UNICODE 'NUMERIC-SORT=1';

CREATE TABLE DOCUMENTOS2 (
  CODIGO VARCHAR(10) CHARACTER SET UTF8 COLLATE UNICODE_NUM
);

INSERT INTO DOCUMENTOS2 SELECT * FROM DOCUMENTOS;

-- Resultado: A1, A2, A10, A11, A100, B1, B10
SELECT CODIGO FROM DOCUMENTOS2 ORDER BY CODIGO;



Outra novidade da versão 2.5 é o collate UNICODE_CI_AI (para o character set UTF8), variação do collate UNICODE pré-configurado para desconsiderar diferenças de acentos e maiúsculas/minúsculas. O collate UNICODE_CI_AI funciona de maneira similar ao WIN_PTBR e PT_BR, mas aceita o conjunto completo de caracteres Unicode.