Qual é a diferença entre varchar e varchar2 no Oracle?

Respostas:

337

Por enquanto, eles são sinônimos.

VARCHARé reservado Oraclepara oferecer suporte à distinção entre NULLe cadeia vazia no futuro, conforme ANSIprescrito pelo padrão.

VARCHAR2não faz distinção entre uma NULLstring e uma string vazia, e nunca o fará.

Se você confia na cadeia vazia e NULLé a mesma coisa, deve usar VARCHAR2.

Quassnoi
fonte
40
Não ouvira essa lógica antes, isso é útil. Obrigado. Para o registro, ainda é totalmente ridículo que o tipo de personagem principal no Oracle seja "varchar2". Isso não parece mais um comentário terrível? Parece que eu teria resolvido algum problema na minha primeira semana de aprendizado de programação.
Ian Varley
7
@ Ian: tipo principal é VARCHAR2porque atualmente não há nenhum tipo que se comporte como VARCHARdeveria. Na verdade, você não deve usá VARCHAR-lo até que seja implementado corretamente.
Quassnoi 31/05/10
11
Obrigado, @Quassnoi. Então, acho que a parte mais estúpida é que o Oracle não possui um VARCHAR adequado como todos os outros bancos de dados, então? Há algo estúpido acontecendo aqui, eu tenho certeza disso ... :)
Ian Varley
11
@ Ian: quando o Oracle estava sendo desenvolvido, não havia padrões. Quando os padrões surgiram, ele já tinha um fardo de aplicativos herdados. Todos sabemos como isso acontece.
Quassnoi 01/06/10
5
Desculpe, na verdade, foi @UnKnown quem escreveu o comentário incorreto ao qual eu estava respondendo . O fato de que where x is NULLretorna resultados diferentes where x = ''que não significa que NULLe ''são de forma alguma diferente. O comportamento diferente é devido ao =operador.
11117 Dan Crystalki
38

Atualmente, o VARCHAR se comporta exatamente da mesma forma que o VARCHAR2. No entanto, o tipo VARCHARnão deve ser usado, pois está reservado para uso futuro.

Retirado de: Diferença entre CHAR, VARCHAR, VARCHAR2

Brian
fonte
@PhilipRego VARCHARnão deve ser usado. Eu editei
bugybunny
29

Retirado da versão estável mais recente da produção Oracle 12.2: Tipos de Dados

A principal diferença é que VARCHAR2é um tipo de dados interno e VARCHARé um tipo de dados externo . Portanto, precisamos entender a diferença entre um tipo de dados interno e externo ...

Dentro de um banco de dados, os valores são armazenados em colunas nas tabelas. Internamente, o Oracle representa dados em formatos específicos, conhecidos como tipos de dados internos .

Em geral, os aplicativos OCI (Oracle Call Interface) não funcionam com representações internas de dados, mas com tipos de dados no idioma do host predefinidos pelo idioma em que foram gravados. Quando os dados são transferidos entre um aplicativo cliente OCI e uma tabela de banco de dados, as bibliotecas OCI convertem os dados entre tipos de dados internos e externos.

Tipos externos fornecem uma conveniência para o programador, possibilitando o trabalho com tipos de idioma do host em vez de formatos de dados proprietários. O OCI pode executar uma ampla variedade de conversões de tipo de dados ao transferir dados entre um banco de dados Oracle e um aplicativo OCI. Existem mais tipos de dados externos do OCI que tipos de dados internos do Oracle.

O VARCHAR2tipo de dados é uma cadeia de caracteres de tamanho variável com um comprimento máximo de 4000 bytes. Se o parâmetro init.ora max_string_size for o padrão, o comprimento máximo de a VARCHAR2poderá ser 4000 bytes. Se o parâmetro init.ora max_string_size = estendido, o comprimento máximo de a VARCHAR2pode ser 32767 bytes

O VARCHARtipo de dados armazena cadeias de caracteres de comprimento variável. Os 2 primeiros bytes contêm o comprimento da cadeia de caracteres e os bytes restantes contêm a cadeia. O comprimento especificado da sequência em uma ligação ou chamada de definição deve incluir os dois bytes de comprimento; portanto, a maior VARCHARsequência que pode ser recebida ou enviada tem 65533 bytes, e não 65535.

Um teste rápido de um banco de dados de 12.2 sugere que, como um tipo de dados internos , a Oracle ainda trata um VARCHARcomo um pseudotipo para VARCHAR2. NÃO SYNONYMé um tipo de objeto real no Oracle.

SQL> select substr(banner,1,80) from v$version where rownum=1;
Oracle Database 12c Enterprise Edition Release 12.2.0.1.0 - 64bit Production    

SQL> create table test (my_char varchar(20));
Table created.

SQL> desc test
Name                 Null?    Type
MY_CHAR                       VARCHAR2(20)

Também existem algumas implicações VARCHARpara as opções do ProC / C ++ Precompiler. Para programadores interessados, o link está em: Pro * C / C ++ Programmer's Guide

sandman
fonte
1
então isso significa que VARCHARainda trata '' == null?
2
Sim. A discussão dos tipos interno e externo acima é da referência da OCI. A Referência da linguagem SQL 12.2 ainda carrega a mesma instrução 'não usar' que sempre teve para o VARCHAR.
William Robertson
É por isso que discuti as diferenças da OCI, caso contrário, é praticamente reservado para uso futuro ou, como dizem 'comprimento variável', que pode estar sugerindo conjuntos de caracteres como UTF8 de vários bytes ...
sandman
1
Você mostrou que os valores declarados como VARCHAR são armazenados no banco de dados como VARCHAR2, no entanto, o comprimento máximo do VARCHAR (65533 bytes) é maior que o comprimento máximo do VARCHAR2 (32767 bytes). Como o banco de dados lida com isso?
Piotr Dobrogost 15/1018
IIRC, há muito tempo (talvez Oracle 6?), Havia um tipo VARCHAR que se comportava mal com preenchimento de espaço - ou era truncamento de espaços? AAR, VARCHAR2 foi a resposta. A Oracle tem dito que eles devolverão o VARCHAR, mas, tenho certeza, haverá ranger de dentes quando a string vazia NÃO É NULA.
JMD
2

Após algumas experiências (veja abaixo), posso confirmar que, em setembro de 2017, nada mudou com relação à funcionalidade descrita na resposta aceita : -

  1. Demonstração do Rextester para Oracle 11g: cadeias vazias são inseridas comoNULLs para ambosVARCHAR eVARCHAR2.
  2. Demonstração do LiveSQL para Oracle 12c: Mesmos resultados.

O motivo histórico dessas duas palavras-chave é explicado bem em uma resposta a uma pergunta diferente .

Steve Chambers
fonte
0
  1. O VARCHAR pode armazenar até 2000 bytes de caracteres, enquanto o VARCHAR2 pode armazenar até 4000 bytes de caracteres.

  2. Se declararmos o tipo de dados como VARCHAR, ele ocupará espaço para valores NULL. No caso do tipo de dados VARCHAR2, ele não ocupará espaço para valores NULL. por exemplo,

    name varchar(10)

reservará 6 bytes de memória, mesmo se o nome for 'Ravi__', enquanto

name varchar2(10) 

reservará espaço de acordo com o comprimento da sequência de entrada. por exemplo, 4 bytes de memória para 'Ravi__'.

Aqui, _ representa NULL.

NOTA: varchar reservará espaço para valores nulos e varchar2 não reservará espaço para valores nulos.

Palak Jain
fonte
2
Eu acho que esta resposta é confuso VARCHARcom CHAR.
Jon Heller
0

Atualmente, eles são os mesmos. mas anteriormente

  1. Em algum lugar na rede, eu li isso,

VARCHARé reservado pela Oracle para oferecer suporte à distinção entre NULLe sequência vazia no futuro, conforme prescreve o padrão ANSI.

VARCHAR2não faz distinção entre uma NULLstring e uma string vazia, e nunca o fará.

  1. Além disso,

Emp_name varchar(10)- se você digitar um valor inferior a 10 dígitos, o espaço restante não poderá ser excluído. utilizou um total de 10 espaços.

Emp_name varchar2(10) - se você digitar um valor inferior a 10 dígitos, o espaço restante será excluído automaticamente

Ramkumar P
fonte
Encontrei este post recentemente, observe que ele está incorreto. Execute o seguinte e os dois campos terão três caracteres:create table deleteme_table(v varchar(10), v2 varchar2(10)); insert into deleteme_table (v, v2) values ('abc','abc'); select v, length(v), v2, length(v2) from deleteme_table;
Brian Leach
-1

VARCHAR é o sinônimo de VARCHAR2. No entanto, você não deve usar o VARCHAR porque o Oracle pode alterar sua semântica no futuro.

Premraj
fonte