Groovy Sql dan Oracle 'Invalid column index' SQLEception

Ada beberapa potensi bahaya kecil yang terkait dengan kata kunci def Groovy. Panduan fitur bahasa dan gaya Groovy untuk developer Java menyediakan beberapa peringatan tentang penggunaan def. Dalam posting blog ini, saya menunjukkan keuntungan menjadi lebih eksplisit dalam mengetik saat menggunakan Groovy SQL dengan database Oracle untuk menghindari potensi SQLException "Indeks kolom tidak valid" karena saya telah mengalami masalah ini beberapa kali.

Skrip Groovy berikut memberikan komentar pada tabel database Oracle yang cocok dengan string pencarian yang disediakan. Dalam hal ini, apa yang dilakukan skrip tidak sepenting melihat kode yang mendefinisikan string kueri SQL (baris 18-21).

searchDbComments.groovy (menggunakan def tanpa mengetik String atau sebagai 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}" } 

Ketika kode di atas dijalankan, kesalahan berikut dihasilkan:

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) 

Mengatasi "indeks kolom tidak valid" SQLException itu mudah. Salah satu solusinya adalah dengan mengubah "def" pada baris 18-21 menjadi tipe "String" yang eksplisit. Solusi lain, yang ditampilkan dalam daftar kode berikutnya, adalah dengan menggunakan kata kunci pemaksaan "as" Groovy untuk secara eksplisit mengizinkan "def" digunakan dan dbTableCommentsQryvariabel diketik sebagai String.

searchDbComments.groovy (menggunakan sebagai 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}%'""" as String sql.eachRow(dbTableCommentsQry) { println "${it.table_name} (${it.table_type}): ${it.comments}" } 

Menggunakan "def" saja atau tanpa "def" tanpa tipe sama sekali menyebabkan kesalahan di atas. Mendefinisikan secara eksplisit variabel String yang digunakan dalam kueri baik melalui pengetikan statis atau melalui penggunaan kata kunci "sebagai" memungkinkan kode dijalankan dengan benar. Seseorang dapat menggunakan pengetikan statis dengan "def", tetapi itu dianggap berlebihan.

Tidak ada yang salah tentang menggunakan "def," tetapi kita perlu berhati-hati dengan penerapannya. Guillaume Laforge telah menulis bahwa "def baik-baik saja dalam badan metode atau untuk aspek dinamis tertentu, tetapi untuk segala sesuatu yang merupakan 'kontrak' (tanda tangan metode, properti, dll), lebih baik menggunakan tipe eksplisit."

Pengeposan asli tersedia di //marxsoftware.blogspot.com/ (Terinspirasi oleh Acara Aktual)

Artikel ini, "Groovy Sql dan Oracle 'Invalid column index' SQLException" awalnya diterbitkan oleh JavaWorld.