Groovy Sql und Oracle 'Ungültiger Spaltenindex' SQLException

Mit Groovys Schlüsselwort def sind einige geringfügige potenzielle Gefahren verbunden. Die Richtlinien für Groovy-Stile und Sprachfunktionen für Java-Entwickler enthalten einige Warnungen zur Verwendung von def. In diesem Blog-Beitrag zeige ich den Vorteil einer expliziteren Eingabe bei Verwendung von Groovy SQL mit einer Oracle-Datenbank, um eine potenzielle SQLException "Ungültiger Spaltenindex" zu vermeiden, da ich einige Male auf dieses Problem gestoßen bin.

Das folgende Groovy-Skript enthält Kommentare zu Oracle-Datenbanktabellen, die mit einer angegebenen Suchzeichenfolge übereinstimmen. In diesem Fall ist die Funktionsweise des Skripts nicht so wichtig wie der Code, der die SQL-Abfragezeichenfolge definiert (Zeilen 18-21).

searchDbComments.groovy (mit def ohne String-Eingabe oder als String)

#!/usr/bin/env groovy // searchDbComments.groovy this.class.classLoader.rootLoader.addURL( new URL("file:///C:/oraclexe/app/oracle/product/11.2.0/server/jdbc/lib/ojdbc6.jar")) if (args.length < 1) { println "USAGE: searchDbComments.groovy " System.exit(-1) } def searchString = args[0].toUpperCase() import groovy.sql.Sql def sql = Sql.newInstance("jdbc:oracle:thin:@localhost:1521:xe", "hr", "hr", "oracle.jdbc.pool.OracleDataSource") def dbTableCommentsQry = """ SELECT table_name, table_type, comments FROM user_tab_comments WHERE UPPER(comments) LIKE '%${searchString}%'""" sql.eachRow(dbTableCommentsQry) { println "${it.table_name} (${it.table_type}): ${it.comments}" } 

Wenn der obige Code ausgeführt wird, wird der folgende Fehler generiert:

WARNING: Failed to execute: SELECT table_name, table_type, comments FROM user_tab_comments WHERE UPPER(comments) LIKE '%?%' because: Invalid column index Caught: java.sql.SQLException: Invalid column index java.sql.SQLException: Invalid column index at oracle.jdbc.driver.OraclePreparedStatement.setStringInternal(OraclePreparedStatement.java:5303) at oracle.jdbc.driver.OraclePreparedStatement.setObjectCritical(OraclePreparedStatement.java:8323) at oracle.jdbc.driver.OraclePreparedStatement.setObjectInternal(OraclePreparedStatement.java:8259) at oracle.jdbc.driver.OraclePreparedStatement.setObjectInternal(OraclePreparedStatement.java:9012) at oracle.jdbc.driver.OraclePreparedStatement.setObject(OraclePreparedStatement.java:8993) at oracle.jdbc.driver.OraclePreparedStatementWrapper.setObject(OraclePreparedStatementWrapper.java:230) at searchDbComments.run(searchDbComments.groovy:23) 

Das Adressieren der SQLException "ungültiger Spaltenindex" ist einfach. Eine Lösung besteht darin, das "def" in den Zeilen 18-21 in einen expliziten "String" -Typ zu ändern. Eine andere Lösung, die in der nächsten Codeliste gezeigt wird, besteht darin, Groovys Schlüsselwort "als" zu verwenden, um explizit die Verwendung von "def" zu ermöglichen und die dbTableCommentsQryVariable als String eingeben zu lassen.

searchDbComments.groovy (als String verwenden)

#!/usr/bin/env groovy // searchDbComments.groovy this.class.classLoader.rootLoader.addURL( new URL("file:///C:/oraclexe/app/oracle/product/11.2.0/server/jdbc/lib/ojdbc6.jar")) if (args.length < 1) { println "USAGE: searchDbComments.groovy " System.exit(-1) } def searchString = args[0].toUpperCase() import groovy.sql.Sql def sql = Sql.newInstance("jdbc:oracle:thin:@localhost:1521:xe", "hr", "hr", "oracle.jdbc.pool.OracleDataSource") def dbTableCommentsQry = """ SELECT table_name, table_type, comments FROM user_tab_comments WHERE UPPER(comments) LIKE '%${searchString}%'""" as String sql.eachRow(dbTableCommentsQry) { println "${it.table_name} (${it.table_type}): ${it.comments}" } 

Die Verwendung von "def" nur oder ohne "def" ohne Typ führt zu dem obigen Fehler. Durch die explizite Definition der in der Abfrage verwendeten String-Variablen entweder durch statische Typisierung oder durch Verwendung des Schlüsselworts "as" kann der Code ordnungsgemäß ausgeführt werden. Man könnte eine statische Typisierung mit "def" verwenden, aber das wird als redundant angesehen.

Es ist nicht unbedingt falsch, "def" zu verwenden, aber man muss vorsichtig mit seiner Anwendung sein. Guillaume Laforge hat geschrieben, dass "def in Methodenkörpern oder für bestimmte dynamische Aspekte in Ordnung ist, aber für alles, was ein 'Vertrag' ist (Methodensignaturen, Eigenschaften usw.), ist es besser, explizite Typen zu verwenden."

Originalbeitrag verfügbar unter //marxsoftware.blogspot.com/ (Inspiriert von tatsächlichen Ereignissen)

Diese Geschichte "Groovy Sql und Oracle 'Ungültiger Spaltenindex' SQLException" wurde ursprünglich von JavaWorld veröffentlicht.