varchar2 et Unicode pour ceux qui ne comprennent rien aux bases de données Oracle ou ORA-12899: valeur trop grande pour la colonne

Il se trouve que le produit que nous développons fonctionne avec plusieurs bases de données relationnelles. Maintenant, ce sont MS SQL, Postgres et Oracle. Il y a eu des lancements sous beaucoup de choses, de MySQL au défunt, probablement Firebird et Sybase exotique avec DB2, mais ce n'est pas l'histoire.





Si avec MS SQL et Postgres c'est de plus en plus moins compréhensible et familier, alors avec Oracle à chaque fois, nous avons quelques surprises. Un lecteur avisé remarquera immédiatement que «nos mains sont tordues» et que nous «ne savons tout simplement pas comment le faire cuire», mais si, cher lecteur veut savoir en quoi varchar (ou plutôt varchar2



) dans l'Oracle divin diffère de ses frères, alors s'il vous plaît sous cat.





Comme tous les systèmes modernes, nous stockons les données au format Unicode (actuellement UTF-8). Pourquoi cela pourrait-il être important pour les bases de données relationnelles?





Eh bien, par exemple, si vous avez un mélange de types de données unicode et non-unicode dans votre base de données, certains pilotes ne peuvent pas le faire. Par exemple, le pilote JTDS - JDBC pour serveur MS SQL peut fonctionner en mode Unicode ou en Ansi. En conséquence, si vous décidez de "sauvegarder" et de créer une colonne non-unicode (varchar / char), vous obtiendrez une conversion unicode-> ansi au niveau de l'insertion de données dans la table et, très probablement, obtiendrez l'effet inverse (au moins ralentissement de l'insertion de données, sinon et sur la recherche).





Donc l'histoire. Notre serveur d'application vérifie la longueur maximale autorisée des champs avant de les insérer (ici il faut stipuler que le contrôle est effectué non pas en fonction des données de la base de données, mais en fonction de nos métadonnées internes), mais malgré cela, parfois sous Oracle nous "attrapons" une erreur commeORA-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 Voici ce qu'Oracle pense de changer la valeur du paramètre  NLSLENGTHSEMANTICS



 en quelque chose de plus raisonnable "Oracle vous recommande vivement de NE PAS définir le paramètre NLS LENGTH SEMANTICS sur CHAR dans le fichier de paramètres d'instance ou de serveur. Cela peut entraîner la désactivation de nombreux scripts d'installation existants. créer de manière inattendue des colonnes avec une sémantique de longueur de caractère, ce qui entraîne des erreurs d'exécution, y compris des dépassements de mémoire tampon. " https://docs.oracle.com/cd/E24693 01 / server.11203 / e24448 / initparams149.htm








All Articles