Oracle JDBC charset et 4000 char limite
Nous essayons de stocker une codé en UTF-16 de Chaîne dans une AL32UTF8 de base de données Oracle.
Notre programme fonctionne parfaitement sur une base de données qui utilise WE8MSWIN1252
comme jeu de caractères. Quand nous essayons de le faire fonctionner sur une base de données qui utilise AL32UTF8
il arrive à un java.sql.SQLException: ORA-01461: can bind a LONG value only for insert into a LONG column
.
Dans le cas de test ci-dessous tout fonctionne bien aussi longtemps que nos données d'entrée ne soit pas trop long.
La Chaîne d'entrée peut dépasser les 4000 caractères. Nous souhaitons conserver autant d'informations que possible, même si nous nous rendons compte de l'entrée devra être coupée.
Nos tables de base de données sont définies à l'aide de la CHAR
mot-clé (voir ci-dessous). Nous espérons que cela nous permettrait de stocker jusqu'à 4000 caractères de caractère. Cela peut-il être fait? Si oui, comment?
Nous avons essayé de convertir la Chaîne de UTF8
à l'aide d'un ByteBuffer
sans succès. OraclePreparedStatement.setFormOfUse(...)
ne voulait pas nous aider.
De passer à un CLOB
n'est pas une option. Si la chaîne est trop longue, il doit être coupé.
C'est notre code pour le moment:
public static void main(String[] args) throws Exception {
String ip ="193.53.40.229";
int port = 1521;
String sid = "ora11";
String username = "obasi";
String password = "********";
String driver = "oracle.jdbc.driver.OracleDriver";
String url = "jdbc:oracle:thin:@" + ip + ":" + port + ":" + sid;
Class.forName(driver);
String shortData = "";
String longData = "";
String data;
for (int i = 0; i < 5; i++)
shortData += "é";
for (int i = 0; i < 4000; i++)
longData += "é";
Connection conn = DriverManager.getConnection(url, username, password);
PreparedStatement stat = null;
try {
stat = conn.prepareStatement("insert into test_table_short values (?)");
data = shortData.substring(0, Math.min(5, shortData.length()));
stat.setString(1, data);
stat.execute();
stat = conn.prepareStatement("insert into test_table_long values (?)");
data = longData.substring(0, Math.min(4000, longData.length()));
stat.setString(1, data);
stat.execute();
} finally {
try {
stat.close();
} catch (Exception ex){}
}
}
C'est le script de création de la table simple:
CREATE TABLE test_table_short (
DATA VARCHAR2(5 CHAR);
);
CREATE TABLE test_table_long (
DATA VARCHAR2(4000 CHAR);
);
Le cas de test fonctionne parfaitement sur le court de données. Sur le long données, cependant, il continue à recevoir l'erreur. Même quand nos longData
est seulement 3000 caractères, il ne s'est toujours pas exécuté avec succès.
Merci d'avance!
OriginalL'auteur Arolition | 2012-07-19
Vous devez vous connecter pour publier un commentaire.
Avant Oracle 12.1, un
VARCHAR2
colonne est limitée à la mémorisation de 4000 octets de données dans la base de données de jeu de caractères, même si elle est déclaréeVARCHAR2(4000 CHAR)
. Depuis, chaque personnage de votre chaîne nécessite 2 octets de stockage dans le caractère UTF-8, vous ne serez pas en mesure de stocker plus de 2000 caractères dans la colonne. Bien sûr, ce nombre va changer, si certains de vos personnages ont réellement besoin seulement 1 octet de stockage ou si certaines d'entre elles nécessitent plus de 2 octets de stockage. Lorsque la base de données utilise le jeu de caractères Windows-1252, chaque personnage de votre chaîne ne nécessite qu'un seul octet de stockage de sorte que vous serez en mesure de stocker des 4000 caractères dans la colonne.Puisque vous avez des chaînes plus longues, serait-il possible de déclarer la colonne comme un
CLOB
plutôt que comme unVARCHAR2
? Que serait (efficacement) supprimer la limitation de la longueur (il y a une limite sur la taille d'unCLOB
qui dépend de l'Oracle de la version et de la taille de bloc, mais il est au moins à plusieurs GO).Si vous arrive d'être en utilisant Oracle 12.1 ou tard, la
max_string_size
paramètre vous permet de augmenter la taille maximale d'unVARCHAR2
de la colonne à partir de 4000 octets à 32767 octets.J'ai ajouté un commentaire sur le fil. La réponse est correcte dans la mesure où il va. Il n'a tout simplement pas de noter que si un particulier 4000 caractères nécessite plus de 4000 octets de stockage que l'4000 octets limite de capacité encore des coups de pied dans.
UTF-8 est un codage à longueur variable. De nombreux caractères asiatiques besoin d'au moins trois octets pour coder.
OriginalL'auteur Justin Cave
Résolu ce problème en coupant la Corde pour le besoin de la longueur en octets. Notez que cela ne peut être fait simplement à l'aide de
puisqu'il produit une Chaîne UTF-8 qui peut être jusqu'à trois fois plus de permis.
remarque n'utilisez pas de stat.getBytes() dépend de l'ensemble de fichiers".l'encodage " et produit Windows-1252 ou d'octets UTF-8!
Si vous utiliser Hibernate vous pouvez faire cela en utilisant org.mise en veille prolongée.Interceptor!
OriginalL'auteur dfreis