Insérer un champ clob dans Oracle [Résolu]

cs_polux31 3 Messages postés lundi 11 juin 2007Date d'inscription 13 avril 2011 Dernière intervention - 7 avril 2011 à 14:51 - Dernière réponse : cs_polux31 3 Messages postés lundi 11 juin 2007Date d'inscription 13 avril 2011 Dernière intervention
- 13 avril 2011 à 09:15
Bonjour,

Je rencontre un problème lors d'un INSERT d'un champ Clob dans une base Oracle 10g.

Je dois parser un fichier XML et passer à la base le contenu d'une balise qui contient du texte. La taille de ce texte dépasse les 4000 caractères. Jusque là pas de problème, tout fonctionne.

J'ai donc créé une table avec un champ Clob.

Voilà mon code :
public void insertNote(int id, String mTexte){		

String query = "INSERT INTO TABLE_CLOB (ID, CLOB_NOTETEXT) VALUES ('" + id + "', '" + mTexte + "')";


OracleConnection oc = new OracleConnection();
cnx = oc.connexionBD();

//
System.out.println(query);
//

try {

Statement s = cnx.createStatement();

s.executeUpdate(query);

s.close();

oc.closeBD();

}
catch (SQLException excep){
oc.closeBD();
excep.printStackTrace();
}


}


Et voilà ce que j'obtiens dans la console :
java.sql.SQLException: ORA-00917: missing comma

at oracle.jdbc.dbaccess.DBError.throwSqlException(DBError.java:134)
at oracle.jdbc.ttc7.TTIoer.processError(TTIoer.java:289)
at oracle.jdbc.ttc7.Oall7.receive(Oall7.java:573)
at oracle.jdbc.ttc7.TTC7Protocol.doOall7(TTC7Protocol.java:1891)
at oracle.jdbc.ttc7.TTC7Protocol.parseExecuteFetch(TTC7Protocol.java:1093)
at oracle.jdbc.driver.OracleStatement.executeNonQuery(OracleStatement.java:2047)
at oracle.jdbc.driver.OracleStatement.doExecuteOther(OracleStatement.java:1940)
at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:2709)
at oracle.jdbc.driver.OracleStatement.executeUpdate(OracleStatement.java:796)
at QuerySQL.insertQueryNote(QuerySQL.java:75)
at ParseNote.ParseNoteXML(ParseNote.java:63)
at SearchNodeCandidat.SearchCandidat(SearchNodeCandidat.java:63)
at SearchNodeCandidat.OpenDocXML(SearchNodeCandidat.java:24)
at Main.main(Main.java:14)


Quelqu'un a-t-il une piste ?

Merci pour l'intérêt que vous porterez à mon blème.
Afficher la suite 

Votre réponse

4 réponses

Meilleure réponse
HFanny 699 Messages postés mercredi 19 février 2003Date d'inscription 13 mai 2011 Dernière intervention - 7 avril 2011 à 22:58
3
Merci
Quelle est la valeur de "query" lors du System.out.println ?
As-tu essayé d'exécuter ce résultat directement en base de données ? Il est possible que mTexte contienne une apostrophe qui casserait l'instruction SQL.

Essaie de modifier ton code en utilisant un PreparedStatement (plus "safe" que de créer la requête soi-même dans un object String) :

//pas besoin d'apostrophes, juste un point d'interrogation pour chaque valeur qu'on veut passer
String query = "INSERT INTO TABLE_CLOB (ID, CLOB_NOTETEXT) VALUES (?, ?)";
//On initialise le PreparedStatement
PreparedStatement s = cnx.prepareStatement(query);
//En fonction du type du champ, on utilise setInt, setString, setDate ...
s.setInt(1, id);
s.setString(2, mTexte);
s.executeUpdate();
s.close();


Fanny

Merci HFanny 3

Avec quelques mots c'est encore mieux Ajouter un commentaire

Codes Sources a aidé 95 internautes ce mois-ci

Commenter la réponse de HFanny
Meilleure réponse
cs_polux31 3 Messages postés lundi 11 juin 2007Date d'inscription 13 avril 2011 Dernière intervention - 13 avril 2011 à 09:15
3
Merci
Bonjour,

Encore merci à toi pour ton aide. Effectivement en utilisant le lien que tu m'as indiqué, j'ai pu résoudre mon problème.

J'ai pris l'exemple d'un insert de fichier dans un clob. J'ai donc créé un fichier temporaire avec le texte à insérer que j'efface une fois la requête effectuée:

import java.io.*;
import java.sql.*;
import oracle.jdbc.*;
import oracle.sql.*;


public void insertQueryCV(String candid, String profileid) throws IOException, SQLException{

/** Insertion d'un cv dans la table profile_CV_Clob
    @candid = identifiant du candidat
    @profileid = identifiant du profil du candidat pour une offre
**/

OracleConnection oc = new OracleConnection();
cnx = oc.connexionBD();

try{

//initialize connection variable to connect to your database...
Statement stmt = cnx.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE);
stmt.executeUpdate("INSERT INTO PROFILE_CV_CLOB (PROFILEID, RESUME_CV_CLOB) VALUES('" + profileid + "',EMPTY_CLOB())");

String query="SELECT RESUME_CV_CLOB FROM PROFILE_CV_CLOB WHERE PROFILEID = '" + profileid + "' for update";
//
System.out.println(query);
//
cnx.setAutoCommit(false);
ResultSet resultset = stmt.executeQuery(query);


if(resultset.next()){
CLOB clobnew = ((OracleResultSet) resultset).getCLOB("RESUME_CV_CLOB");
PrintWriter pw = new PrintWriter(clobnew.getCharacterOutputStream() );
BufferedReader br = new BufferedReader (new FileReader( new File("C:\\temp\"tmpClob.txt") ) );
String  lineIn = null;
while( ( lineIn = br.readLine() ) != null )
      pw.println( lineIn );
      pw.close();
      br.close();
}

stmt.executeUpdate("Update PROFILE_CV_CLOB SET CANDID '" + candid + "' WHERE PROFILEID '" + profileid + "'");
cnx.setAutoCommit(true);
cnx.commit();

}
catch (SQLException excep){
oc.closeBD();
excep.printStackTrace();
}

}


En espérant que ça aide également d'autres néophytes comme moi.

Merci cs_polux31 3

Avec quelques mots c'est encore mieux Ajouter un commentaire

Codes Sources a aidé 95 internautes ce mois-ci

Commenter la réponse de cs_polux31
cs_polux31 3 Messages postés lundi 11 juin 2007Date d'inscription 13 avril 2011 Dernière intervention - 8 avril 2011 à 09:57
0
Merci
Bonjour,

Tout d'abord merci pour ce précieux conseil qui a partiellement réglé le problème.

Oui, j'avais vérifié le contenu de query et également le passage de la requête directement dans la base. Je me doutais bien que je n'employais pas la bonne méthode dans mon code.

J'ai donc une nouvelle exception qui se lève :

java.sql.SQLException: La taille des données est supérieure à la taille max. pour ce type: 9029
...


Le champ de la base est pourtant bien de type CLOB qui devrait pouvoir contenir 4Go.

Est-ce un problème Java ou Oracle ?

Merci encore.
Commenter la réponse de cs_polux31
HFanny 699 Messages postés mercredi 19 février 2003Date d'inscription 13 mai 2011 Dernière intervention - 8 avril 2011 à 20:45
0
Merci
J'avoue n'avoir jamais eu besoin d'exécuter ce genre de requête et n'ai donc jamais rencontré cette erreur.
En faisant quelques recherches rapidement, il semblerait qu'il faudrait d'abord ajouter un contenu Clob vide, et ensuite récupérer l'objet pour le mettre à jour :

SELECT clob_notetexte FROM table_clob WHERE id = ? FOR UPDATE


Voici l'exemple que j'ai trouvé (en anglais) ici.

Citation :
The main point: Unlike with other JDBC drivers, the one from Oracle doesn't support using Reader and InputStream as parameters of an INSERT. Instead, you must SELECT the CLOB column FOR UPDATE and then write into the ResultSet

En tout cas, il semblerait qu'en utilisant "thin", un setString() ne peut pas fonctionner pour plus de 4000 caractères.

Fanny
Commenter la réponse de HFanny

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.