2016-09-02 113 views
1

我有一個奇怪的問題。我用準備好的聲明中這樣執行插入:JDBC MSSQL插入失敗,錯誤「near where」

try (Connection connection = connectionPool.getConnection(); 
    PreparedStatement ps = connection.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS)) { //TODO: caching of PS 
    int i = 1; 
    ParameterMetaData pmd = ps.getParameterMetaData(); 
    ... 
} catch (SQLException e) { 
    throw new TGFIOException("Error executing SQL command " + sql, e); 
} 

Insert語句是這樣的:

insert into dbo.CurrencyRates(RateDate, CurrencyID, Rate) values (?, ?, ?) 

不幸的是失敗,以下情況除外:

com.microsoft.sqlserver.jdbc.SQLServerException: com.microsoft.sqlserver.jdbc.SQLServerException: Incorrect syntax near the keyword 'WHERE'. 
    at com.microsoft.sqlserver.jdbc.SQLServerException.makeFromDriverError(SQLServerException.java:190) 
    at com.microsoft.sqlserver.jdbc.SQLServerParameterMetaData.<init>(SQLServerParameterMetaData.java:426) 
    at com.microsoft.sqlserver.jdbc.SQLServerPreparedStatement.getParameterMetaData(SQLServerPreparedStatement.java:1532) 
    at com.jolbox.bonecp.PreparedStatementHandle.getParameterMetaData(PreparedStatementHandle.java:246) 

沒有在WHERE聲明,所以我很困惑它爲什麼在元數據提取上失敗...

編輯:

SQL服務器= 10.50.2500.0速成版, 驅動= 4.0包

而且sqljdbc4.jar,我使用getParameterMetaData,因爲我需要設置一些PARAMS爲null,首選的方法是在需要SQLType的地方使用setNull()。

EDIT2: 我和司機從sqljdbc41 6.0最新測試包 - 結果是相同的

EDIT3: 我已經刪除調用getParameterMetaData()和它的工作,遺憾的是它是應該最大便攜,但它不符合這個單一的工作表中的通用部分(在同一個數據庫插入到其他表工作正常!)

EDIT4: 我試着用不同的櫻雪這個表的rt語句,如果我跳過ps.getParameterMetaData(),所有這些語句都可以正常工作,但在我調用它時會失敗。如果我嘗試使用2個或更多參數,則通常會出現near WHERE錯誤。如果我嘗試插入一列,我會收到一個錯誤消息,說明列名是不正確的,即使它是正確的並且沒有元數據調用它也可以很好地工作。我會嘗試跟蹤驅動程序試圖在底下做什麼...

+1

你確定在執行插入語句時是否失敗嗎?看起來有些選擇語句執行失敗。 – Karthik

+3

也許是因爲'Statement.RETURN_GENERATED_KEYS',驅動程序向語句添加了一些額外的條件來實現這一點。您可以嘗試跟蹤發送到服務器的語句。也可能是'getParameterMetaData()'需要第二次往返數據庫,在這期間發送的語句無效。你使用哪個版本的驅動程序和哪個SQL Server版本?也許他們不匹配。 –

+1

您在哪裏設置準備好的語句插入值?像setint設置字符串等 –

回答

1

經過一些實際驅動程序(非常感謝a_horse_with_no_name)的跟蹤後,我得出了一些有趣的結論。

我的問題的解決方案是:

替換下面的INSERT語句

  • INSERT INTO CurrencyRates(RateDate, CurrencyID, Rate) VALUES ( ?, ?, ?)

這種說法

  • INSERT INTO CurrencyRates (RateDate, CurrencyID, Rate) VALUES ( ?, ?, ?)

後面的邏輯是SQL驅動程序在後臺執行一些元數據提取,並且它會創建一個帶有以下片段的查詢:... FROM CurrencyRates(RateDate WHERE ...如果您沒有在表名稱後放置空格,但對於普通調用,這是完全可能的!

編輯: 這顯然是不一致的(撇開究竟是一個有效的插入)應始終如一地接受或拒絕此查詢不管我呼籲元數據與否。