Oracle插入图片时遇ORA-01465无效十六进制数错误求助
解决ORA-01465: invalid hex number错误的方案
嘿,这个错误我太熟了!你遇到的ORA-01465本质是Oracle数据库收到了不符合十六进制格式的数据,问题大概率出在你往BLOB字段插入数据的方式上。咱们一步步来解决:
为什么会出现这个错误?
当你尝试直接把字节数组转成字符串拼到SQL语句里(比如用Statement执行拼接的SQL),Oracle会把这个字符串当成十六进制格式来解析,但图片的字节数组转成字符串后根本不是合法的十六进制,自然就报错了。另外,如果没有正确使用JDBC的BLOB参数设置方法,也会触发这个问题。
正确的解决方案步骤
1. 用PreparedStatement替代Statement
绝对不要用字符串拼接SQL!PreparedStatement不仅能防止SQL注入,还能正确处理BLOB这类二进制数据。
2. 正确读取图片到字节数组
先确保你的byte[] photo确实是从图片文件正确读取的,比如在按钮的事件监听里添加文件选择和读取逻辑:
btnNewButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { JFileChooser fileChooser = new JFileChooser(); int result = fileChooser.showOpenDialog(null); if (result == JFileChooser.APPROVE_OPTION) { File selectedFile = fileChooser.getSelectedFile(); filename = selectedFile.getAbsolutePath(); // 读取图片到字节数组(Java 9+ 可用readAllBytes,低版本用ByteArrayOutputStream) try (FileInputStream fis = new FileInputStream(selectedFile)) { photo = fis.readAllBytes(); } catch (IOException ex) { ex.printStackTrace(); JOptionPane.showMessageDialog(null, "读取图片失败,请检查文件"); } } } });
3. 使用setBytes或setBlob设置BLOB参数
在插入数据的时候,用PreparedStatement的专属方法来设置BLOB字段,示例代码如下:
// 假设你已经获取了有效的数据库连接Connection conn String insertSql = "INSERT INTO your_table_name (image_id, image_scr) VALUES (?, ?)"; try (PreparedStatement pstmt = conn.prepareStatement(insertSql)) { // 设置numeric类型的image_id,这里替换成你的实际ID值 pstmt.setInt(1, 1001); // 设置BLOB字段 if (photo != null) { // 方法一:用setBytes直接传入字节数组 pstmt.setBytes(2, photo); // 方法二:用setBlob传入字节输入流(适合大文件) // pstmt.setBlob(2, new ByteArrayInputStream(photo)); } else { // 如果没有选择图片,设置为NULL pstmt.setNull(2, Types.BLOB); } // 执行插入 int rows = pstmt.executeUpdate(); JOptionPane.showMessageDialog(null, "插入成功!共影响" + rows + "行"); } catch (SQLException ex) { ex.printStackTrace(); JOptionPane.showMessageDialog(null, "插入失败:" + ex.getMessage()); }
要避免的常见坑
- 绝对不要拼接SQL字符串:比如
"INSERT ... VALUES (" + imageId + ", '" + new String(photo) + "')",这种方式会彻底破坏二进制数据的结构。 - 检查参数索引:确保
image_id对应第一个?,image_scr对应第二个,别搞反了。 - 确保字节数组不为空:如果用户没选图片就插入,记得设置
NULL,避免传入空的字节数组导致异常。
内容的提问来源于stack exchange,提问作者Jenish Tamrakar
相关产品推荐
相关产品推荐

