J'essaie d'insérer CLOB
s dans une base de données (voir question connexe ). Je n'arrive pas à comprendre ce qui ne va pas. J'ai une liste d'environ 85 points que je veux insérer dans un tableau. Même en insérant seulement le premier clob, je reçois ORA-00911: invalid character
. Je n'arrive pas à comprendre comment extraire la déclaration du PreparedStatement
avant qu'elle ne soit exécutée. Je ne peux donc pas être sûr à 100% que c'est vrai, mais si j'ai bien compris, elle devrait alors ressembler exactement à cette:
insert all
into domo_queries values ('select
substr(to_char(max_data),1,4) as year,
substr(to_char(max_data),5,6) as month,
max_data
from dss_fin_user.acq_dashboard_src_load_success
where source = ''CHQ PeopleSoft FS''')
select * from dual;
En fin de compte, ceci insert all
déclaration aurait beaucoup de into
, raison pour laquelle je ne fais pas une déclaration normale insert
. Je ne vois pas de personnage invalide dedans, n'est-ce pas? (Oh, et le code ci-dessus fonctionne correctement lorsque je l'exécute dans mon outil de développement SQL .) Et si je supprime le point-virgule dans le PreparedStatement
, il jette un ORA-00933: SQL command not properly ended
Erreur.
Dans tous les cas, voici mon code pour exécuter la requête (et les valeurs des variables pour l'exemple ci-dessus).
public ResultSet executeQuery(String connection, String query, QueryParameter... params) throws DataException, SQLException {
// query at this point = "insert all
//into domo_queries values (?)
//select * from dual;"
Connection conn = ConnectionPool.getInstance().get(connection);
PreparedStatement pstmt = conn.prepareStatement(query);
for (int i = 1; i <= params.length; i++) {
QueryParameter param = params[i - 1];
switch (param.getType()) { //The type in the example is QueryParameter.CLOB
case QueryParameter.CLOB:
Clob clob = CLOB.createTemporary(conn, false, Oracle.sql.CLOB.DURATION_SESSION);
clob.setString(i, "'" + param.getValue() + "'");
//the value of param.getValue() at this point is:
/*
* select
* substr(to_char(max_data),1,4) as year,
* substr(to_char(max_data),5,6) as month,
* max_data
* from dss_fin_user.acq_dashboard_src_load_success
* where source = ''CHQ PeopleSoft FS''
*/
pstmt.setClob(i, clob);
break;
case QueryParameter.STRING:
pstmt.setString(i, "'" + param.getValue() + "'");
break;
}
}
ResultSet rs = pstmt.executeQuery(); //Obviously, this is where the error is thrown
conn.commit();
ConnectionPool.getInstance().release(conn);
return rs;
}
Y a-t-il quelque chose qui me manque grand temps?
Si vous utilisez le littéral chaîne exactement comme vous nous l'avez montré, le problème est le ;
caractère à la fin. Vous ne pouvez pas inclure cela dans la chaîne de requête dans les appels JDBC.
Comme vous n'insérez qu'une seule ligne, un INSERT
normal devrait suffire, même lors de l'insertion de plusieurs lignes. L'utilisation d'une déclaration par lot est probablement plus efficace. Pas besoin d INSERT ALL
. De plus, vous n'avez pas besoin du clob temporaire et de tout ça. Vous pouvez simplifier votre méthode à quelque chose comme ceci (en supposant que les paramètres soient corrects):
String query1 = "select substr(to_char(max_data),1,4) as year, " +
"substr(to_char(max_data),5,6) as month, max_data " +
"from dss_fin_user.acq_dashboard_src_load_success " +
"where source = 'CHQ PeopleSoft FS'";
String query2 = ".....";
String sql = "insert into domo_queries (clob_column) values (?)";
PreparedStatement pstmt = con.prepareStatement(sql);
StringReader reader = new StringReader(query1);
pstmt.setCharacterStream(1, reader, query1.length());
pstmt.addBatch();
reader = new StringReader(query2);
pstmt.setCharacterStream(1, reader, query2.length());
pstmt.addBatch();
pstmt.executeBatch();
con.commit();
Pouvez-vous essayer d'utiliser l'opérateur 'q' pour le littéral chaîne?
quelque chose comme
insert all
into domo_queries values (q'[select
substr(to_char(max_data),1,4) as year,
substr(to_char(max_data),5,6) as month,
max_data
from dss_fin_user.acq_dashboard_src_load_success
where source = 'CHQ PeopleSoft FS']')
select * from dual;
Notez que les guillemets simples de votre prédicat ne sont pas échappés et que la chaîne se situe entre q '[...]'.