首页 > 编程语言 >java代码将16进制字符串转换为图片,jdbc入库blob字段,解决ORA-01704,PLS-00172,ORA-06550,字符串文字太长等问题

java代码将16进制字符串转换为图片,jdbc入库blob字段,解决ORA-01704,PLS-00172,ORA-06550,字符串文字太长等问题

时间:2024-04-11 11:33:21浏览次数:26  
标签:String 22 HEXTORAW 06550 file 字符串 pstmt id ORA

从Oracle导出SQL文件中的insert语句包含blob字段,语句HEXTORAW函数将16进制的字符串入库,由于字符串太长,insert失败

下面的代码读取完整的insert语句,将HEXTORAW函数连同16进制的字符串替换为NULL,先将字段置空插入记录,然后使用PreparedStatement对图片文件读流更新入库

复制代码
import org.apache.commons.io.FileUtils;

import javax.imageio.ImageIO;
import javax.imageio.stream.FileImageOutputStream;
import java.awt.image.BufferedImage;
import java.io.*;
import java.math.BigInteger;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.List;

public class ImageUtils {

    public static void main(String[] args) throws IOException, SQLException, ClassNotFoundException {
        File file = new File("C:\\Users\\Nihaorz\\Desktop\\b_file_insert.sql");
        List<String> list = FileUtils.readLines(file, "UTF-8");
        for (String s : list) {
            String imageFilePath = null;
            String id = null;
            String[] array = s.split(",");
            StringBuilder sb = new StringBuilder();
            for (String s1 : array) {
                if (s1.startsWith(" HEXTORAW(")) {
                    id = sb.toString();
                    id = id.substring("INSERT INTO \"B_FILE\" VALUES ('".length());
                    id = id.substring(0, id.indexOf("'"));
                    sb.append(" NULL");
                    String hexString = s1.trim();
                    hexString = hexString.substring("HEXTORAW('".length(), hexString.length() - 1);
                    imageFilePath = "C:\\Users\\Nihaorz\\Desktop\\b_file_images\\" + id + ".jpg";
                    hexToImage(imageFilePath, hexString);
                } else {
                    sb.append(s1);
                }
                sb.append(",");
            }
            sb.deleteCharAt(sb.length() - 1);
            sb.deleteCharAt(sb.length() - 1);
            insert2Kingbase(sb.toString(), imageFilePath, id);
        }
    }

    public static boolean insert2Oracle(String insertSql, String imgPath, String id) throws ClassNotFoundException, SQLException, FileNotFoundException {
        boolean flag = false;
        Class.forName("oracle.jdbc.driver.OracleDriver");
        Connection conn = DriverManager.getConnection("jdbc:oracle:thin:@x.x.x.x:1521:orcl", "xxx", "xxx");
        conn.createStatement().execute(insertSql);
        // 打印除blob字段之外的insert语句
        System.out.println(insertSql);
        String sql = "update b_file set file_tx = ? where file_id = ?";
        PreparedStatement pstmt = conn.prepareStatement(sql);
        InputStream is = new FileInputStream(imgPath);
        pstmt.setBlob(1, is);
        //还可以通过二进制流的方法存放图片pstmt.setBinaryStream(1,is);
        pstmt.setString(2, id);
        int i = pstmt.executeUpdate();
        if (i > 0) {
            flag = true;
            System.out.println("插入图片成功");
        } else {
            System.out.println("插入图片失败");
        }
        close(pstmt, conn, is);
        return flag;
    }

    public static boolean insert2Kingbase(String insertSql, String imgPath, String id) throws ClassNotFoundException, SQLException, FileNotFoundException {
        boolean flag = false;
        Class.forName("com.kingbase8.Driver");
        Connection conn = DriverManager.getConnection("jdbc:kingbase8://x.x.x.x:54321/xxx", "xxx", "xxx");
        conn.createStatement().execute(insertSql);
        // 打印除blob字段之外的insert语句
        System.out.println(insertSql);
        String sql = "update b_file set file_tx = ? where file_id = ?";
        PreparedStatement pstmt = conn.prepareStatement(sql);
        InputStream is = new FileInputStream(imgPath);
        pstmt.setBlob(1, is);
        //还可以通过二进制流的方法存放图片pstmt.setBinaryStream(1,is);
        pstmt.setString(2, id);
        int i = pstmt.executeUpdate();
        if (i > 0) {
            flag = true;
            System.out.println("插入图片成功");
        } else {
            System.out.println("插入图片失败");
        }
        close(pstmt, conn, is);
        return flag;
    }

    private static void close(AutoCloseable... closeables) {
        for (AutoCloseable autoCloseable : closeables) {
            if (autoCloseable != null) {
                try {
                    autoCloseable.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 将图片转换成十六进制字符串
     */
    static String imageToHex(String filePath) {
        File f = new File(filePath);
        String suffix = filePath.substring(filePath.lastIndexOf(".") + 1);
        BufferedImage bi;
        try {
            bi = ImageIO.read(f);
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            ImageIO.write(bi, suffix, baos);
            byte[] bytes = baos.toByteArray();
            return new BigInteger(1, bytes).toString(16);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 将十六进制字符串转化成图片
     */
    static void hexToImage(String filePath, String hexString) {
        byte[] bytes = stringToByte(hexString);
        try {
            FileImageOutputStream imageOutput = new FileImageOutputStream(new File(filePath));
            imageOutput.write(bytes, 0, bytes.length);
            imageOutput.close();
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    public static byte[] stringToByte(String s) {
        int length = s.length() / 2;
        byte[] bytes = new byte[length];
        for (int i = 0; i < length; i++) {
            bytes[i] = (byte) ((Character.digit(s.charAt(i * 2), 16) << 4) | Character.digit(s.charAt((i * 2) + 1), 16));
        }
        return bytes;
    }

}
复制代码

 

b_file_insert.sql 示例,HEXTORAW('xxxxxx') 仅做示例,正常的是合法的16进制字符串

复制代码
INSERT INTO "B_FILE" VALUES ('f7fb0c74-8bdc-4edd-8bae-14e9b923c1c0', '长安.jpg', 'image/jpeg', '510368', NULL, HEXTORAW('xxxxxx'), TO_TIMESTAMP('2020-11-22 22:43:54.780000', 'SYYYY-MM-DD HH24:MI:SS:FF6'), '标准地图')
INSERT INTO "B_FILE" VALUES ('ca6a7638-7ab5-437d-a486-f354fd210308', '麻涌.jpg', 'image/jpeg', '441326', NULL, HEXTORAW('xxxxxx'), TO_TIMESTAMP('2020-11-22 22:46:23.792000', 'SYYYY-MM-DD HH24:MI:SS:FF6'), '标准地图')
INSERT INTO "B_FILE" VALUES ('df5be551-653e-4640-bfd6-7581cdce36fb', '洪梅.jpg', 'image/jpeg', '394404', NULL, HEXTORAW('xxxxxx'), TO_TIMESTAMP('2020-11-22 22:48:19.201000', 'SYYYY-MM-DD HH24:MI:SS:FF6'), '标准地图')
INSERT INTO "B_FILE" VALUES ('abe056c6-d2a5-41b6-bc96-a05e6364b59b', '道滘.jpg', 'image/jpeg', '480304', NULL, HEXTORAW('xxxxxx'), TO_TIMESTAMP('2020-11-22 22:48:58.139000', 'SYYYY-MM-DD HH24:MI:SS:FF6'), '标准地图')
INSERT INTO "B_FILE" VALUES ('7c99a74a-f8c4-4cdc-9e59-6735564bc126', '黄江.jpg', 'image/jpeg', '554472', NULL, HEXTORAW('xxxxxx'), TO_TIMESTAMP('2020-11-22 22:50:23.518000', 'SYYYY-MM-DD HH24:MI:SS:FF6'), '标准地图')
INSERT INTO "B_FILE" VALUES ('409f586f-f086-48a8-a367-4d42fba26890', '谢岗.jpg', 'image/jpeg', '562335', NULL, HEXTORAW('xxxxxx'), TO_TIMESTAMP('2020-11-22 22:51:08.539000', 'SYYYY-MM-DD HH24:MI:SS:FF6'), '标准地图')
INSERT INTO "B_FILE" VALUES ('cf923739-6938-448f-af06-bc8d70678dac', '桥头.jpg', 'image/jpeg', '519045', NULL, HEXTORAW('xxxxxx'), TO_TIMESTAMP('2020-11-22 22:51:49.255000', 'SYYYY-MM-DD HH24:MI:SS:FF6'), '标准地图')
复制代码

 

b_file表结构

复制代码
-- Create table
create table B_FILE
(
  file_id         VARCHAR2(64) not null,
  file_name       VARCHAR2(64),
  file_type       VARCHAR2(100),
  file_size       VARCHAR2(16),
  file_small      BLOB,
  file_tx         BLOB,
  file_createtime TIMESTAMP(6),
  file_remark     VARCHAR2(512)
)
tablespace DATA
  pctfree 10
  initrans 1
  maxtrans 255
  storage
  (
    initial 64K
    next 1M
    minextents 1
    maxextents unlimited
  );
-- Create/Recreate primary, unique and foreign key constraints 
alter table B_FILE
  add primary key (FILE_ID)
  using index 
  tablespace DATA
  pctfree 10
  initrans 2
  maxtrans 255
  storage
  (
    initial 64K
    next 1M
    minextents 1
    maxextents unlimited
  );
复制代码

 

说明

1、此示例中b_file表存在两个blob字段,且所有记录的file_small字段均为null,如果处理的表不止一个blob字段,需根据实际情况调整代码逻辑

2、对于此代码造成的数据丢失本人概不负责

 

参考链接:

https://blog.csdn.net/rexueqingchun/article/details/78150877

https://blog.csdn.net/qq_34514384/article/details/51134416

标签:String,22,HEXTORAW,06550,file,字符串,pstmt,id,ORA
From: https://www.cnblogs.com/lvjinlin/p/18128667

相关文章

  • 资源池化基于DORADO双集群搭建指南(非日志合一)
    资源池化基于DORADO双集群搭建指南----非日志合一10.10.10前置条件工程已完成代码编译,或者。主备存储已经挂载磁阵LUN设备,并且已经安装ultrapath多路径软件,磁阵设备可用。限制条件两套正常的dorado存储,需要搭建两套资源池化集群。基于资源池化本地日志和同步复制共享xlog两......
  • Java中将字符串转换成数字的方法
    转换为整数(int)你可以使用Integer.parseInt()方法或Integer.valueOf()方法将字符串转换为int类型。javaStringstr="123";intnumber=Integer.parseInt(str);//使用parseInt//或者intnumberValue=Integer.valueOf(str);//使用valueOfSystem.out.println(number);//......
  • MySQL 06 mysql 如何实现类似 oracle 的 merge into
    拓展阅读MySQLViewMySQLtruncatetable与delete清空表的区别和坑MySQLRulermysql日常开发规范MySQLdatetimetimestamp以及如何自动更新,如何实现范围查询MySQL06mysql如何实现类似oracle的mergeintoMySQL05MySQL入门教程(MySQLtutorialbook)MySQL04-E......
  • localStorage使用总结
    一、什么是localStorage、sessionStorage在HTML5中,新加入了一个localStorage特性,这个特性主要是用来作为本地存储来使用的,解决了cookie存储空间不足的问题(cookie中每条cookie的存储空间为4k),localStorage中一般浏览器支持的是5M大小,这个在不同的浏览器中localStorage会有所不同......
  • 两个纯数字字符串相加Python实现版
    """两个字符串相加模拟两个大整数相加,但是不能直接相加,采用每一位相加的方式"""defadd_large_numbers(num1,num2):#反转字符串,方便从低位开始相加num1=num1[::-1]num2=num2[::-1]#初始化结果列表和进位result=[]carry=0#......
  • 解析oracle的DDL语句生成高斯内表及表字段主键配置
    oracle的DDL语句如下:CREATETABLETPPROD.CONFIG( NOVARCHAR2(50), CONFIGCODEVARCHAR2(400), CONFIGVALUEVARCHAR2(400), CONSTRAINTPK_GUENDORASSISTCONFIGPRIMARYKEY(NO,CONFIGCODE));CREATEUNIQUEINDEXPK_GUENDORASSISTCONFIGONTPPROD.GUENDORASSI......
  • Oracle 替代变量
    替代变量说明在Oracle命令行中默认&为替代变量,只要在执行的sql中出现&符号,那么&符号后面的sql则会失效;这就意味着,包含&符号的sql将不会正确的执行比如:insertintoXXX_DB.XXX_TABLE(COLUMN1,COLUMN2)value('AB&CD','EF&GH');在不关闭替代变量的情况下,数据库中的数据将不会......
  • C语言: 字符串函数(下)
    片头在上一篇中,我们介绍了字符串函数。在这一篇章中,我们将继续学习字符串函数,准备好了吗?开始咯!1.strncpy函数1.1strncpy函数的用法strncpy是C语言中的一个字符串处理函数,它用于将一个字符串的一部分内容复制到另一个字符串中。其函数原型为:char*strncpy(char*dest......
  • leedcode-反转字符串中的元音字母
    自己写的,双指针,一次通过classSolution:defreverseVowels(self,s:str)->str:#将输入的字符串转换为列表s_list=list(s)#定义元音字母列表vowels=['a','e','i','o','u','A&......
  • Obsidian自定义代码块样式成Typora
    先来效果图修改前效果:修改后效果:编辑模式:预览模式:两种模式的表现间距略有不同,但不影响.添加自定义css样式.markdown-source-view.mod-cm6.cm-content>.HyperMD-codeblock{border-width:01px01px;border-style:solid;border-color:#E7EAE......