2013-06-19 13 views
0

我試圖從RedShift使用Java + Hibernate卸載數據到S3,但無法弄清楚如何讓它接受字符串中的字符串SQL。Java,PostgreSQL和Hibernate:Select語句嵌套字符串

無論我嘗試使用正確傳遞給RedShift的引號字符的轉義序列,我只是在異常之後得到異常。

任何想法都會受到歡迎。謝謝。

這裏是我試圖在紅移運行查詢(如果我鍵入此直接進入紅移,它的工作原理):

unload ('select raw_line from stl_load_errors where starttime > \'2013-01-01\' ') 
    to 's3://myBucket/myTable/' 
    credentials 'aws_access_key_id=*;aws_secret_access_key=*' gzip; 

這裏是我在Java中嘗試了各種命令,用錯誤我遇到:

單反斜線

session.createSQLQuery("unload ('select raw_line from stl_load_errors where starttime > \'2013-01-01\' ')" 
    + " to 's3://myBucket/myTable/'" 
    + " credentials 'aws_access_key_id=" + key + ";aws_secret_access_key=" + secret + "' gzip") 
    .executeUpdate(); 

成績
WARN org.hibernate.engine.jdbc.spi.SqlExceptionHelper - SQL錯誤:0,SQLState:42601
錯誤org.hibernate.engine.jdbc.spi.SqlExceptionHelper - 錯誤:語法錯誤處於或接近「2013」​​位置:66
錯誤org.hibernate.exception.SQLGrammarException:無法執行語句

雙反斜線

session.createSQLQuery("unload ('select raw_line from stl_load_errors where starttime > \\'2013-01-01\\' ')" 
    + " to 's3://myBucket/myTable/'" 
    + " credentials 'aws_access_key_id=" + key + ";aws_secret_access_key=" + secret + "' gzip") 
    .executeUpdate(); 

成績
錯誤org.hibernate.QueryException:在參數前綴':'[unload('從stl_load_errors中選擇raw_line,其中starttime> \'2013-01-01 \'')'s3:// myBucket/myTable/「憑證 'aws_access_key_id = *; aws_secret_access_key = *' 的gzip]
在org.hibernate.engine.query.spi.ParameterParser.parse(ParameterParser.java:95)

三重反斜槓

session.createSQLQuery("unload ('select raw_line from stl_load_errors where starttime > \\\'2013-01-01\\\' ')" 
    + " to 's3://myBucket/myTable/'" 
    + " credentials 'aws_access_key_id=" + key + ";aws_secret_access_key=" + secret + "' gzip") 
    .executeUpdate(); 

結果
2013-06-19 01:39:59,233錯誤org.hibernate.QueryExceptio n:在參數前綴':'之後不允許空格:[unload('從stl_load_errors中選擇raw_line,其中starttime> \'2013-01-01 \'')爲's3:// myBucket/myTable /'憑證'aws_access_key_id = * ; aws_secret_access_key = *」的gzip]
在org.hibernate.engine.query.spi.ParameterParser.parse(ParameterParser.java:95)

四反斜槓

session.createSQLQuery("unload ('select raw_line from stl_load_errors where starttime > \\\\'2013-01-01\\\\' ')" 
    + " to 's3://myBucket/myTable/'" 
    + " credentials 'aws_access_key_id=" + key + ";aws_secret_access_key=" + secret + "' gzip") 
    .executeUpdate(); 

成績
WARN org.hibernate.engine.jdbc.spi.SqlExceptionHelper - SQL錯誤:0,SQLState:42601
錯誤org.hibernate.engine.jdbc.spi.SqlExceptionHelper - 錯誤:在「2013」​​或其附近的語法錯誤位置:68
錯誤org.hibernate.exception。SQLGrammarException:無法執行語句

命名參數

session.createSQLQuery("unload (:query)" 
    + " to 's3://myBucket/myTable/'" 
    + " credentials 'aws_access_key_id=" + key + ";aws_secret_access_key=" + secret + "' gzip") 
    .setString("query", "select raw_line from stl_load_errors where starttime > '2013-01-01'") 
    .executeUpdate(); 

結果:
WARN org.hibernate.engine.jdbc.spi.SqlExceptionHelper - SQL錯誤:0,SQLSTATE:42601
錯誤org.hibernate.engine.jdbc.spi.SqlExceptionHelper - 錯誤:語法錯誤或接近「$ 1」的位置:9
錯誤org.hibernate.exception.SQLGrammarException:無法執行語句

+0

你是把密鑰和密碼不參數化,SQL注入攻擊,爲什麼不把日期參數化嗎? :日期:關鍵:祕密 – nachokk

+0

如果我能得到任何的這個工作,我一定會清理(命名參數各地​​,這樣) – Tinclon

回答

0

我被給出了建議,嘗試將s3路徑作爲命名參數,因爲Hibernate(在雙反斜槓和三重反斜槓的情況下)似乎不喜歡冒號字符。

這樣做,給了我這個錯誤:

ERROR java.lang.IllegalArgumentException: Parameter s3 does not exist as a named parameter in [unload ('select raw_line from stl_load_errors where starttime > \'2014-01-01\'') to :s3 credentials 'aws_access_key_id=*;aws_secret_access_key=*' gzip]

我得到的休眠是感到困惑與轉義單引號和失去跟蹤什麼應該被引用,哪些不是(的印象s3之後的冒號不應該首先出現問題,因爲它在引用文本中,但顯然Hibernate無法弄清楚)。

有時你太接近問題。不去想它了一會兒,明顯的解決方案(解決方法,真的)之後,就是我會做以下幾點:

  1. 創建臨時表
  2. 插入所需的數據到臨時表(無需嵌套字符串)
  3. 卸載臨時表的全部內容S3(無需嵌套字符串)
  4. 刪除臨時表