要插入图片的表不是固定的,而且是批量插入很多张,还要考虑到因为图片的文件名错误,修改后要再次插入,此时应避免已经插入的重复执行操作, 浪费时间。

所以就选择先用一张临时表来暂时保存从文件系统读取的照片,用DBMS_LOB的方法来处理。

第一步:创建一个数据库可以访问的目录(注意:这个目录是数据库服务器上的目录,不是客户机上的)

-- Create directory
create or replace directory 图片目录
  as 'E:\照片';

第二步:将图片文件放入刚建好的目录下面,不要在新建文件夹,就放在这个根目录

第三步:根据自己的具体需求,编写存储过程,在做之前,我也在网上找了很多,但基本都只是大概说一下,没有找到比较完整的,这里就把自己的项目源码贴出来,供大家学习交流。

CREATE OR REPLACE PROCEDURE PRO_插入图片(V_表名 IN VARCHAR2) IS
  P_FILENAME VARCHAR2(50); --照片名,动态拼接得到
  P_证件号码 VARCHAR2(50);
  P_姓名     VARCHAR2(50);--这个照片名是通过姓名+证件号拼接得到的,因为基础测试数据没有提供真实的证件号码,就选择用手机号来代替
  P_查询SQL  VARCHAR2(500);
  P_更新SQL  VARCHAR2(5000);
  P_LOB      BLOB;
  P_FILE     BFILE;
  TYPE P_REF_CURSOR IS REF CURSOR; --定义动态游标变量类型
  P_CURSOR P_REF_CURSOR; --定义动态游标变量,因为一次要插入全表的照片,所以选择用游标来处理
  TYPE P_ROW_RECORD IS RECORD(
    证件号码 VARCHAR2(50),
    姓名     VARCHAR2(50));
  C_ROW P_ROW_RECORD;
  V_ERR VARCHAR2(300);
BEGIN
  P_更新SQL := 'update ' || V_表名 || ' set 证件号码=手机号码 WHERE 证件号码 IS NULL';

--用手机号来代替证件号码为空的数据
  EXECUTE IMMEDIATE P_更新SQL;
  COMMIT;
  P_查询SQL := 'SELECT  证件号码,姓名 FROM ' || V_表名 ||
             '  WHERE 证件号码 IS NOT NULL and 照片 IS NULL order by 证件号码';
  OPEN P_CURSOR FOR P_查询SQL;
  LOOP
    begin
      FETCH P_CURSOR
        INTO C_ROW;
      EXIT WHEN P_CURSOR%NOTFOUND;

--获取证件号码和姓名,先排除空格等脏数据,然后拼接成文件名;
      P_证件号码 := C_ROW.证件号码;
      P_姓名     := C_ROW.姓名;
      SELECT REPLACE(P_证件号码, ' ', '') INTO P_证件号码 FROM DUAL;
      SELECT substr(P_证件号码, 1, 11) INTO P_证件号码 FROM DUAL;
      SELECT REPLACE(P_姓名, ' ', '') INTO P_姓名 FROM DUAL;
      P_FILENAME := P_证件号码 || P_姓名 || '.jpg';
      SELECT REPLACE(P_FILENAME, ' ', '') INTO P_FILENAME FROM DUAL;

--以下便是插入图片的核心代码
      INSERT INTO TA_照片总表_TEMP
        (证件号码, 姓名, 照片)
      VALUES
        (P_证件号码, P_姓名, EMPTY_BLOB()) RETURN 照片 INTO P_LOB;
      --获取指定目录下的文件
      P_FILE := BFILENAME('图片目录', P_FILENAME);
      --以只读的方式打开文件
      DBMS_LOB.FILEOPEN(P_FILE, DBMS_LOB.FILE_READONLY);
      --传递对象
      DBMS_LOB.LOADFROMFILE(P_LOB, P_FILE, DBMS_LOB.GETLENGTH(P_FILE));
      --关闭原始文件
      DBMS_LOB.FILECLOSE(P_FILE);
      COMMIT;

--通过更新语句来向目标表插入图片
      P_更新SQL := 'UPDATE ' || V_表名 ||
                 '  A SET a.照片=(SELECT 照片 FROM TA_照片总表_TEMP b
                 WHERE A.证件号码 = B.证件号码 and a.姓名=b.姓名 AND ROWNUM=1)
      WHERE EXISTS (SELECT 1 FROM TA_照片总表_TEMP  B WHERE A.证件号码 = B.证件号码 and a.姓名=b.姓名)';
      EXECUTE IMMEDIATE P_更新SQL;
      COMMIT;
    EXCEPTION

--处理异常情况,这个可以在出现异常时跳过异常继续跑。正常数据依然可以插入,并且记录异常信息,方便异常处理。这个是因为第一次写的过程一报错就断掉了,本来可以插入的图片也无法继续,然后就做了这个优化。
      WHEN OTHERS THEN
        rollback;
        V_ERR := SUBSTR(SQLERRM, 1, 150) || '照片名:' || P_FILENAME;

--定义一张异常信息记录表,是一个非常好的习惯
        INSERT INTO TA_程序运行异常记录
        VALUES
          (SQ_异常序列.NEXTVAL, 'PRO_插入图片', V_ERR, SYSDATE);
        COMMIT;
    end;
  END LOOP;
  CLOSE P_CURSOR;
  COMMIT;
  DELETE TA_照片总表_TEMP;
  COMMIT;
END PRO_插入图片;

然后测试、运行,基本都没问题,不过图片的大小,很影响实际插入的时间,这个时间的优化目前还没有好的对策。

ORACLE批量导入图片到BLOB字段的更多相关文章

  1. [转]iOS:批量导入图片和视频到模拟器的相册

    IOS开发中我们经常会用到模拟器调试,模拟器有个主要的好处就是程序启动块,最重要的是如果没有证书的话,我们就只能在模拟器上调试了.使用模拟器调试时我们可能碰到需要从系统相册选择图片的情况,特别是做图片 ...

  2. C# 自动批量导入图片到数据库中

    using Model; using System; using System.Collections.Generic; using System.Data; using System.Data.Sq ...

  3. EBS oracle 批量导入更新MOQ(最小拆分量、采购提前期、最小订购量、最小包装量)

    EXCEL的列:组织id,供应商编号,供应商地点,料号,最小拆分量.采购提前期.最小订购量.最小包装量 --采购导入更新MOQ四个值,若有为空的那列,会保留原来的值,不会去更新那列的值 PROCEDU ...

  4. Oracle批量更改所有表的字段取值_类型_原字段名

    CREATE PROCEDURE 存储过程名称 is cursor c_tab is select * from user_tab_columns t r_tab user_tab_columns%r ...

  5. 批量导入图片到word并添加文件名

    Sub InsertPic() Dim myfile As FileDialog Set myfile = Application.FileDialog(msoFileDialogFilePicker ...

  6. oracle批量导入数据

    关键代码 OracleDataAdapter da=new OracleDataAdapter(); string sql_select = string.Format("select id ...

  7. VBA批量导入图片到多Word文档并加标题(会飞的鱼)

    感谢会飞的鱼大牛~ Public fp$, obmapp As Object Sub kk() 文件夹浏览器 Application.ScreenUpdating = False Set fso = ...

  8. 基于.NetCore开发博客项目 StarBlog - (9) 图片批量导入

    系列文章 基于.NetCore开发博客项目 StarBlog - (1) 为什么需要自己写一个博客? 基于.NetCore开发博客项目 StarBlog - (2) 环境准备和创建项目 基于.NetC ...

  9. 【转】Oracle中插入和取出图片(用BLOB类型)

    原文地址:http://czllfy.iteye.com/blog/66737 其他参考资料地址:http://lavasoft.blog.51cto.com/62575/321882/ 要在orac ...

随机推荐

  1. .gitignore文件的写法

    有些时候,你必须把某些文件放到Git工作目录中,但又不能提交它们,比如保存了数据库密码的配置文件啦,等等,每次git status都会显示Untracked files .... 解决的方法就是在gi ...

  2. vue -- 数组过滤 filter (vue 表格)

    如下图:  左边表格滑动滚轮,可以自动赋值右边表格:   现在是后台只有一个接口,把整个页面的数据全部返回出来了, 左边表格滑动到每一项时显示右边表格内容,但是需要code相同:   问题: 右边表格 ...

  3. [iOS]UIButton内、外边距设置

    - (void)viewDidLoad {        [super viewDidLoad];        /*         UIButton设置对应的边距image跟title的边距属性  ...

  4. 3.JUC之volatile

    原文链接:http://blog.csdn.net/zteny/article/details/54888629 一.简介 volatile是Java语言的关键字,用来修饰可变变量(即该变量不能被fi ...

  5. 父类调用子类的常量 lumen查询数据库方式

    我要在一个基类里面实例化所有的model 要根据集成的对象定义的model实例化 BaseRepository.php <?php namespace App\Repository; class ...

  6. ELK文档--ELK简介

    请参考:http://www.cnblogs.com/aresxin/p/8035137.html

  7. 前台.cshtml得到cookie值方法

    function Cookie_() { $.ajax({ url: "/Login_/do_cookie",//请求地址 dataType: "json",/ ...

  8. layui 添加

    {include file="Public:inner_header" /} <link rel="stylesheet" href="__ST ...

  9. python与mysql的数据交互

    一 Python 中操作 MySQL 步骤 1.1 安装pymysql命令 sudo pip3 install pymysql 安装软件:sudo apt-get install 软件名称 安装模块: ...

  10. Spring Boot源码探索——自动配置的内部实现

    前面写了两篇文章 <Spring Boot自动配置的魔法是怎么实现的>和 <Spring Boot起步依赖:定制starter>,分别分析了Spring Boot的自动配置和起 ...