【发布时间】:2017-01-10 03:27:11
【问题描述】:
我有一个奇怪的问题。我正在使用这样的准备好的语句执行插入:
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 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 Server = 10.50.2500.0 快捷版, Driver = 4.0 包中的 sqljdbc4.jar
另外,我使用 getParameterMetaData 是因为我需要将一些参数设置为 null,而首选方法是在需要 SQLType 的地方使用 setNull()。
EDIT2: 我已经用最新的 6.0 包中的驱动程序 sqljdbc41 进行了测试 - 结果是一样的
EDIT3: 我已经删除了对 getParameterMetaData() 的调用并且它起作用了,不幸的是它是一个应该最大可移植的通用部分,但它不适用于这个单个表(插入到同一数据库上的其他表工作正常!!!)
EDIT4:
我已经为这个表尝试了不同的插入语句,如果我跳过ps.getParameterMetaData() 并且在我调用它时失败,它们都可以正常工作。如果我尝试使用 2 个或更多参数,我会得到通常的 near WHERE 错误。如果我尝试插入一列,我会收到一条错误消息,指出列名不正确,即使它是正确的并且没有元数据调用,它也可以正常工作。我将尝试追踪驱动程序试图在下面做什么......
【问题讨论】:
-
你确定它在执行插入语句时是否失败?似乎某些选择语句执行失败。
-
可能是因为
Statement.RETURN_GENERATED_KEYS并且驱动程序在语句中添加了一些额外的条件来实现这一点。您可以尝试跟踪发送到服务器的语句。也可能是getParameterMetaData()需要第二次往返数据库,并且在此期间发送了无效的语句。您使用的是哪个版本的驱动程序和哪个 SQL Server 版本?也许他们不匹配。 -
您在哪里设置准备好的语句插入值?比如 setint 设置字符串等。
-
请在连接字符串中添加
jdbc:mysql://localhost:3306/mydb?generateSimpleParameterMetadata=true,然后尝试运行。 -
为什么需要调用getParameterMetadata()。如果您只需要返回生成的(插入的)密钥,那么您可以简单地调用 ps.getGeneratedKeys() 并从 ResultSet 中提取密钥。
标签: java sql-server jdbc