ORA-01461:只能将LONG值绑定到LONG列中 – 在查询时发生

当我尝试查询对象时,最终出现以下错误:

ORA-01461: can bind a LONG value only for insert into a LONG column 

有人能帮助我解决问题的原因和解决办法吗?

好吧,既然你没有显示任何代码,我会在这里做一些假设。

基于ORA-1461错误,似乎你已经在select语句中指定了一个LONG数据types? 而你试图把它绑定到一个输出variables? 是对的吗? 错误非常简单。 您只能绑定一个LONG值插入LONG列。

不知道还有什么要说的。 这个错误是不言而喻的。

一般来说,从LONG数据types转移到CLOB是一个好主意。 CLOBs支持得更好,而LONG数据types实际上只是为了向后兼容。

以下是LONG数据types限制的列表

希望有所帮助。

它也可以发生在varchar2列。 通过简单的JDBC,PreparedStatements就可以很好的重现这一点

  1. 创build一个varchar2(20或任意长度)列的表
  2. 在包含超过20个字符的行中插入上表

所以如上所述,它可能是错误的types,或列宽超过。

还要注意,由于varchar2允许最大4k个字符,所以对于双字节字符,真正的限制是2k

希望这可以帮助

当您尝试在SQL语句中使用超过4000个字节的varcharvariables时,会发生此错误。 PL / SQL允许最多32767个字节的variables,但数据库表和SQL语言的限制是4000.不能使用SQL在SQL语句中无法识别的PL / SQLvariables; 正如消息所解释的那样,一个例外是直接插入到长型列中。

 create table test (v varchar2(10), c clob); declare shortStr varchar2(10) := '0123456789'; longStr1 varchar2(10000) := shortStr; longStr2 varchar2(10000); begin for i in 1 .. 10000 loop longStr2 := longStr2 || 'X'; end loop; -- The following results in ORA-01461 insert into test(v, c) values(longStr2, longStr2); -- This is OK; the actual length matters, not the declared one insert into test(v, c) values(longStr1, longStr1); -- This works, too (a direct insert into a clob column) insert into test(v, c) values(shortStr, longStr2); -- ORA-01461 again: You can't use longStr2 in an SQL function! insert into test(v, c) values(shortStr, substr(longStr2, 1, 4000)); end; 

我和我的同事发现了以下几点:

当我们使用Microsoft .NET Oracle驱动程序连接到Oracle数据库(System.Data.OracleClient.OracleConnection)时,

我们试图使用数据库参数将一个长度在2000到4000个字符之间的string插入CLOB或NCLOB域

 oraCommand.CommandText = "INSERT INTO MY_TABLE (NCLOB_COLUMN) VALUES (:PARAMETER1)"; // Add string-parameters with different lengths // oraCommand.Parameters.Add("PARAMETER1", new string(' ', 1900)); // ok oraCommand.Parameters.Add("PARAMETER1", new string(' ', 2500)); // Exception //oraCommand.Parameters.Add("PARAMETER1", new string(' ', 4100)); // ok oraCommand.ExecuteNonQuery(); 
  • 长度小于2000个字符的string不会抛出这个exception
  • 任何长度超过4000个字符的string都不会抛出这个exception
  • 只有长度在2000到4000个字符之间的string才会抛出这个exception

我们多年前在微软为这个bug打开了一张票,但是它还没有被修复。

我面临着同样的问题,只需用CLOBreplaceVARCHAR解决问题。 这个链接帮了我。

基兰的答案肯定是我的情况的答案。

在代码部分,我将string拆分为4000个string,并尝试将它们放入数据库。

爆炸与此错误。

错误的原因是使用utf字符,每个字节计数2个字节。 即使我在代码中截断为4000个字符(例如String.Take(4000)),当string包含“ö”或任何其他非eng(非ascii)时,oracle会认为是4001, utf8)字符。

我在所有CLOB列上首先遇到与entity framework数据库相同的问题。

作为一种解决方法,我用空格填充了文本值,在插入操作中宽度至less为4000(没有提供更好的解决scheme)。

使用JDBC 10.1的应用程序有一个错误(Doc ID 370438.1),即使插入的字符小于列的最大大小,也可以在使用UTF8字符集数据库时抛出相同的ORA-01461exception。

推荐的解决scheme: – 在这种情况下,使用10gR2 JDBC驱动程序或更高版本。

HTH

在使用最新的Instant Client驱动程序时,我遇到了使用Siebel REXPIMP(registry导入)的相同问题。 要解决这些问题,请改用Siebel提供的Data Direct驱动程序。 该DLL是SEOR823.DLL

添加另一个用例,我发现这种情况发生。 我使用的是ADF Fusion应用程序,使用的列types是varchar2(4000),不能容纳文本,因此出现此错误。

尝试将string插入XMLTYPE列时遇到此错误消息。

特别是使用Java的PreparedStatement,像这样:

 ps.setString('XML', document); 

这里的XML被定义为XMLTYPE。

当插入一个长度超过4000个字符的XML XMLTYPE列插入一个长xmlstring(> 4000) 到一个Oracle XMLTYPE列时,我有一个Java / JPA / eclipselink / oracle的解决scheme。 为了清楚起见,在链接不起作用的情况下,在这里包含相同的内容

您需要将超过4000个charcaters的xmlstring转换为SQLXMLtypes。

环境:jpa 2.1.0,eclipselink 2.5.2,oracle db 11gr2

SQL:

 CREATE TABLE "XMLTEST" ( "ID" NUMBER(10,0) NOT NULL ENABLE, "DESCRIPTION" VARCHAR2(50 CHAR) NOT NULL ENABLE, "XML_TXT" "XMLTYPE" NOT NULL ENABLE ); INSERT INTO XMLTEST (ID, DESCRIPTION, XML_TXT) VALUES (101, 'XML DATA', '<data>TEST</data>'); COMMIT; DROP TABLE "XMLTEST"; 

Java代码

 String sql = "INSERT INTO XMLTEST (ID, DESCRIPTION, XML_TXT) VALUES (?, ?, ?)"; String xmlDataStr = "<data>test...</data>"; // a long xml string with length > 4000 characters Connection con = getEntityManager().unwrap(Connection.class); SQLXML sqlXml = con.createSQLXML(); sqlXml.setString(xmlDataStr); 

Java代码 – 使用PreparedStatement

 PreparedStatement pstmt = con.prepareStatement(sql); pstmt.setLong(1, 201); pstmt.setLong(2, "Long XML Data"); pstmt.setSQLXML(3, sqlXml); pstmt.execute(); 

Java代码 – 使用本机查询而不是PreparedStatement

 Query query = getEntityManager().createNativeQuery(sql); query.setParameter(1, 301); query.setParameter(2, "Long XML Data"); query.setParameter(3, sqlXml); query.executeUpdate(); 

我在使用PHP和准备VARCHAR2列上的语句时遇到了同样的问题。 我的string没有超过VARCHAR2大小。 问题是我用-1作为绑定的maxlength,但是可变的内容稍后改变了。

例如:

 $sMyVariable = ''; $rParsedQuery = oci_parse($rLink, 'INSERT INTO MyTable (MyVarChar2Column) VALUES (:MYPLACEHOLDER)'); oci_bind_by_name($rParsedQuery, ':MYPLACEHOLDER', $sMyVariable, -1, SQLT_CHR); $sMyVariable = 'a'; oci_execute($rParsedQuery, OCI_DEFAULT); $sMyVariable = 'b'; oci_execute($rParsedQuery, OCI_DEFAULT); 

如果用最大列宽(即254)replace-1,则此代码有效。 用-1 oci_bind_by_param使用variables内容的当前长度(在我的情况下为0)作为此列的最大长度。 执行时会导致ORA-01461。

在我的情况下,我试图使用Mybatis将Base64编码文件存储到表BLOB字段中。

所以在我的XML我有:

 <insert id="save..." parameterType="...DTO"> <selectKey keyProperty="id" resultType="long" order="BEFORE"> SELECT SEQ.nextVal FROM DUAL </selectKey> insert into MYTABLE( ID, ..., PDF ) values ( #{id, jdbcType=VARCHAR}, ..., #{tcPdf, jdbcType=BLOB}, ) </insert> 

并在我的DTO:

 String getPdf(){ return pdf; } 

这使得Mybatis威胁仿佛是一个string字符序列,并尝试将其存储为一个Varchar。 所以我的解决scheme如下:

在我的DTO中:

 Byte[] getPdf(){ return pdf.getBytes(); } 

和工作。

我希望这可以帮助任何人。