DD373是不是金盛微交易提现问题出问题了

Oracle(19)
JAVA(64)
當時的環境:
数据库:Oracle 9i
数据库字段类型:varchar2(4000)
输入汉字:大于1000字
& 我的数据库字符集应该是UTF-8的,对于UTF-8或欧洲的某些字符集,oracle在存储时,对于一个字符需要2个或3个字节的存储空间,虽然表定义 中为varchar2(4000),但是其实该字段的data_length为其2倍或3倍长。这种情况下oracle会把data_length长度超 过4000的当做LONG型处理,你的表中有两个这样的字段,插入数据时相当于同时操作2个LONG字段,所以报错。
當時的解决办法:建议减小字段长度或拆分。实在需要的,可以转而采用CLOB字段类型。
現在的環境:
開發框架:Spring 2.0.6 + Hibernate 3.2
數據庫:Oracle 9i
数据库字段类型:CLOB
输入字節:1000 ~ 2000
現在的問題:
現 在的項目中我采用了CLOB字段類型,但又遇到了這個錯誤。当我对Oracle数据库中的CLOB字段进入insert或update操作的时候,后台出 现 java.sql.SQLException:&& ORA-01461: 仅可以为插入 LONG 列的 LONG值赋值。这个错误的特點是,当插入的数据长度小於1000字節或者大於2000字節時都不會報錯,一旦插入的数据长度在1000 ~ 2000之間時就會報錯。經過google一番之後,ORA-01461錯誤是一個經典問題了,有人認為是CLOB字段本身的問題。
解決方法:
采用Oracle 10g最新的ojdbc14.jar驱动替換原有的驅動即可。試過了這種方法,但是并沒有生效。
1. Hibernate實體對象中的数据成员类型为String,映射的数据库字段类型为org.springframework.orm.hibernate.support.ClobStringType。實例如下:
@SuppressWarnings(&serial&)
@Table(name
= &GUIDE&)
//@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
class Guide
&&& @Type(type
= &org.springframework.orm.hibernate3.support.ClobStringType&)
//get & set
2. 如果使用Spring的这个Clob类型就需要在applicationContext.xml中的sessionFactory bean里注入oracleLobHandler bean。下面給出Oracle數據庫的LobHandler配置:
id=&oracleLobHandler&
&&&&& class=&org.springframework.jdbc.support.lob.OracleLobHandler&
&&&&& lazy-init=&true&&&
name=&nativeJdbcExtractor& ref=&nativeJdbcExtractor&
&/bean&&&&
id=&nativeJdbcExtractor&&&&&&& class=&org.springframework.jdbc.monsDbcpNativeJdbcExtractor&
&&&&& lazy-init=&true&
&!-- Hibernate SessionFactory
id=&sessionFactory& class=&org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean&&
name=&dataSource& ref=&dataSource&
name=&configLocation& value=&classpath:hibernate/hibernate.cfg.xml&
name=&hibernateProperties&&
&/property&
name=&lobHandler& ref=&oracleLobHandler&
LobHandler需要访问本地 JDBC 对象,这一任务委托给 NativeJdbcExtractor Bean来完成,NativeJdbcExtractor是一個本地JDBC對象抽取器,因此我們为 LobHandler 注入了一个nativeJdbcExtractor。最后,我们把 lobHandler Bean 注入到需要进行 LOB数据访问操作的sessionFactory Bean中或者直接注入到dao Bean中去。
大家可能已经注意到nativeJdbcExtractor 和 oracleLobHandler Bean 都设置为 lazy-init=&true&,这是因为nativeJdbcExtractor 需要通过运行期的反射机制获取底层的JDBC 对象,所以需要避免在 Spring容器启动时就实例化这两个Bean。
如果底層數據庫是 DB2、SQL Server、MySQL 等非 Oracle 的其它數據庫,则只要简单配置一个 DefaultLobHandler 就可以了,如下所示:
id=&defaultLobHandler&
class=&org.springframework.jdbc.support.lob.DefaultLobHandler&
lazy-init=&true&/&
id=&testDao& class=&com.test.dao.jdbc.TestJdbcDao&&
&property name=&lobHandler& ref=& defaultLobHandler&/&
name=&jdbcTemplate& ref=&jdbcTemplate&
DefaultLobHandler 只是简单地代理标准 JDBC 的 PreparedStatement 和 ResultSet 对象,由于并不需要访问数据库驱动本地的 JDBC 对象,所以它不需要 NativeJdbcExtractor 的帮助。
&&& 采用第二種方法即可解決我所遇到的問題,如果再見到“ORA-01461: 仅可以为插入 LONG 列的 LONG 值赋值”時,希望這個方法能夠幫您順利拿下ORA-01461。
PS:給出Oracle下幾種大容量字段類型的解釋
LONG:可变长的字符串数据,最长2G,LONG具有VARCHAR2列的特性,可以存储长文本一个表中最多一个LONG列
LONG RAW: 可变长二进制数据,最长2G
CLOB:& 字符大对象Clob 用来存储单字节的字符数据
NCLOB: 用来存储多字节的字符数据
BLOB: 用于存储二进制数据
BFILE: 存储在文件中的二进制数据,这个文件中的数据只能被只读访。但该文件不包含在数据库内。bfile字段实际的文件存储在文件系统中,字段中存储的是文件定位指针.bfile对oracle来说是只读的,也不参与事务性控制和数据恢复。
其 中CLOB,NCLOB,BLOB都是内部的LOB(Large Object)类型,最长4G,没有LONG只能有一列的限制。要保存图片、文本文件、Word文件各自最好采用那種数据类型呢?BLOB最好,LONG RAW也不错,但Long是oracle将要废弃的类型,因此建议用BLOB。
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:337618次
积分:4767
积分:4767
排名:第4966名
原创:87篇
转载:239篇
评论:89条
(2)(3)(2)(3)(2)(5)(10)(1)(2)(2)(1)(6)(1)(1)(6)(7)(1)(2)(9)(3)(5)(8)(2)(5)(7)(2)(3)(3)(2)(7)(4)(2)(4)(1)(3)(4)(3)(3)(3)(3)(9)(3)(1)(3)(5)(5)(3)(3)(4)(2)(13)(4)(2)(4)(4)(9)(5)(8)(4)(5)(10)(3)(16)(1)(3)(2)(4)(5)(2)(2)(6)(2)(8)(10)(4)(2)(4)(11)ORA-01461: 仅可以为插入 LONG 列的 LONG 值赋值
插入的数据没有超过数据库的设定的长度 &更改CLOB类型 &varchar2均无效 &求解释
重新下载一个连接数据库的ojdbc6.jar,你的那个版本太低。
这个和长度啥的没啥关系吧,数据类型问题了。
引用来自“Andre.Z”的答案这个和长度啥的没啥关系吧,数据类型问题了。没有耶. &我插入的是Long型的数字 &用varchar2.. &clob & 只要是数据类型都试过了 &就是不行
--- 共有 1 条评论 ---
数字去用varchar和clob???
你是否用了啥ORM之类的?还有哪里没修改啊? 参数值啥的,直接一个setObject就搞定了,除非类型有问题。 大内容字段我一直用Clob,没啥问题。 搜索下,网上很多这样的,比如:15:18 提问
ORA-03001:未实施的功能 和 ORA-01461: 仅能绑定要插入 LONG 列的 LONG 值
我现在一个存储过程中报错“ORA-01461: 仅能绑定要插入 LONG 列的 LONG 值”,我怀疑是clob限制的问题,但是做实验时遇到下面的错误
我是写了一个很简单的存储过程,准备验证普通表中clob字段存储有没有大小限制,查资料好像说最大4G,我想验证一下。但是写存储过程将大量数据插入clob字段时报标题错误:
SQL& select * from v$
Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Prod
PL/SQL Release 10.2.0.1.0 - Production
10.2.0.1.0
Production
TNS for 32-bit Windows: Version 10.2.0.1.0 - Production
NLSRTL Version 10.2.0.1.0 - Production
create table t_wll_clob(mobile clob);
建存储过程:
create or replace procedure p_wll_clob
for v_11 in(select allcode from T_BUSI_MAIN_PRESEND3 where main1status='0') loop
--allcode字段为clob类型,存储的是用逗号分隔的手机号码。for一共500条记录,每条200个用逗号分隔的手机号
v_clob := v_11.allcode||','||v_
insert into t_wll_clob(mobile) values v_
insert into t_wll_clob(mobile) values v_
ORA-03001:未实施的功能
求高手解答。
另外我想知道:
1.普通表中clob字段最大限制是多少
2.存储过程中clob变量最大限制是多少
3.如果clob有限制,那么超过限制报错一般是怎么解决,是限制数据的大小还是?proc中插入VARCHAR2字段报ORA-01461: can bind a LONG value only for insert into a LONG column - 博客频道 - CSDN.NET
bisal的专栏
分类:Oracle个人心得技术之我见
最近做一个天信达货运接口的项目,碰到这么个诡异的问题。
使用proc写的应用,向数据库插入记录。表中有三个VARCHAR2(4000)类型的字段。注:Oracle 9i的库。
执行的时候提示:ORA-01461: can bind a LONG value only for insert into a LONG column
无法插入记录,但使用PLSQL Developer或SQLPLUS手工执行相同的SQL却没有问题。
然后换了一个10g的库,用proc可以正确完成插入。
难道9i的库,对于proc插入有什么特殊的限制?
解决过程:
<span style="color:#. 查询OERR对该问题的说明:
带着这个问题首先OERR看下1461的错误,没有任何说明。
<span style="color:#. 查询MOS对该问题的说明:
接着查下MOS,Workarounds for bug 1400539: GETTING ORA-1461 INSERTING INTO A VARCHAR (文档 ID ),这篇文章和这个问题很对应。
文章中说明了问题之和9i及之前版本有关,并且指出同一个ORA的错误可能在高版本中出现,但根本原因和这里要描述的不同。开了一个bug(1400539),在10.1.0.1版本中进行了重写修复了此bug。
GETTING ORA-1461 WHEN INSERTING INTO A VARCHAR FIELD
Problem symptoms
(1) Using PRO*C or OCI. (2) Database character set is set a multibyte character set. For example UTF8, AL32UTF8, JA16SJIS or JA16EUC.(3) Trying to insert a VARCHAR2 into a column that is defined with a length of more than 1333 bytes.(4) The same table either has another LONG column or at least 1 other VARCHAR2 with a length over 1333 bytes.(5) NLS_LANG is set to a single-byte character set. For example american_america.WE8ISO8859P1
Resulting error
ORA-1461: &can bind a LONG value only for insert into a LONG column&
从这里可以看到,产生这个问题的原因之一就是使用了(1)PRO*C,对于其他可能的原因:
(5). proc应用的环境字符集:
&echo $NLS_LANG
AMERICAN_AMERICA.ZHS16CGB231280
(2). 查看数据库字符集:
&SELECT * FROM nls_database_
NLS_CHARACTERSET&&&&&&&&& ZHS16GBK
“When connecting to a UTF8 server, then all character lengths are multiplied by 3 since this is the maximum length that the data could take up on the server.The
maximum size of a VARCHAR2 is 4000 bytes. Anything bigger will be treated as a LONG.
During run-time no check is made for the actual content of the columns. Even if a VARCHAR2(2000) column only contains 1 character, this is treated as if you're using a LONG (just like a LONG that contains only 1 character). If you have 1 of these columns plus
a LONG, or simply 2 or more of these columns, effectively the database believes that you are binding 2 long columns. Since that is not allowed you receive this error.”
文章提了一种场景,就是当连接UTF8字符集的数据库时,所有字符长度需要乘3,因为这是这种字符集的数据需要占据的空间。VARCHAR2类型的最大长度是4000字节,任何更大的存储&#20540;都会作为LONG来看待。
运行时不会检查列的实际内容。即使VARCHAR2(2000)列仅包含一个字符,它也会按照LONG处理,就像使用了一个包含1个字符的LONG字段。如果有一个这样的列,再加上一个LONG列,或者有两个或更多这样的列,数据库会认为你正在绑定两个LONG列。因此就会报这种错误。
对于以上错误的workaround方法,MOS则给出了四种:
1. Limit the size of the buffer from within the OCI code
2. Use the database character set also as the client character set
3. Decrease the size of the columns
4. Do not use the multibyte character set as the database character set
针对我这的问题,
1. 我这里使用的是char数组,估计改为varchar的proc类型,限制其中的字符长度,和这种OCI限制字符长度会相近,但源于精力,没有使用。
2. 这种做法其实和imp/exp导出时会碰到的字符集问题的解决方法类&#20284;,规避字符集不一致带来的问题。
3. “If you make sure that there is only 1 LONG and no VARCHAR & 1333 bytes, OR just 1 VARCHAR & 1333 bytes in the table, you cannot hit this problem.”,如果确认这表只会有1个LONG类型,没有大于1333字节的VARCHAR类型,或者仅仅有一个大于1333字节的VARCHAR类型,就可以绕开这个问题。这就取决于应用的业务逻辑和数据库设计之间是否可以匹配这种做法了。
4. 这块也是针对字符集引发的“乘3”问题的一种规避。
最后还有一种方法,就是使用10.1.0.1及以上版本,就不会有这种问题了。
<span style="color:#.
PLSQL Developer或SQLPLUS和proc的报错现象不同:
之所以使用PLSQL Developer或SQLPLUS没碰到这种问题,是因为他们使用了和proc不同的驱动,proc也是使用了OCI来连接数据库,因此这说的是Using PRO*C or OCI两种。
针对上面的各种说明,做如下实验验证:
(1) proc中先声明a,b,c,l四个变量且赋初&#20540;:
char a[4001], b[4001], c[4001];
memset(a, 0, sizeof(a));
memset(b, 0, sizeof(b));
memset(c, 0, sizeof(c));
strcpy(a, &a&);
strcpy(b, &b&);
strcpy(c, &c&);
(2) 建立测试表并用proc插入记录:
create table TBL_LV1
& B VARCHAR2(10),
& C VARCHAR2(10)
INSERT ... L, B VALUES(:l, :b);
INSERT ... L, B, C VALUES(:l, :b, :c);
create table TBL_LV1
& B VARCHAR2(10)
VARCHAR2(1334)、VARCHAR2(4000)
INSERT ... L, B VALUES(:l, :b);
create table TBL_LV1
& A VARCHAR2(10),
& B VARCHAR2(10)
INSERT ... A, B VALUES(:a, :b);
INSERT ... A, B VALUES('a', 'b');不报错。
即使改为:
create table TBL_LV1
& A VARCHAR2(4000),
& B VARCHAR2(4000)
INSERT ... A, B VALUES('a', 'b');也不报错。
1. 如果使用proc连接9i的库时,由于客户端和服务端的多字节字符问题,插入VARCHAR2类型时会出现ORA-01461: can bind a LONG value only for insert into a LONG column的报错。但使用PLSQL Developer或SQLPLUS这些非OCI驱动,则不会报错。
2. 使用proc绑定变量,根据上面的实验来看,会让ORA-01461这个错误的产生更混淆。
3. 以上问题只在9i及以下版本会出现,10.1.0.1版本中已经修复bug,若仍使用9i及以下版本,Oracle提供了如下四种workaround:
1. Limit the size of the buffer from within the OCI code(使用OCI驱动时限制buffer大小(4000))
2. Use the database character set also as the client character set(数据库端和客户端的字符集保持一致)
3. Decrease the size of the columns(根据字符集的长度限制,减少列长度)
4. Do not use the multibyte character set as the database character set(不要使用多字节字符集作为数据库字符集)
排名:第1339名
(159)(213)(18)(7)(0)(1)(1)(209)(20)(8)(18)(1)(1)(5)(1)(1)(3)(2)(2)(1)(1)(0)(1)(1)(1)(1)(1)(2)(1)(2)(1)(1)(1)(1)(1)(1)(1)(1)(0)(0)(2)(1)(0)(1)(1)(1)(1)(2)(2)(1)(1)(3)(3)(0)(1)(3)(2)(1)(1)(1)(0)(1)(0)(1)(1)

我要回帖

更多关于 中华古玩网提现问题 的文章

 

随机推荐