2016-09-02 79 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 ...如果您没有在表名称后放置空格,但对于普通调用,这是完全可能的!

编辑: 这显然是不一致的(撇开究竟是一个有效的插入)应始终如一地接受或拒绝此查询不管我呼吁元数据与否。