java.sql.SQLException: ORA-01461: 只能绑定 LONG 值以插入 LONG 列

Posted

技术标签:

【中文标题】java.sql.SQLException: ORA-01461: 只能绑定 LONG 值以插入 LONG 列【英文标题】:java.sql.SQLException: ORA-01461: can bind a LONG value only for insert into a LONG column 【发布时间】:2012-07-08 18:38:36 【问题描述】:

我正在使用一个简单的界面(在 jsf 1.2 和 Rich faces 3.3.2,Oracle 11g R1 中)让用户使用 rich:fileUpload 选择图片并保存在表格中。 作为测试,我创建了下表。

CREATE TABLE TEST
(
 MIME_TYPE VARCHAR2 (1000),
 PHOTO BLOB,
 STUDENT_ID NUMBER NOT NULL
)

将图片保存到BLOB字段的代码sn-p如下。

//......From the uploadFile Listener
public void listener(UploadEvent event) throws Exception 
...      
item = event.getUploadItem();
...
StudentPhotoDAO dao = new StudentPhotoDAO();
dao.storePhoto(item.getData(),item.getContentType(),studentId);
...



//......From the PhotoDAO ..........................


public void storePhoto(byte data[],String mimeType, Long studentId)

 ...
  ByteArrayInputStream bis=new ByteArrayInputStream(data);
  String query = "update  TEST set PHOTO = ? ,MIME_TYPE = ?  where STUDENT_ID=?";
  pstmt = conn.prepareStatement(query);
  pstmt.setAsciiStream(1,(InputStream)bis,data.length);
  pstmt.setString(2,mimeType.toString());
  pstmt.setLong(3,studentId);
  pstmt.executeUpdate();
 

我收到以下错误:

java.sql.SQLException: ORA-01461: can bind a LONG value only for insert into a LONG column

请问代码哪里出错了。

谢谢。

【问题讨论】:

SQL 类型 NUMBER 似乎与 Java 类型 Long 不兼容。 在 Oracle 中,LONG 是文本类型,而不是数字类型。这些答案中的大多数都在错误的地方寻找。 【参考方案1】:

您将student_id 指定为number,这似乎映射到BigInteger。参见例如this table.

您要么提供BigInteger,要么需要更改student_id 的类型。

【讨论】:

感谢您的回复。我确实将 student_id 转换为 BigInteger。但是如何将它映射到preparedStatement 参数。因为没有 pstmt.setBigInteger 方法... 使用了这个但同样的错误 BigInteger bi = BigInteger.valueOf(studentId.longValue());字符串查询 = "更新测试集照片 = ? , MIME_TYPE = ? where STUDENT_ID=" + bi + ""; 尝试使用setObject()来设置它 先生,您能输入一些代码如何使用 setObject()(我是这里的初学者)【参考方案2】:

你在打电话

pstmt.setLong(3,studentId);

并且您将列指定为

STUDENT_ID NUMBER NOT NULL

文档怎么说:

尝试将 LONG 数据类型的值插入 另一种数据类型。这是不允许的。

所以就这样吧:

STUDENT_ID INTEGER NOT NULL
pstmt.setInt(3, studentId);

【讨论】:

无法更改 NUMBER 列。 (这是我可以告诉你的一些强迫症,但我会*让你生病;))。 INTEGER oracle 数据类型等价于 NUMBER(28) Oracle's LONG type is a character data type。这里的问题与第一个绑定值有关,而不是第三个...【参考方案3】:

看Oracle LONG type description: “LONG 是一种用于存储字符数据的 Oracle 数据类型……”。所以 LONG 不是 Oracle 中的数字。这是一个文本。

我认为您收到此错误是因为: pstmt.setAsciiStream(1,(InputStream)bis,data.length);

尝试使用pstmt.setBinaryStream(int, InputStream, int)pstmt.setBinaryStream(int, InputStream, long)

【讨论】:

pstmt.setBinaryStream(int, InputStream, int) 在数据超过4000字节时抛出同样的异常 @AjaySharma,sscce 证明请。我无法在我的测试中重现它。【参考方案4】:

在 Oracle 中将大型二进制流绑定到 BLOB 列时,请使用 PreparedStatement.setBlob() 而不是 setAsciiStream()setBinaryStream()

【讨论】:

【参考方案5】:

我猜是因为使用 ASCII 流。

pstmt.setAsciiStream(1, (InputStream) bis, data.length);

试试

pstmt.setBinaryStream(1, new ByteArrayInputStream(data));

(看起来Oracle将带有长度参数的ASCII流解释为不能超过4000字节的LONG。但这只是一个未经证实的猜测。)

【讨论】:

以上是关于java.sql.SQLException: ORA-01461: 只能绑定 LONG 值以插入 LONG 列的主要内容,如果未能解决你的问题,请参考以下文章

Python 操作Redis

python爬虫入门----- 阿里巴巴供应商爬虫

Python词典设置默认值小技巧

《python学习手册(第4版)》pdf

Django settings.py 的media路径设置

Python中的赋值,浅拷贝和深拷贝的区别