2009-11-09 38 views
0

我有以下小Groovy腳本,只是在特定的日期數據庫中的行數。如何使用Groovy中的變量使用PL/SQL to_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/[email protected]: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') 
警告

有沒有更好的方式做到這一點,而不是以不同的方式對變量進行格式化?我是Groovy的新手,因此歡迎任何建議。提前致謝!

回答

2

試試下面的(我希望我沒有出臺一個語法錯誤,沒有Groovy的在這裏...)

import groovy.sql.Sql 

def today= new java.sql.Date(new java.util.Date().getTime()) 

def sql = Sql.newInstance("jdbc:oracle:thin:bc/[email protected]: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()) 
+0

我想你需要一個java.sql.Date實例,以便將它與沒有時間戳的Date列進行比較。 – 2009-11-09 20:39:06

+0

謝謝Christoph,我想我已經解決了它。 – 2009-11-09 22:09:49

1

實際上,您可以從DataSource中讀取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_DATETO_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; 
2

最近有一個類似問題的開發人員回答。

我發現,這個問題是可以通過改變聲明中的固定:

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

...它創建sqlLine作爲GStringImpl對象。如果相反,你聲明sqlline是這樣的:

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

...我們解析變量內聯並接收一個String對象。這樣groovy.sql.Sql永遠不會知道我們是動態創建的。

+0

您還沒有修復安全風險,您只是欺騙了Groovy無法發現它,所以它不顯示警告。 – 2016-08-20 00:00:14