SQLSyntaxErrorException: ORA-00911: caractère non valide
J'essaie d'INSÉRER des enregistrements à une DB Oracle à l'aide de PreparedStatement mais je ne reçois cette erreur. À ce stade, mes efforts pour les surmonter, il l'emporte de loin sur mes progrès, et donc une autre paire d'yeux peut aider. Où est le caractère non valide?
Beaucoup de ce que j'ai trouvé suggère qu'une fuite ";
" à l'intérieur de votre Chaîne sql peut être le coupable, mais je n'ai pas eu une dans ma déclaration, dès le départ.
Ma connexion elle-même, qui œuvres parfaitement à plusieurs autres endroits dans le programme:
Properties props = new Properties();
props.setProperty( "user", username );
props.setProperty( "password", password );
props.setProperty( "defaultRowPrefetch", "10" );
props.setProperty( "defaultBatchValue", "10" );
props.setProperty( "processEscapes", "false" );
DriverManager.registerDriver(new oracle.jdbc.OracleDriver());
Connection conn = DriverManager.getConnection(DB_URL_SVC, props);
La façon dont je tiens à le faire (sauf que je l'envelopper dans une méthode qui accepte trois Cordes), mais il jette un SQLSyntaxErrorException
String INSERT_BIKE = "INSERT INTO RACEBIKES ( BIKENAME , COUNTRY_OF_ORIGIN , COST ) VALUES ( ? , ? , ? )";
PreparedStatement preStatement = conn.prepareStatement( INSERT_BIKE );
preStatement.setString(1, "JHT");
preStatement.setString(2, "USA");
preStatement.setInt(3, 2500);
preStatement.executeUpdate(); //ORA-00911: invalid character error
Ce œuvres, mais défait le but de l'utilisation de PreparedStatement étant donné que les paramètres sont codés en dur:
String INSERT_BIKE = "INSERT INTO RACEBIKES ( BIKENAME , COUNTRY_OF_ORIGIN , COST ) VALUES ( 'JHT' , 'USA' , '2500' )";
PreparedStatement preStatement = conn.prepareStatement( INSERT_BIKE );
preStatement.executeUpdate();
Œuvres. Cependant, je comprends que la concaténation de variables avec des apostrophes et des guillemets n'est pas vraiment la meilleure façon pour que PreparedStatement devrait soulager d'avoir à traiter avec la partie de la syntaxe:
String value1 = "JHT";
String value2 = "USA";
int value3 = 2500;
String INSERT_BIKE = "INSERT INTO RACEBIKES ( BIKENAME , COUNTRY_OF_ORIGIN , COST ) VALUES ( '" + value1 + "', '" + value2 + "', '" + value3 + "' )";
PreparedStatement preStatement = conn.prepareStatement( INSERT_BIKE );
preStatement.executeUpdate();
Échoue avec un SQLSyntaxErrorException. Donc, même si le code devis syntaxe moi-même, je suis toujours incapable de placer ces variables dans le preStatement.setString(), ce qui permettrait au moins de laisser un peu de souplesse.
String INSERT_BIKE = "INSERT INTO RACEBIKES ( BIKENAME , COUNTRY_OF_ORIGIN , COST ) VALUES ( ? , ? , ? )";
PreparedStatement preStatement = conn.prepareStatement( INSERT_BIKE );
preStatement.setString(1, "' + value1 + '");
preStatement.setString(2, "' + value2 + '");
preStatement.setInt(3, "' + value3 + '");
preStatement.executeUpdate(); //ORA-00911: invalid character error
Échoue. En joignant les espaces réservés dans mon String avec les guillemets simples résultats dans SQLException.
String INSERT_BIKE = "INSERT INTO RACEBIKES ( BIKENAME , COUNTRY_OF_ORIGIN , COST ) VALUES ( '?' , '?' , '?' )";
PreparedStatement preStatement = conn.prepareStatement( INSERT_BIKE );
preStatement.setString(1, "JHT");
preStatement.setString(2, "USA");
preStatement.setInt(3, 2500);
preStatement.executeUpdate(); //invalid column index
Échoue. En joignant les deux String
(mais pas le int
) des espaces réservés dans mon String avec les guillemets simples résultats dans SQLException.
String INSERT_BIKE = "INSERT INTO RACEBIKES ( BIKENAME , COUNTRY_OF_ORIGIN , COST ) VALUES ( '?' , '?' , ? )";
PreparedStatement preStatement = conn.prepareStatement( INSERT_BIKE );
preStatement.setString(1, "JHT");
preStatement.setString(2, "USA");
preStatement.setInt(3, 2500);
preStatement.executeUpdate(); //invalid column index
Ce n'est pas un échec, mais ne pas écrire dans la base de données soit (même si je n'ai pas désactivé auto-commit).
String INSERT_BIKE = "INSERT INTO RACEBIKES ( BIKENAME , COUNTRY_OF_ORIGIN , COST ) VALUES ( ? , ? , ? )";
PreparedStatement preStatement = conn.prepareStatement( INSERT_BIKE );
preStatement.setString(1, "JHT");
preStatement.setString(2, "USA");
preStatement.setInt(3, 2500);
preStatement.executeBatch();
J'ai aussi essayé toutes les évasions par des barres obliques inverses, double barres obliques inverses, backticks, quitsies, sans startsies, erasies, double-timbres, et les tofus-make-it-vrai! Peut-être quelqu'un là-bas sait le vaudou qui va m'aider?!
executeBatch()
, vous devez appeler addBatch()
(pour chaque ligne) avant. Je suppose qu'ensuite, il va échouer.Ce qui me frappe, c'est que votre troisième paramètre est un int, mais dans vos exemples, vous utilisez des guillemets simples, trop. Qu'advient-il si vous quittez? Si cela ne fonctionne pas non plus, je suppose que votre
COST
colonne est VARCHAR
, trop.Ah oui, j'ai oublié d'inclure ce cas dans mon post original. À l'aide de executeBatch() a été plus d'un coup de feu dans l'obscurité que j'ai essayé parce que j'avais mis un batchValue dans mes propriétés de l'objet. Dans ce cas, l'utilisateur ne peut mettre à jour un enregistrement unique. Mais y compris addBatch() juste au-dessus de executeBatch() toujours des résultats dans BatchUpdateException: ORA-00911: caractère non valide.
Le
COST
colonne est une NUMBER
mais en enlevant les guillemets simples jette ORA-00911.Tu veux dire, l'exécution de
"INSERT INTO RACEBIKES ( BIKENAME , COUNTRY_OF_ORIGIN , COST ) VALUES ( 'JHT' , 'USA' , 2500 )"
résultats dans un ORA-00911, trop? Pourriez-vous veuillez modifier votre première (d'origine) extrait de: preStatement.setString(3, "2500");
et essayer de nouveau?OriginalL'auteur es0329 | 2013-03-29
Vous devez vous connecter pour publier un commentaire.
Est-il une raison pourquoi vous avez
props.setProperty( "processEscapes", "false" );
?Je crois que cela désactive la possibilité d'utiliser
?
comme paramètre de liaison de l'espace réservé. Je crois que si le traitement d'échappement est activé, JDBC fait un peu de "magie" avec le?
espaces réservés avant l'adoption de la chaîne SQL pour Oracle. Sinon, le?
caractère est envoyé à la base de données.Il arrive qu'on utilise pour la désactivation de traitement d'échappement. Je l'ai utilisé en une réponse précédente à une question impliquant
?
caractères dans les mots de passe. Je crois qu'il peut être désactivée lors de la connexion ou de la déclaration; pour réactiver le traitement d'échappement sur un PreparedStatement, essayez d'appelerpreStatement.setEscapeProcessing(true);
. J'attendrais la première de votre faute exemples pour réussir avec cette option.Comme pour votre à défaut d'exemples, ceux avec sans échappement
?
s va causer des problèmes comme?
n'est pas un caractère valide dans SQL. Entourant?
dans des guillemets simples, il se transforme en une simple chaîne de caractères, donc il n'est pas un paramètre de liaison, même si le traitement d'échappement est activé. Je ne peux pas dire pourquoi la dernière à ne pas écrire dans la base de données.INSERT INTO RACEBIKES (BIKENAME, COUNTRY_OF_ORIGIN, COST) VALUES ('JHT','USA', 2500)
échec?Très Sympa! L'appel de
preStatement.setEscapeProcessing(true);
était la réponse. Je l'avais mis à faux parce que dans certains autres endroits, j'ai été en utilisant cette même instance pour certains codée en dur requêtes où l'évasion de traitement n'est pas nécessaire. Dans ces cas, j'ai cru que l'omission de ces appels était plus efficace, mais jamais pensé que c'était aussi m'empêchant d'utiliser PreparedStatement comme il était prévu. @luc-woodward, merci beaucoup pour votre perspicacité!quel exemple, voulez-vous dire? Je ne vois pas pourquoi le SQL que vous avez mis dans votre commentaire doit échouer.
heureux d'entendre ma réponse aidé. Je ne peux pas dire si la désactivation de traitement d'échappement améliore les performances beaucoup (pour être honnête, je serais surpris si c'était le cas), mais la seule façon de le savoir serait à l'indice de référence. De temps combien de temps il faut à votre base de données d'exécution à travers une charge de votre codée en dur requêtes, une fois avec traitement d'échappement est activé et une fois avec elle handicapés, et de voir ce que la différence de temps entre les deux séries.
Je voulais dire une légère variation du deuxième exemple - avec des guillemets simples supprimé autour de
2500
. es0329 a été d'obtenir un ORA-00911 pour cela aussi. Et même avec traitement d'échappement s'est éteint, je ne comprends pas pourquoi cela échoue. Avez-vous une idée?OriginalL'auteur Luke Woodward