8.3. Tipos para cadeias de caracteres

A Tabela 8-4 mostra os tipos de propósito geral para cadeias de caracteres disponíveis no PostgreSQL.

Tabela 8-4. Tipos para cadeias de caracteres

Nome Descrição
character varying(n), varchar(n) comprimento variável com limite
character(n), char(n) comprimento fixo, completado com brancos
text comprimento variável não limitado

O SQL define dois tipos primários para caracteres: character varying(n) e character(n), onde n é um número inteiro positivo. Estes dois tipos podem armazenar cadeias de caracteres com comprimento de até n caracteres. A tentativa de armazenar uma cadeia de caracteres mais longa em uma coluna de um destes tipos resulta em erro, a não ser que os caracteres excedentes sejam todos espaços; neste caso a cadeia de caracteres será truncada em seu comprimento máximo (Esta exceção um tanto bizarra é requerida pelo padrão SQL). Se a cadeia de caracteres a ser armazenada for mais curta que o comprimento declarado, os valores do tipo character são completados com espaços; os valores do tipo character varying simplesmente armazenam uma cadeia de caracteres mais curta.

Se um valor for convertido explicitamente (cast) para character varying(n), ou para character(n), o excesso de comprimento será truncado para n caracteres sem gerar erro (isto também é requerido pelo padrão SQL).

Nota: Antes do PostgreSQL 7.2 as cadeias de caracteres muito longas eram sempre truncadas sem gerar erro, tanto no contexto de conversão explícita quanto no de implícita.

As notações varchar(n) e char(n) são sinônimos para character varying(n) e character(n), respectivamente. O uso de character sem especificação de comprimento equivale a character(1); se for utilizado character varying sem especificador de comprimento, este tipo aceita cadeias de caracteres de qualquer tamanho. Este último é uma extensão do PostgreSQL.

Além desses o PostgreSQL disponibiliza o tipo text, que armazena cadeias de caracteres de qualquer comprimento. Embora o tipo text não esteja no padrão SQL, vários outros sistemas gerenciadores de banco de dados SQL também o possuem.

São necessários para armazenar dados destes tipos 4 bytes mais a própria cadeia de caracteres e, no caso do tipo character, mais os espaços para completar o tamanho. As cadeias de caracteres longas são comprimidas automaticamente pelo sistema e, portanto, o espaço físico necessário em disco pode ser menor. Os valores longos também são armazenados em tabelas secundárias, para não interferirem com o acesso rápido aos valores mais curtos da coluna. De qualquer forma, a cadeia de caracteres mais longa que pode ser armazenada é em torno de 1 GB (O valor máximo permitido para n na declaração do tipo de dado é menor que isto. Não seria muito útil mudar, porque de todo jeito nas codificações de caractere multibyte o número de caracteres e de bytes podem ser bem diferentes. Se for desejado armazenar cadeias de caracteres longas, sem um limite superior especificado, deve ser utilizado text ou character varying sem a especificação de comprimento, em vez de especificar um limite de comprimento arbitrário).

Dica: Não existe diferença de desempenho entre estes três tipos, a não ser pelo aumento do tamanho do armazenamento quando é utilizado o tipo completado com brancos.

Consulte a Seção 4.1.2.1 para obter informações sobre a sintaxe dos literais cadeias de caracteres, e o Capítulo 9 para obter informações sobre os operadores e funções.

Existem dois outros tipos para cadeias de caracteres de comprimento fixo no PostgreSQL, mostrados na Tabela 8-5 . O tipo name existe apenas para armazenamento de identificadores nos catálogos internos do sistema, não tendo por finalidade ser usado pelos usuários comuns. Seu comprimento é definido atualmente como 64 bytes (63 caracteres utilizáveis mais o terminador) mas deve ser referenciado utilizando a constante NAMEDATALEN. O comprimento é definido quando é feita a compilação (sendo, portanto, ajustável para usos especiais); o padrão para comprimento máximo poderá mudar em uma versão futura. O tipo "char" (observe as aspas) é diferente de char(1), porque utiliza apenas um byte para armazenamento. É utilizado internamente nos catálogos do sistema como o tipo de enumeração do homem pobre (poor-man's enumeration type).

Tabela 8-5. Tipos especiais para caracteres

Nome Tamanho de Armazenamento Descrição
"char" 1 byte tipo interno de um único caractere
name 64 bytes tipo interno para nomes de objeto

Exemplo 8-3. Utilização dos tipos para cadeias de caracteres

=> CREATE TABLE teste1 (a character(4));
=> INSERT INTO teste1 VALUES ('ok');
=> SELECT a, char_length(a) FROM teste1; -- 
(1)


  a   | char_length
------+-------------
 ok   |           4

=> CREATE TABLE teste2 (b VARCHAR(5));
=> INSERT INTO teste2 VALUES ('ok');
=> INSERT INTO teste2 VALUES ('bom        '); -- 
(2)

=> INSERT INTO teste2 VALUES ('muito longo');
ERRO:  valor muito longo para o tipo character varying(5)
=> INSERT INTO teste2 VALUES (CAST('muito longo' AS VARCHAR(5))); -- truncamento explícito
=> SELECT b, char_length(b) FROM teste2;

   b   | char_length
-------+-------------
 ok    |           2
 bom   |           5
 muito |           5

(1)
A função char_length é mostrada na Seção 9.4 .
(2)
O DB2 8.1 atua da mesma maneira que o PostgreSQL 7.4.1, truncando os espaços à direita que excedem o tamanho do campo, o SQL Server 2000 também, mas a função len não conta os espaços à direita e o comprimento mostrado fica sendo igual a 3, enquanto o Oracle 10g não trunca os espaços à direita e gera mensagem de erro informando que o valor é muito longo, como no comando seguinte. (N. do T.)
Exemplo 8-4. Comparação de cadeias de caracteres com espaço à direita Nestes exemplos faz-se a comparação de uma cadeia de caracteres com espaço à direita com outra cadeia de caracteres idêntica sem espaço à direita. Na tabela t1 é feita a comparação entre dois tipos char, na tabela t2 é feita a comparação entre dois tipos varchar, e na tabela t3 é feita a comparação entre os tipos char e varchar. O mesmo script foi executado no PostgreSQL, no Oracle, no SQL Server e no DB2. Abaixo está mostrado o script executado: [1] [2]
CREATE TABLE t1 ( c1 CHAR(10), c2 CHAR(10));
INSERT INTO t1 VALUES ('X', 'X ');
SELECT '''' || c1 || '''' AS c1,
       '''' || c2 || '''' AS c2,
       CASE WHEN (c1=c2) THEN 'igual' ELSE 'diferente' END AS comparação
FROM t1;

CREATE TABLE t2 ( c1 VARCHAR(10), c2 VARCHAR(10));
INSERT INTO t2 VALUES ('X', 'X ');
SELECT '''' || c1 || '''' AS c1,
       '''' || c2 || '''' AS c2,
       CASE WHEN (c1=c2) THEN 'igual' ELSE 'diferente' END AS comparação
FROM t2;

CREATE TABLE t3 ( c1 CHAR(10), c2 VARCHAR(10));
INSERT INTO t3 VALUES ('X', 'X ');
INSERT INTO t3 VALUES ('X ', 'X');
SELECT '''' || c1 || '''' AS c1,
       '''' || c2 || '''' AS c2,
       CASE WHEN (c1=c2) THEN 'igual' ELSE 'diferente' END AS comparação
FROM t3;
A seguir estão mostrados os resultados obtidos: PostgreSQL 7.4.1:

 c1  | c2  | comparação
-----+-----+------------
 'X' | 'X' | igual

 c1  |  c2  | comparação
-----+------+------------
 'X' | 'X ' | diferente

 c1  |  c2  | comparação
-----+------+------------
 'X' | 'X ' | igual
 'X' | 'X'  | igual
SQL Server 2000:
c1           c2           comparação
------------ ------------ ----------
'X         ' 'X         ' igual

c1           c2           comparação
------------ ------------ ----------
'X'          'X '         igual

c1           c2           comparação
------------ ------------ ----------
'X         ' 'X '         igual
'X         ' 'X'          igual
Oracle 10g:
C1           C2           COMPARAÇÃO
------------ ------------ ----------
'X         ' 'X         ' igual

C1           C2           COMPARAÇÃO
------------ ------------ ----------
'X'          'X '         diferente

C1           C2           COMPARAÇÃO
------------ ------------ ----------
'X         ' 'X '         diferente
'X         ' 'X'          diferente
DB2 8.1:
C1           C2           COMPARAÇÃO
------------ ------------ ----------
'X         ' 'X         ' igual

C1           C2           COMPARAÇÃO
------------ ------------ ----------
'X'          'X '         igual

C1           C2           COMPARAÇÃO
------------ ------------ ----------
'X         ' 'X '         igual
'X         ' 'X'          igual
Como pode ser visto, no SQL Server e no DB2 todas as comparações foram consideradas como sendo iguais. No Oracle só foi considerada igual a comparação entre dois tipos char, enquanto no PostgreSQL só foi considerada diferente a comparação entre dois tipos varchar.

Notas

[1] Exemplo escrito pelo tradutor, não fazendo parte do manual original.
[2] No SQL Server o operador || foi substituído pelo operador +.
SourceForge.net Logo