使用 spring StoredProcedure 插入 oracle clob IN 参数时克服 32k 限制
overcome 32k limit when inserting oracle clob IN parameter using spring StoredProcedure
环境:oracle 11g,spring-jdbc-3.2.2-RELEASE.jar,JDK 1.7,Oracle UCP 驱动程序。
我有一个存储过程,可以将记录插入到带有 CLOB 列的 table。 SP 在其他 IN 和 OUT 参数中有一个 CLOB 输入参数。我的 Java 代码使用 Spring StoredProcedure 来调用存储过程:
public class MyClass extends StoredProcedure {
public MyClass(){
.....
declareParameter(new SqlParameter("content", Types.CLOB));
.....
}
public void insert(){
HashMap<String,Object> params = new HashMap<String, Object>(37);
String bigContent = ....; // which contains ASCII chars in my test
....
params.put("content", new SqlLobValue(bigContent));
....
execute(params);
}
}
如果 bigContent 的字符数小于 32k,则代码可以正常工作。如果 bigContent 有 50K 个字符,它就不起作用。
我还测试了使用 jdbcTemplate 和 SqlLobValue 直接插入 table,bigContent 有 50K 个字符时一切正常。
我想使用 SP,因为它可以做很多其他事情,而且比分别调用多个 SQL 插入、更新和查询语句更有效。
有人知道如何让它与 SP 一起工作吗?或者如果 bigContent 有 > 32K 个字符,这就是我必须以不同方式处理它的限制?
这取决于您的 Oracle 版本:
- < 10.1: 你可以把
SetBigStringTryClob
属性 到 true
放在你的 DriverManager
.
- >= 10.1: 你可以使用
OraclePreparedStatement.setStringForClob
doc here.
此外,this article可能会对您有所帮助。
Oracle 中 CLOB 的限制是 176TB。 32KB 是 VARCHAR 的限制。您的代码在某处使用从 VARCHAR 到 CLOB 的隐式转换。在 Oracle 中,CLOB 必须是 OUTPUT 参数 - 即使您正在插入它。 Oracle 的 API 假定您在数据库端创建 empty_clob(),然后您 return 应用程序的 LOB 定位器。应用程序然后使用此 LOB 定位器作为文件句柄。
此行为与其他数据库不同。
如果您将数据作为字符串发送,PL/SQL 的硬性限制为 32k 个字符。如果参数是 CLOB,您可以先创建一个临时 LOB,用数据填充它,然后使用 CLOB 对象调用您的 PL/SQL 过程。
我们遇到了类似的问题,但后来我们在 PL/SQL 中发现了根本原因 - 为“大”参数混合了 VARCHAR2 和 CLOB 类型。
所以最后我们保留了 Java 代码——甚至使用 String 而不是 Clob 将大参数传递给 Java(使用 Spring StoredProcedure)。
环境:oracle 11g,spring-jdbc-3.2.2-RELEASE.jar,JDK 1.7,Oracle UCP 驱动程序。
我有一个存储过程,可以将记录插入到带有 CLOB 列的 table。 SP 在其他 IN 和 OUT 参数中有一个 CLOB 输入参数。我的 Java 代码使用 Spring StoredProcedure 来调用存储过程:
public class MyClass extends StoredProcedure {
public MyClass(){
.....
declareParameter(new SqlParameter("content", Types.CLOB));
.....
}
public void insert(){
HashMap<String,Object> params = new HashMap<String, Object>(37);
String bigContent = ....; // which contains ASCII chars in my test
....
params.put("content", new SqlLobValue(bigContent));
....
execute(params);
}
}
如果 bigContent 的字符数小于 32k,则代码可以正常工作。如果 bigContent 有 50K 个字符,它就不起作用。 我还测试了使用 jdbcTemplate 和 SqlLobValue 直接插入 table,bigContent 有 50K 个字符时一切正常。
我想使用 SP,因为它可以做很多其他事情,而且比分别调用多个 SQL 插入、更新和查询语句更有效。
有人知道如何让它与 SP 一起工作吗?或者如果 bigContent 有 > 32K 个字符,这就是我必须以不同方式处理它的限制?
这取决于您的 Oracle 版本:
- < 10.1: 你可以把
SetBigStringTryClob
属性 到true
放在你的DriverManager
. - >= 10.1: 你可以使用
OraclePreparedStatement.setStringForClob
doc here.
此外,this article可能会对您有所帮助。
Oracle 中 CLOB 的限制是 176TB。 32KB 是 VARCHAR 的限制。您的代码在某处使用从 VARCHAR 到 CLOB 的隐式转换。在 Oracle 中,CLOB 必须是 OUTPUT 参数 - 即使您正在插入它。 Oracle 的 API 假定您在数据库端创建 empty_clob(),然后您 return 应用程序的 LOB 定位器。应用程序然后使用此 LOB 定位器作为文件句柄。
此行为与其他数据库不同。
PL/SQL 的硬性限制为 32k 个字符。如果参数是 CLOB,您可以先创建一个临时 LOB,用数据填充它,然后使用 CLOB 对象调用您的 PL/SQL 过程。
我们遇到了类似的问题,但后来我们在 PL/SQL 中发现了根本原因 - 为“大”参数混合了 VARCHAR2 和 CLOB 类型。
所以最后我们保留了 Java 代码——甚至使用 String 而不是 Clob 将大参数传递给 Java(使用 Spring StoredProcedure)。