ORA-01461:只能绑定LONG值以插入LONG列-在查询时发生


72

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

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

有人可以帮我解决问题的原因和解决方案吗?


@Rupesh您确定这是来自查询吗?您是否正在尝试插入?另外,如何运行(java,C#,sqlplus 、?)
tbone 2012年

1
存在使用长字符串文字插入CLOBBLOB列的PL / SQL解决方法。
瓦季姆

Answers:


19

好的,既然您没有显示任何代码,在这里我将做一些假设。

基于ORA-1461错误,似乎您在select语句中指定了LONG数据类型?您正在尝试将其绑定到输出变量吗?是对的吗?该错误非常简单。您只能绑定一个LONG值以插入到LONG列中。

不知道还有什么要说的。该错误是不言自明的。

通常,从LONG数据类型转移到CLOB是一个好主意。更好地支持CLOB,而LONG数据类型实际上仅是为了向后兼容。

是LONG数据类型限制列表

希望能有所帮助。


14
可能会发生此错误,而不会在LONG类型的表上进行可察觉的操作。
Gus Crawford 2015年

1
尝试将一些数据合并到带有CLOB的表中时得到了它
dougd_in_nc

19
不幸的是,如果错误消息不是由varchar2字段引起的,该消息超出了其字段长度(请参见Kiran的答案),它不是很容易解释
。– max.mustermann

3
我没有向下滚动,意识到基兰有更好的答案。我不喜欢接受的答案如何位于顶部的想法,当另一个答案得到更多支持时,应该有某种方法可以将其提高到第二位。
CoderSteve

2
即使您尝试放置的字符数超过为varchar列指定的大小,也会发生这种情况。例如varchar(4000):如果输入4001个字符,则会出现该错误。
劳拉·里帕鲁洛

198

varchar2列也可能发生这种情况。这可以通过JDBC在PreparedStatements中重现,方法很简单

  1. 创建一个具有varchar2列(20或任意长度)的表,并
  2. 插入到上面的表中,一行包含20个以上的字符

因此,如上所述,类型可能有误,或者超出了列宽。

另请注意,由于varchar2最多允许4k个字符,因此双字节字符的实际限制为2k

希望这可以帮助


15
在Oracle数据库中,我有一个表,该表的列为VARCHAR2(2000 CHAR)。我同时看到了ORA-01461(大约该长值)和另一个错误ORA-12899。ORA-12899精确地指出了问题:实际长度:2392,最大长度:2000。当content> 4000 CHAR(这是Oracle支持的最大长度)时,似乎会返回一种误导性的ORA-01461。当长度> 2000且<4000时返回ORA-12899。有人可以确认这一点(至少对于Oracle)吗?
Vering 2014年

5
@Vering,可以确认。我们得到相同的行为。
Grant H.

1
这就是我们真正发生的事情。
Mathew Berg

我在VARCHAR2(2000)的列上有ORA-01461。
Marcel

1
出于好奇,为什么Oracle在这种情况下会产生这样的错误?
Seldon

35

当尝试在SQL语句中使用长度超过4000字节的varchar变量时,会发生此错误。PL / SQL最多允许varchars 32767字节,但数据库表和SQL语言的限制为4000。正如消息所解释的,一个例外是直接插入长型列。

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;

8

我和我的一个同事发现了以下内容:

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

我们正在尝试使用数据库参数将长度在2000到4000个字符之间的字符串插入到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个字符的任何字符串都不会引发此异常
  • 长度超过4000个字符的任何字符串都不会引发此异常
  • 只有长度在2000到4000个字符之间的字符串会引发此异常

许多年前,我们在Microsoft针对该错误打开了一张票,但仍未得到修复。


我们有同样的问题。您有合理的解决方法吗?
jeromerg '16

如果可能,请使用Oracle.ManagedDataAccess.dll。(可以自由部署,无需在客户端计算机上安装Oracle客户端)。[requires.NET 4.0]如果无法更改为其他.NET DataProvider,则可以使用一些可能的解决方法:我们将XML-Data或人类可读的文本存储在此类字段中。因此,我们添加了空格(如果字符串的长度在2000到4000个字符之间。)其他可能的解决方案是将字符串长度保存在一个额外的数据库字段中,如果字符串长度在2000到4000之间,则添加空格,并使用长度信息在多余的字段中,以在读取时剪切字符串。
Markus1980Wien

8

仅当将其插入到Long列中时,才会出现此ORA-01461。绑定长字符串以插入VARCHAR2列时,可能会发生此错误,并且最常见的情况是在存在多字节(意味着单个字符在oracle中可能占用一个以上字节空间)字符转换问题时发生。

如果数据库为UTF-8,则由于每个字符最多占用3个字节,因此将3的转换应用于校验,因此实际上限制为使用1333个字符插入varchar2(4000)。

另一个解决方案是将数据类型从varchar2(4000)更改为CLOB。


4

我面临着同样的问题,只需将替换VARCHAR为即可解决CLOB。该链接帮助我。


3

使用JDBC 10.1的应用程序存在一个错误(文档ID 370438.1),即使插入的字符小于该列的最大大小,使用UTF8字符集数据库时也可能引发相同的ORA-01461异常。

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

高温超导


2

基兰的答案绝对是我案的答案。

在代码部分,我将字符串拆分为4000个char字符串,然后尝试将其放入db中。

爆炸并显示此错误。

错误的原因是使用utf字符,每个字符计数2个字节。即使我将代码中的字符截断为4000个字符(例如String.Take(4000)),当字符串包含'ö'或任何其他非eng(non ascii精确地用两个或两个字节表示)时,oracle也认为4001 utf8)字符。


1

首先在所有CLOB列上使用Entity Framework数据库遇到相同的问题。

解决方法是,在插入操作中,将文本值填充为至少4000宽度的空格(没有更好的解决方案)。


1

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

专门使用Java的PreparedStatement像这样:

ps.setString('XML', document);

其中,XML在这里被定义为XMLTYPE。


您如何解决此问题?
Acroyear

1

在我的特定情况下,我试图使用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构成了字符串字符序列的威胁,并尝试将其存储为Varchar。所以我的解决方案是:

在我的DTO中:

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

和工作。

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


0

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


0

在发现这种情况的地方添加了另一个用例。我使用的是ADF Fusion应用程序,使用的列类型是varchar2(4000),它无法容纳文本,因此会出现此错误。


0

当在以下位置的XMLTYPE列中插入长xml字符串(> 4000)时,我有一个针对Java / JPA / eclipselink / oracle的解决方案 超过4000个字符的XML插入Oracle XMLTYPE列中插入。为了清楚起见,请在此处添加相同的内容,以防链接不起作用

您首先需要将超过4000个字符的xml字符串转换为SQLXML类型。

环境: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();

0

使用PHP和在VARCHAR2列上准备语句时,我遇到了同样的问题。我的字符串没有超出VARCHAR2的大小。问题是我使用-1作为最大长度进行绑定,但是变量内容后来更改了。

例如:

$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)替换-1,则此代码有效。使用-1时,oci_bind_by_param将变量内容的当前长度(在我的情况下为0)用作此列的最大长度。执行时将导致ORA-01461。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.