How do I use PL/SQL to_date with a variable in Groovy?
I've got the following small Groovy script that just does a count of rows in the database for a specific date.
import groovy.sql.Sql
def today= new GregorianCalendar()
def dateString = "${today.get(Calendar.MONTH)+1}/${today.get(Calendar.DAY_OF_MONTH)-1}/${today.get(Calendar.YEAR)}"
def sql = Sql.newInstance("jdbc:oracle:thin:bc/bc@nemesis:1521:billctr", "bc","bc", "oracle.jdbc.OracleDriver")
def sqlLine = "select count(id) as count from bc_payment where trunc(paymentdate) = to_date(${dateString}, \'MM/DD/YYYY\')"
println(sqlLine)
def payCount = sql.execute(sqlLine)
println payCount
to_date requires single-quotes around the date you pass in. If I leave them off, I get SQLException: Invalid column type
but if I put \' around the variable, I get a warning from Groovy
WARNING: In Groovy SQL please do not use quotes around dynamic expressions (which start with $) as this means we cannot use a JDBC PreparedStatement and so is a security hole. Groovy has worked around your mistake but the security hole is still there. The expression so far is: select count(id) as count from bc_payment where trunc(paymentdate) = to_date('?', 'MM/DD/YYYY')
Is there a better way of doing this without to_date or formatting the variable differently? I'm new to Groovy so any suggestions are welcome. Thanks in adv开发者_开发技巧ance!
Try the following (I hope I haven't introduced a syntax error, no Groovy here...)
import groovy.sql.Sql
def today= new java.sql.Date(new java.util.Date().getTime())
def sql = Sql.newInstance("jdbc:oracle:thin:bc/bc@nemesis:1521:billctr", "bc","bc", "oracle.jdbc.OracleDriver")
def sqlLine = "select count(id) as count from bc_payment where trunc(paymentdate) = ?"
println(sqlLine)
def payCount = sql.execute(sqlLine, [today])
println payCount
Edit: replaced
def today = new Date()
with
def today= new java.sql.Date(new java.util.Date().getTime())
Late answer by a developer with similar problems.
I found that the problem was could be fixed by changing the declaration:
def sqlLine = "... ${yourString} ..."
... which creates sqlLine as a GStringImpl-object. If instead you declare sqlLine like this:
String sqlLine = "... ${yourString} ..."
... we resolve the variables inline and receive a String-object. This way groovy.sql.Sql never know that we created the sql dynamically.
Actually you can read the sql instance parameters from the DataSource doing the followng:
def _url = ConfigurationHolder.config.dataSource.url
def _username = ConfigurationHolder.config.dataSource.username
def _password = ConfigurationHolder.config.dataSource.password
def _driver = ConfigurationHolder.config.dataSource.driverClassName
def sql = Sql.newInstance(_url, _username, _password, _driver)
// For the paging
def int max = Math.min(params.max ? params.max.toInteger() : 25, 100)
def int offset = params.offset.toInteger()
def int last = offset + max
def month= params.month_value
I use Oracle TO_DATE and TO_TIMESTAMP function. In my case it is as follows:
query = "select * from " +
"(SELECT reporting.id, " +
"company_id as comp, " +
"to_date(TO_CHAR(invoice,'dd.mm.YYYY')) as invoice, " +
"TO_CHAR(last_updated,'dd.mm.YYYY HH:MI') as erstelltAm, " +
"row_number() over (" + sortByStr + ") as row_num FROM reporting, company " +
"WHERE reporting.company_id = company.id) " +
"reporting.month = TO_TIMESTAMP(" + month + ", 'dd.mm.yy')""
"where ROW_NUM between " + offset + " and " + last;
精彩评论