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.

Os valores do tipo character são preenchidos fisicamente com espaços até o comprimento n especificado, sendo armazenados e mostrados desta forma. Entretanto, os espaços de preenchimento são tratados como não sendo significativos semanticamente. Os espaços de preenchimento são desconsiderados ao se comparar dois valores do tipo character, e são removidos ao converter um valor do tipo character para um dos outros tipos para cadeia de caracteres. Deve ser observado que os espaços no final são significativos semanticamente nos valores dos tipos character varying e text.

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. Enquanto o tipo character(n) possui vantagens no desempenho em alguns outros sistemas gerenciadores de banco de dados, não possui estas vantagens no PostgreSQL. Na maioria das situações deve ser utilizado text ou character varying em vez deste tipo.

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. O conjunto de caracteres do banco de dados determina o conjunto de caracteres utilizado para armazenar valores textuais; para obter mais informações sobre o suporte a conjunto de caracteres consulte a Seção 20.2.

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 8.0.0, truncando os espaços à direita que excedem o tamanho do campo, o SQL Server 2005 também, mas como a função len exclui os espaços à direita 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 8.0.0:

 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 CSS válido!