我有一个奇怪的问题。我正在使用这样的预处理语句执行insert:
arr = "1,2,3,4"
arr = list(map(int,arr.rsplit(',', len(arr))))
print(sum(arr))
Insert语句是这样的:
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 ( ?, ?, ? )
声明中没有WHERE,所以我很困惑为什么它在元数据提取上失败了......
修改
SQL Server = 10.50.2500.0 Express Edition, 来自4.0包的Driver = sqljdbc4.jar
另外,我使用的是getParameterMetaData,因为我需要将一些params设置为null,首选方法是使用需要SQLType的setNull()。
EDIT2: 我已经使用最新的6.0软件包中的Driver sqljdbc41进行了测试 - 结果是相同的
EDIT3: 我已经删除了对getParameterMetaData()的调用并且它工作了,不幸的是它是一个通用的部分,应该是最大的可移植性,但它不适用于这个单个表(插入到同一个数据库上的其他表工作正常!)
EDIT4:
我已尝试使用此表的不同插入语句,如果我跳过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)
并且在调用它时失败,则所有这些都可以正常工作。如果我尝试使用2个或更多参数,我会遇到ps.getParameterMetaData()
错误。如果我尝试一个列插入,我会收到一个错误,指出列名不正确,即使它是正确的,没有元数据调用它也可以正常工作。我将尝试跟踪司机在下面尝试做什么......
答案 0 :(得分:1)
在对驱动程序实际执行的操作进行一些跟踪之后(非常感谢 a_horse_with_no_name ),我得出了一些有趣的结论。
我的问题的解决方案是:
替换以下插入语句
INSERT INTO CurrencyRates(RateDate, CurrencyID, Rate) VALUES ( ?, ?, ? )
使用此声明
INSERT INTO CurrencyRates (RateDate, CurrencyID, Rate) VALUES ( ?, ?, ? )
背后的逻辑是SQL驱动程序在后台进行一些元数据提取,如果你没有在表名之后放置空格,它会创建一个包含以下片段的查询:... FROM CurrencyRates(RateDate WHERE ...
,但对于普通调用,这是完美的可能!
修改强> 这显然是不一致的(暂时放置实际上是有效的插入)它应该始终接受或拒绝此查询,无论我是否调用元数据。