varchar2 e Unicode para aqueles que não entendem nada sobre bancos de dados Oracle ou ORA-12899: valor muito grande para a coluna

Acontece que o produto que estamos desenvolvendo trabalha com múltiplos bancos de dados relacionais. Agora, esses são MS SQL, Postgres e Oracle. Houve lançamentos em muitas coisas, do MySQL aos falecidos, provavelmente Firebird e exótico Sybase com DB2, mas essa não é a história.





Se com MS SQL e Postgres tudo é mais e menos compreensível e familiar, então com Oracle sempre teremos algumas surpresas. Um leitor astuto notará imediatamente que "nossas mãos estão tortas" e "simplesmente não sabemos como cozinhá-las", mas se, caro leitor, quiser saber como varchar (ou melhor, varchar2



) no oráculo divino difere de seus irmãos, então, por favor, em gato.





Como todos os sistemas modernos, armazenamos dados no formato Unicode (atualmente UTF-8). Por que isso pode ser importante para bancos de dados relacionais?





Bem, por exemplo, se você tiver uma mistura de tipos de dados Unicode e não Unicode em seu banco de dados, alguns drivers não podem fazer isso. Por exemplo, o driver JTDS - JDBC para o servidor MS SQL pode funcionar no modo Unicode ou em Ansi. Consequentemente, se você decidir "salvar" e criar uma coluna não Unicode (varchar / char), você obterá uma conversão unicode-> ansi no nível de inserção de dados na tabela e, mais provavelmente, obterá o efeito oposto (pelo menos desaceleração na inserção de dados, caso contrário e na pesquisa).





Então, a história. Nosso servidor de aplicação verifica o comprimento máximo permitido de campos antes de inseri-los (aqui é necessário estipular que a verificação é realizada não de acordo com os dados do banco de dados, mas de acordo com nossos metadados internos), mas apesar disso, às vezes no Oracle "pegamos" um erro comoORA-12899: value too large for column.







? , , Oracle.





. , varchar2



:) 





, ,





alter table address modify street varchar2(150);
      
      



150 - ( -)? - :) .









alter table address modify street varchar2(150 char);
      
      



.. char



-byte



. ( )   - .





, UTF-8, , 4 ( 1 ANSI, 2 4 ).





Unicode !? , , , " ". .. , : legacy, , Unicode' " ", , backup 86 imp - .





? tool, , create table



char



:)





:





, , , .









SELECT value FROM NLSDATABASEPARAMETERS WHERE parameter='NLSLENGTHSEMANTICS';
      
      



, , " ":





SELECT TABLE_NAME, COLUMN_NAME, DATA_LENGTH, CHAR_USED 
FROM USER_TAB_COLUMNS 
WHERE DATA_TYPE = 'VARCHAR2' AND CHAR_USED = 'B'
ORDER BY TABLE_NAME, COLUMN_NAME
      
      



P.S. , , (, 100% ansi ), Unciode … ...





P.P.S. Regexp " " varchar2\(\s*\d+\s*\)







P.P.P.S.  StackOverflow





PPPPS E aqui está o que a Oracle pensa sobre alterar o valor do parâmetro  NLSLENGTHSEMANTICS



 para algo mais razoável "A Oracle recomenda enfaticamente que você NÃO defina o parâmetro NLS LENGTH SEMANTICS como CHAR na instância ou no arquivo de parâmetro do servidor. Isso pode fazer com que muitos scripts de instalação existentes criar colunas inesperadamente com semântica de comprimento de caracteres, resultando em erros de tempo de execução, incluindo estouro de buffer. " https://docs.oracle.com/cd/E24693 01 / server.11203 / e24448 / initparams149.htm








All Articles