Как использовать PL / SQL to_date с переменной в Groovy? - PullRequest
0 голосов
/ 09 ноября 2009

У меня есть следующий небольшой скрипт Groovy, который просто подсчитывает количество строк в базе данных на определенную дату.

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 требует одинарных кавычек вокруг даты, в которую вы переходите. Если я оставлю их, я получу SQLException: Invalid column type, но если я поставлю переменную вокруг, я получу предупреждение от 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')

Есть ли лучший способ сделать это без to_date или по-другому отформатировать переменную? Я новичок в Groovy, поэтому любые предложения приветствуются. Заранее спасибо!

Ответы [ 3 ]

2 голосов
/ 01 февраля 2012

Поздний ответ от разработчика с похожими проблемами.

Я обнаружил, что проблему можно решить, изменив объявление:

def sqlLine = "... ${yourString} ..."

... который создает sqlLine как объект GStringImpl. Если вместо этого вы объявляете sqlLine следующим образом:

String sqlLine = "... ${yourString} ..."

... мы разрешаем переменные inline и получаем объект String. Таким образом groovy.sql.Sql никогда не узнает, что мы создали sql динамически.

2 голосов
/ 09 ноября 2009

Попробуйте следующее (надеюсь, я не ввел синтаксическую ошибку, здесь нет Groovy ...)

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

Редактировать: заменено

def today = new Date()

с

def today= new java.sql.Date(new java.util.Date().getTime())
1 голос
/ 19 января 2010

На самом деле вы можете прочитать параметры экземпляра sql из источника данных, выполнив следующее:

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

Я использую функцию Oracle TO_DATE и TO_TIMESTAMP . В моем случае это выглядит следующим образом:

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;
...