2017-01-23 497 views
1

我不明白爲什麼我得到「無效的列名稱」在這裏。java.sql.SQLException:無效的列名稱

我們在Oracle中直接嘗試過一種sql的變體,它工作正常,但是當我使用jdbcTemplate進行嘗試時,出現了一些問題。

List<Dataholder> alleXmler = jdbcTemplate.query("select p.applicationid, x.datadocumentid, x.datadocumentxml " + 
         "from CFUSERENGINE51.PROCESSENGINE p " + 
         "left join CFUSERENGINE51.DATADOCUMENTXML x " + 
         "on p.processengineguid = x.processengineguid " + 
         "where x.datadocumentid = 'Disbursment' " + 
         "and p.phasecacheid = 'Disbursed' ", 
       (rs, rowNum) -> { 
        return Dataholder.builder() 
          .applicationid(rs.getInt("p.applicationid")) 
          .datadocumentId(rs.getInt("x.datadocumentid")) 
          .xml(lobHandler.getClobAsString(rs, "x.datadocumentxml")) 
          .build(); 
       }); 

是在Oracle工作的整個SQL是這樣的:

select 
process.applicationid, 
xml.datadocumentid, 
xml.datadocumentxml 
from CFUSERENGINE51.PROCESSENGINE process 
left join CFUSERENGINE51.DATADOCUMENTXML xml 
on process.processengineguid = xml. processengineguid 
where xml.datadocumentid = 'Disbursment' 
and process.phasecacheid = 'Disbursed' 
and process.lastupdatetime > sysdate-14 

整個堆棧跟蹤:

java.lang.reflect.InvocationTargetException 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
    at java.lang.reflect.Method.invoke(Method.java:498) 
    at org.springframework.boot.maven.AbstractRunMojo$LaunchRunner.run(AbstractRunMojo.java:507) 
    at java.lang.Thread.run(Thread.java:745) 
Caused by: java.lang.IllegalStateException: Failed to execute CommandLineRunner 
    at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:803) 
    at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:784) 
    at org.springframework.boot.SpringApplication.afterRefresh(SpringApplication.java:771) 
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:316) 
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1186) 
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1175) 
    at no.gjensidige.bank.datavarehus.kontonrinfridd.Application.main(Application.java:44) 
    ... 6 more 
Caused by: org.springframework.jdbc.BadSqlGrammarException: StatementCallback; bad SQL grammar [select p.applicationid, x.datadocumentid, x.datadocumentxml from CFUSERENGINE51.PROCESSENGINE p left join CFUSERENGINE51.DATADOCUMENTXML x on p.processengineguid = x.processengineguid where x.datadocumentid = 'Disbursment' ]; nested exception is java.sql.SQLException: Invalid column name 
    at org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator.doTranslate(SQLErrorCodeSQLExceptionTranslator.java:231) 
    at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:73) 
    at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:419) 
    at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:474) 
    at org.springframework.jdbc.core.JdbcTemplate.query(JdbcTemplate.java:484) 
    at no.gjensidige.bank.datavarehus.kontonrinfridd.Application.run(Application.java:61) 
    at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:800) 
    ... 12 more 
Caused by: java.sql.SQLException: Invalid column name 
    at oracle.jdbc.driver.OracleStatement.getColumnIndex(OracleStatement.java:4146) 
    at oracle.jdbc.driver.InsensitiveScrollableResultSet.findColumn(InsensitiveScrollableResultSet.java:300) 
    at oracle.jdbc.driver.GeneratedResultSet.getString(GeneratedResultSet.java:1460) 
    at org.apache.commons.dbcp2.DelegatingResultSet.getString(DelegatingResultSet.java:267) 
    at org.apache.commons.dbcp2.DelegatingResultSet.getString(DelegatingResultSet.java:267) 
    at no.gjensidige.bank.datavarehus.kontonrinfridd.Application.lambda$run$0(Application.java:69) 
    at org.springframework.jdbc.core.RowMapperResultSetExtractor.extractData(RowMapperResultSetExtractor.java:93) 
    at org.springframework.jdbc.core.RowMapperResultSetExtractor.extractData(RowMapperResultSetExtractor.java:60) 
    at org.springframework.jdbc.core.JdbcTemplate$1QueryStatementCallback.doInStatement(JdbcTemplate.java:463) 
    at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:408) 
    ... 16 more 
+0

您的表格是如何定義的?該變種如何直接在Oracle上嘗試?請將它們添加到您的問題。 – Alfabravo

+0

@Alfabravo我真的不知道。我收到了某人發來的這個數據庫,他告訴我它直接在Oracle中運行。所以我知道它應該工作。但是「無效的列名」意味着它不是Oracle的錯誤,而是spring-jdbc自身。所以這應該是我認爲很明顯的事情。只是不在我:) –

+0

所以你甚至沒有無效列的名稱?我們應該如何幫助你? –

回答

6

的問題是不是查詢。查詢運行良好。

問題在於將行從ResultSet轉換爲域對象的行映射。看起來,作爲應用程序行映射的一部分,您嘗試從其不包含的列中讀取ResultSet的值。

您的堆棧跟蹤的關鍵線以下三種,接近底部:

at org.apache.commons.dbcp2.DelegatingResultSet.getString(DelegatingResultSet.java:267) 
    at no.gjensidige.bank.datavarehus.kontonrinfridd.Application.lambda$run$0(Application.java:69) 
    at org.springframework.jdbc.core.RowMapperResultSetExtractor.extractData(RowMapperResultSetExtractor.java:93) 

這三條線的中間會出現在你的代碼。 Application類的第69行包含一個調用ResultSet.getString()的lambda,但由於這會導致「無效列名稱」錯誤,因此(a)傳遞的是字符串而不是數字列索引,而(b) )您傳入的列名不存在於結果集中。

現在您已經編輯了您的問題以包含對jdbcTemplate.query()的調用,特別是負責將結果集行映射到對象的lambda表達式,問題會更清楚一些。當與索引相對應地呼叫rs.getInt(...)rs.getString(...)時,不要包括諸如p.x.之類的前綴。不要寫rs.getInt("p.applicationid")rs.getInt("x.datadocumentid"),請寫rs.getInt("applicationid")rs.getInt("datadocumentid")

+0

我認爲你在這裏的東西。它缺乏關於jdbcTemplate如何工作的知識。我已經用我如何讀取數據的代碼更新了這個問題。你能看看嗎?我將getString()更改爲getInt,但它仍然無效。 –

+0

我終於使用getObject(int index)工作了。謝謝。從錯誤信息中不太清楚。 –

+1

@ShervinAsgari:從調用getInt或getString的列名稱中刪除前綴「p.'和」x「:它們應該是applicationid或datadocumentid而不是'''p.applicationid'或者'x.datadocumentid'。 –

0

您需要的表定義,找出問題的所在。安裝/運行Oracle SQL Developer(它是免費的),設置JDBC連接並調查架構。

您需要檢查以下幾列的存在:

CFUSERENGINE51.PROCESSENGINE.applicationid, 
CFUSERENGINE51.PROCESSENGINE.lastupdatetime 
CFUSERENGINE51.PROCESSENGINE.phasecacheid 
CFUSERENGINE51.PROCESSENGINE.processengineguid 
CFUSERENGINE51.DATADOCUMENTXML.datadocumentid 
CFUSERENGINE51.DATADOCUMENTXML.datadocumentxml 
CFUSERENGINE51.DATADOCUMENTXML.processengineguid