在不知道数据类型的情况下将值绑定到 PreparedStatement

Posted

技术标签:

【中文标题】在不知道数据类型的情况下将值绑定到 PreparedStatement【英文标题】:Binding Values To PreparedStatement without knowing the data types 【发布时间】:2013-10-15 14:36:22 【问题描述】:

使用 setObject(index,object) 将值绑定到preparedstatement 使用mysql 可以正常工作,但不能使用Oracle。

preparedStatement.setObject(i, bindValue);

以下是附加绑定变量后构建的查询。

select ACC_NO from ACC_TABLE where ACC_NAME='java.lang.String';

正在尝试转换为java.lang.String类型,导致如下异常:

java.sql.SQLException:无法执行 sql 命令 - 原始消息:null

而我的 ACC_NAME 是“user01”。

所以实际上查询应该是这样的,

select ACC_NO from ACC_TABLE where ACC_NAME='user01';

所以,如果我的理解没有错的话,preparedStatement.setObject(index, object) 正在将数据转换成其各自的数据类型并进行设置。

preparedStatement.setObject(index, object) 在 MySQL 中运行良好,没有任何问题。

唯一的问题是在使用 Oracle 时。

我正在使用的 Oracle DB 版本是:

Oracle 数据库 11g 快捷版 11.2.0.2.0 版 - 生产 PL/SQL 版本 11.2.0.2.0 - 生产“CORE 11.2.0.2.0 生产” 适用于 32 位 Windows 的 TNS:版本 11.2.0.2.0 - 生产 NLSRTL 版本 11.2.0.2.0 - 生产

【问题讨论】:

请包含异常的堆栈跟踪并在您的问题中添加一些格式(例如代码格式)。 您确定 bindValue 包含 'user01' 吗?当你尝试preparedStatement.setObject(i, 'user01'); 时会发生什么? @Mark Rotteveel :从现在开始肯定会这样做,感谢格式化。 @A.B.Cade 是的,变量 bindValue 的值为 'user01'。 你看过getParameterMetaData(),它应该可以帮助你决定类型(特别是getParameterType() 【参考方案1】:

我不知道确切的答案,但是...

方法 setObject(index, Object) 可用于通过使用特定于驱动程序的 Java 类型来传递特定于数据库的抽象数据类型。如果对象属于实现接口 SQLData 的类,则 JDBC 驱动程序应调用方法 SQLData.writeSQL 将其写入 SQL 数据流。另一方面,如果对象属于实现 Ref、Blob、Clob、NClob、Struct、java.net.URL、RowId、SQLXML 或 Array 的类,则驱动程序应将其作为相应的值传递给数据库SQL 类型。 --- 收集自 Java 文档

【讨论】:

@user245830: setObject(1, "user01") 在这种情况下,它不是任何类型的对象,它只是字符串类型的原语。当我不知道正在传递的对象的数据类型时,我正在尝试使用setObject(index, Object)。例如,setString(index, String) 用于数据类型 String,setInt(index, int) 用于数据类型 int,但我不使用数据类型,因此尝试使用设置 DataType '的setObject(index, Object) java.lang.String' 作为结果集为空的值。生成的示例查询低于select ACC_NO from ACC_TABLE where ACC_NAME='java.lang.String';

以上是关于在不知道数据类型的情况下将值绑定到 PreparedStatement的主要内容,如果未能解决你的问题,请参考以下文章

在不循环的情况下将值更新到数据集中列中的整行

我应该如何在不使用 C++ 中的构造函数的情况下将值(不是指针)转换为子类?

如何在不使用 C++/C 中的阻塞函数的情况下将值从线程返回到主函数

在不知道元素类型的情况下将项添加到列表中

c#在不退出子线程的情况下将值从子线程传递给父线程

如何在不循环的情况下将数组(Range.Value)传递给本机 .NET 类型?