2010-09-25 16 views
1

Le problème en quelques mots:Pourquoi l'utilisation d'une instruction préparée échoue-t-elle avec des valeurs NULL et réussie avec GStrings?

C'est ce qui se passe lorsque vous essayez d'insérer une ligne avec quelques colonnes nulles en utilisant une déclaration préparée et groovy.sql.Sql:

groovy:000> val 
===> [123123123, 2, null, 0, 0, , null, , 1213020112511801, 1283425009158952, 1, 2, null, 0, 0, , null, , 1213020112511801, 1283425009158952] 
groovy:000> destSql.execute "insert into my_table values (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", val 
ERROR java.sql.SQLException: Type is not supported. 
     at org.apache.derby.client.am.SQLExceptionFactory40.getSQLException (Unknown Source) 
     at org.apache.derby.client.am.SqlException.getSQLException (Unknown Source) 
     at org.apache.derby.client.am.PreparedStatement.setObject (Unknown Source) 
     at groovysh_evaluate.run (groovysh_evaluate:3) 
     ... 
groovy:000> 

-je obtenir un résultat similaire avec destSql.dataSet("my_table").add valueMap.

C'est ce qui se passe lorsque vous essayez d'insérer la même ligne comme GString:

groovy:000> destSql.execute "insert into my_table values (${val[0]}, ${val[1]}, ${val[2]}, ${val[3]}, ${val[4]}, ${val[5]}, ${val[6]}, ${val[7]}, ${val[8]}, ${val[9]})" 
===> false 
groovy:000> 

Maintenant, je comprends qu'il ya des problèmes d'insérer des valeurs nulles à l'aide d'une instruction préparée (comme documenté par exemple here et here).

Ce que je voudrais comprendre est la suivante:

1) Je trouve qu'il est difficile de croire que l'insertion des déclarations préparées nulls est impossible, alors pourquoi il ne provoque parfois des problèmes? Pilotes JDBC moins que parfaits, moteurs de base de données?

2) Pourquoi l'exemple avec le GString ne fonctionne? Suivant la même logique, ne tape-t-il pas encore des informations sur les colonnes nulles, alors comment cela fonctionne-t-il?

Répondre

1

Vous obtiendrez de meilleures réponses si vous incluez l'exception réelle que vous J'ai rencontré. Vous pouvez trouver l'exception dans le fichier derby.log de votre serveur Derby, ou vous pouvez également modifier votre application pour imprimer toute la chaîne d'exception, et pas seulement l'exception externe côté client: http://wiki.apache.org/db-derby/UnwindExceptionChain

Sans voir l'exception réelle, c'est assez dur pour vous aider, mais je vais hasarder une hypothèse que vous voyez https://issues.apache.org/jira/browse/DERBY-1938

+0

était un excellent lien Bryan, je crois qu'il explique bien pourquoi le problème est intermittent (certaines combinaisons de pilotes, et SGBDR mode d'utilisation) et pourquoi l'aide d'une déclaration préparée ne fonctionne pas dans mon cas. –

+0

Avez-vous une idée du fonctionnement de l'approche GStrings? J'écrémé sur la source groovy.sql.Sql et a vu qu'il tente également de créer une déclaration préparée ... après avoir passé il « objet » plutôt que des valeurs « String », je ne peux pas imaginer comment il pourrait fonctionner autrement, mais Derby on rejeter une instruction préparée avec une valeur nulle ...? –

+0

Je suis assez sûr que, pour un certain nombre de versions, PreparedStatement.setString (N, null) a bien fonctionné à Derby, mais PreparedStatement.setObject (N, null) a échoué. C'était l'essence du problème que DERBY-1938 a résolu, je crois. Donc, peut-être, en fonction des types de données précis que votre programme Groovy utilisait, la bibliothèque Groovy SQL appelait parfois setString, et d'autres fois appelait setObject? –

0

L'exemple gstring fonctionne parce que le code ${val[0]} renverra null si l'élément de tableau est null.

si le code inséré dans la question est correcte, certains d'entre vous ne éléments ont pas une valeur null ... ce juste une supposition

+0

vous pouvez voir les valeurs que j'essayé d'insérer: ils représentent un enregistrement valide avec deux champs mis à null. '$ {val [0]}' renverra en effet null, mais pourquoi Derby l'accepte-t-il et n'accepte pas une valeur nulle en tant que paramètre d'une instruction préparée? Ce –