Oracle
 sql >> Base de données >  >> RDS >> Oracle

La longueur maximale de VARCHAR est de 4000 mais seulement 2666 octets de texte thaï peuvent être stockés

Le problème

Lorsque vous décrivez un VARCHAR, vous devez fournir une unité, par ex. VARCHAR2(200 BYTE) ou VARCHAR2(200 CHAR) . Si vous omettez l'unité, la valeur par défaut est BYTE (voir Oracle Database Concepts, chapitre Types de données Oracle ). Cela semble être un détail mineur, mais devient assez grave lorsque vous avez des jeux de caractères multi-octets.

Situation jusqu'à 11g

Malheureusement, il existe une limite stricte à la taille maximale d'une colonne VARCHAR2. C'est 4000 BYTEs (!) (voir Oracle Database Reference, chapitre Types de données Oracle ) jusqu'à Oracle 11g et . Il s'agit d'une limite stricte et il n'y a aucun moyen de contourner cela. Le seul moyen de contourner ce problème est une colonne CLOB.

Solution pour 12c

La situation est différente sur Oracle 12c. Là, vous pouvez utiliser le paramètre MAX_STRING_SIZE = EXTENDED pour lever la limite jusqu'à 32767 BYTEs (voir Oracle Database Language Reference, chapitre Types de données et Oracle Database Reference, chapitre Paramètres d'initialisation ). La solution évidente est donc :mise à niveau vers Oracle 12c, définissez MAX_STRING_SIZE = EXTENDED selon la documentation et modifiez la définition de votre table. Vous risquez de perdre certains index lors de la modification de votre table, car auparavant, jusqu'à 12c, les index ne pouvaient pas contenir de valeurs VARCHAR2 avec plus de 4 000 octets et il pouvait encore y avoir des limitations. (Je dois vérifier le problème avec les index et s'il peut être résolu en reconstruisant les index).

Solution :modifier l'encodage de la base de données

Vous pouvez essayer de modifier l'encodage de votre base de données native (la façon dont votre base de données mappe les CHARS aux BYTE). Pour cela, vous devez généralement créer une nouvelle base de données et fournir un paramètre approprié pour NLS_CHARACTERSET. Il s'agit d'un très grand changement dans le fonctionnement de votre base de données et peut avoir plusieurs effets secondaires. Si jamais vous essayez d'ajouter des caractères dans un encodage différent, vous risquez de ne pas avoir de chance (c'est-à-dire que vous ne pouvez pas les stocker dans votre base de données). Je ne suggérerais donc pas cette solution.

Solution :basculer vers CLOB

Habituellement, il n'est pas nécessaire de fournir des requêtes arbitraires sur des champs de texte aussi volumineux. Vous pouvez essayer d'identifier les requêtes sélectionnées dans la grande colonne de texte et les migrer vers Oracle Text sur une colonne CLOB. Mais il s'agit d'un changement très important et peut ne pas être possible avec votre schéma existant ou votre application. Vous pourriez vous retrouver avec un tas de déclencheurs "INSTEAD OF" et avec quelques vérifications de contraintes manquantes (impliquant la colonne CLOB nouvellement créée).

Solution :utiliser XML

Au lieu d'un CLOB, vous pouvez essayer de stocker votre chaîne sous forme de colonne XML. La taille maximale pour ceux-ci est de 4 Go. Cela nuira à vos performances, vous devrez fournir des déclencheurs AU LIEU DE et vous risquez de perdre certaines contraintes, mais cela pourrait fonctionner pour vous.