达梦数据库中插入导出图片的方法与应用

news2025/3/13 10:33:14

达梦数据库中插入导出图片的方法与应用

在数据库的实际应用场景中,图片存储是一项常见且重要的需求。以电商平台为例,商品展示图片是吸引消费者的关键元素;而在社交软件里,用户头像更是个人形象的直观体现。针对达梦数据库,业界常用的图片存储策略主要分为两大类。
第一种策略是将图片存储于磁盘,数据库字段仅记录图片路径。这种方式的显著优势在于减轻了数据库的存储压力,因为数据库无需直接处理图片的二进制数据。然而,它存在明显的局限性,一旦图片存储路径发生变更,或者存储磁盘出现故障,数据库应用在调用图片时就可能遭遇加载失败的问题。例如,若存储图片的磁盘分区因硬件故障损坏,依赖该路径的应用程序将无法正常显示相关图片。
第二种策略是将图片以二进制形式直接存储于数据库。达梦数据库采用这种方式,并支持使用 blob 或 bfile 类型的字段进行存储。这种策略的优势在于保障了数据的完整性和一致性,图片数据与其他相关数据集中存储于数据库,便于统一管理和维护。但高分辨率图片的二进制数据量往往较大,会显著增加数据库的存储负担。
接下来,详细介绍在 达梦数据库中利用这两种策略插入图片的具体操作方法。

一、使用 disql 插入图片

创建表
在插入图片前,需创建相应的表结构,特别要注意将用于存储图片的列定义为 BLOB 类型。具体操作如下:

DROP TABLE IMAGE_LOB;
CREATE TABLE IMAGE_LOB (
    T_ID INT NOT NULL,
    T_IMAGE BLOB NOT NULL,
    PRIMARY KEY(T_ID)
);

在此表结构中,T_ID 作为主键,用于唯一标识每一条记录;T_IMAGE 列则专门用于存储图片的二进制数据。
执行插入语句
打开 disql 工具后,可通过执行以下语句完成图片插入操作:

@INSERT INTO IMAGE_LOB VALUES(1,@'F:\PIC\test.png');
COMMIT;

上述语句将位于F:\PIC\路径下的test.png图片插入到 IMAGE_LOB 表中,对应的记录 ID 为 1。

二、通过 manager 调用系统包插入图片

创建表
同样,首先要创建表,并且将插入图片的列定义为 BLOB 类型,操作语句与使用 disql 创建表时一致:

DROP TABLE IMAGE_LOB;
CREATE TABLE IMAGE_LOB (
    T_ID INT NOT NULL,
    T_IMAGE BLOB NOT NULL,
    PRIMARY KEY(T_ID)
);

创建图片存放目录
需要创建一个虚拟路径目录,用于存放待插入到表中的图片。例如:

CREATE OR REPLACE DIRECTORY "IMAGES" AS 'F:\PIC';

此语句创建了一个名为 “IMAGES” 的虚拟目录,其实际指向的物理路径为F:\PIC。
创建存储过程
接下来创建一个存储过程,用于实现图片插入操作。其中,FILENAME参数为图片文件名,例如’test.png’。

CREATE OR REPLACE PROCEDURE IMG_INSERT(
    TID INT,
    FILENAME VARCHAR(200)
) AS
    F_LOB BFILE;
    B_LOB BLOB;
BEGIN
    INSERT INTO IMAGE_LOB (T_ID, T_IMAGE) VALUES (TID,EMPTY_BLOB()) RETURN T_IMAGE INTO B_LOB;
    F_LOB:= BFILENAME ('IMAGES', FILENAME);
    DBMS_LOB.FILEOPEN (F_LOB, DBMS_LOB.FILE_READONLY);
    DBMS_LOB.LOADFROMFILE (B_LOB, F_LOB, DBMS_LOB.GETLENGTH (F_LOB));
    DBMS_LOB.FILECLOSE (F_LOB);
    COMMIT;
END;

在这个存储过程中,首先向 IMAGE_LOB 表中插入一条记录,其中图片字段先使用EMPTY_BLOB()占位。然后通过BFILENAME函数获取图片文件路径,接着以只读方式打开文件,并将文件内容加载到 BLOB 字段中,最后关闭文件并提交事务。
执行存储过程
执行上述创建的存储过程,即可实现图片插入操作。例如:

CALL IMG_INSERT(1,'test.png');

这条语句会将test.png图片插入到 IMAGE_LOB 表中,对应的记录 ID 为 1。
查看表
插入完成后,可通过以下语句查看表中的数据:

SELECT * FROM IMAGE_LOB;

执行该查询语句后,可看到表中已成功插入图片相关记录,其中图片字段显示为二进制数据。


在达梦数据库实际应用场景里,不仅会有往数据库表中插入图片的需求,有时也需要从数据库表中导出图片。下面将详细介绍在达梦数据库中导出图片的具体方法。

三、创建图片导出目录

在数据库中定义一个虚拟目录,用于指定图片导出的本地路径。执行以下SQL语句:

--定义本地图片导出目录
CREATE OR REPLACE DIRECTORY "IMAGES" AS 'D:\vm\FIC';

上述语句中,CREATE OR REPLACE DIRECTORY用于创建或替换一个目录对象,将名为IMAGES的虚拟目录映射到本地路径D:\vm\FIC。这个路径是本地实际存在的目录,用于存放导出的图片。

四、创建导出图片的存储过程

通过创建存储过程来实现从指定表中根据记录ID导出图片到之前定义的目录中。

--导出图片到本地dir
CREATE OR REPLACE PROCEDURE DUMP_IMAGE_TO_DIR(IN_TABLE_NAME VARCHAR2(1000),  IN_ID          INT)
IS
    L_FILE UTL_FILE.FILE_TYPE;
    L_BUFFER RAW (32767);
    L_AMOUNT BINARY_INTEGER := 32767;
    L_POS INTEGER           := 1;
    L_BLOB BLOB;
    L_BLOB_LEN INTEGER;
    L_SQL      VARCHAR2(1000);
BEGIN
    L_SQL := 'SELECT T_IMAGE FROM ' || IN_TABLE_NAME || ' WHERE T_ID = :1';
    EXECUTE IMMEDIATE L_SQL INTO L_BLOB USING IN_ID;
    L_BLOB_LEN := DBMS_LOB.GETLENGTH (L_BLOB);
    L_FILE     := UTL_FILE.FOPEN ('IMAGES',IN_ID||'.JPG', 'WB', 32767);
    WHILE L_POS < L_BLOB_LEN
    LOOP
        IF L_POS + L_AMOUNT -1 > L_BLOB_LEN THEN
            L_AMOUNT := L_BLOB_LEN - L_POS + 1;
        END IF;
        DBMS_LOB.READ ( L_BLOB, L_AMOUNT, L_POS, L_BUFFER );
        UTL_FILE.PUT_RAW ( L_FILE, L_BUFFER, TRUE );
        L_POS := L_POS + L_AMOUNT;
    END LOOP;
    UTL_FILE.FCLOSE (L_FILE);
EXCEPTION
WHEN OTHERS THEN
    IF UTL_FILE.IS_OPEN (L_FILE) THEN
        UTL_FILE.FCLOSE (L_FILE);
    END IF;
    RAISE;
END DUMP_IMAGE_TO_DIR;
  1. 参数说明
    • IN_TABLE_NAME:要从中导出图片的表名,数据类型为VARCHAR2(1000)
    • IN_ID:对应表中图片记录的ID,数据类型为INT
  2. 变量定义
    • L_FILE:用于表示文件句柄,数据类型为UTL_FILE.FILE_TYPE
    • L_BUFFER:定义一个RAW类型的缓冲区,大小为32767字节,用于临时存储从BLOB字段中读取的数据。
    • L_AMOUNT:每次从BLOB字段读取数据的长度,初始值为32767字节,数据类型为BINARY_INTEGER
    • L_POS:记录当前读取数据在BLOB字段中的位置,初始值为1,数据类型为INTEGER
    • L_BLOB:用于存储从表中查询出来的图片数据(BLOB类型)。
    • L_BLOB_LEN:存储BLOB字段的长度,数据类型为INTEGER
    • L_SQL:用于构建动态SQL语句,数据类型为VARCHAR2(1000)
  3. 主要逻辑
    • 构建动态SQL语句,根据传入的表名和ID查询对应的图片数据(BLOB类型)。
    • 使用DBMS_LOB.GETLENGTH获取BLOB数据的长度。
    • 使用UTL_FILE.FOPEN打开一个文件,文件名为传入的ID加上.JPG后缀,路径为之前定义的IMAGES虚拟目录对应的本地路径,以二进制写模式打开。
    • 通过循环读取BLOB数据,并将读取的数据写入文件中。在循环过程中,根据剩余数据长度调整每次读取的字节数,确保完整读取BLOB数据。
    • 操作完成后,使用UTL_FILE.FCLOSE关闭文件。
  4. 异常处理
    • 如果在执行过程中发生其他异常,首先检查文件是否打开,如果打开则关闭文件,然后重新抛出异常,以便上层调用能够捕获并处理异常。

五、调用存储过程导出全表图片

通过游标遍历表中所有记录的ID,调用上述存储过程实现全表图片的导出。

--调用导出过程把全表图片导出
DECLARE 
	CURSOR cur IS 
		SELECT T_ID FROM IMAGE_LOB;
BEGIN
	FOR rec IN cur LOOP
		DUMP_IMAGE_TO_DIR('IMAGE_LOB',rec.T_ID);
  END LOOP;
END;
  1. 定义游标:使用CURSOR定义一个游标cur,用于查询IMAGE_LOB表中的所有T_ID
  2. 循环调用存储过程:通过FOR循环遍历游标cur中的每一条记录,将表名IMAGE_LOB和当前记录的T_ID作为参数传递给DUMP_IMAGE_TO_DIR存储过程,实现逐张图片导出到指定目录。

通过以上步骤,就可以在达梦数据库中实现从表中导出图片的功能。在实际操作过程中,请确保相关路径正确无误,并且数据库用户具有相应的权限,以保证导出操作的顺利进行。

综上所述,在 达梦数据库中,开发者可依据实际需求和应用场景,灵活选择使用 disql 或通过 manager 调用系统包的方式插入图片。以及使用存储过程的方式导出图片。不同方式各有优劣,在实际项目中,需综合考量数据量、性能要求以及管理维护的便捷性等多方面因素,从而确定最适宜的图片存储和插入方案。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2314244.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

推理大模型时代,TextIn ParseX助力出版业知识资产重构

在大语言模型&#xff08;LLM&#xff09;与推理能力快速进化的技术浪潮下&#xff0c;出版机构沉淀数十年的非结构化数据资产&#xff0c;包括书籍、期刊、手稿及历史档案&#xff0c;正在焕发新的机遇。基于文档解析、NLP与大模型的推理生成能力&#xff0c;我们在图书馆层层…

Redis 2025/3/9

Redis主从集群 搭建主从集群 Redis并发能力非常强&#xff0c;单节点能够达到数万的并发。 不过对一些用户规模大&#xff0c;并发量比较高的应用来讲&#xff0c;数万并发不太够。这时候就用到redis的集群了。因为Redis中的数据通常读多写少&#xff0c;所以最常用的集群方…

2min搞定~Mac Pro 编译安装 Nginx 1.8.1

2min搞定&#xff5e;Mac Pro 编译安装 Nginx 1.8.1 一安装流程简述1、编译源码前&#xff0c;获取要依赖的源码包2、进行编译、安装nginx3、启动 二、实战部分&#xff1a;测试demo1、nginx.conf改动2、代码改动3、访问 一安装流程简述 阿哟啊哟老铁&#xff0c;别嫌我啰嗦奥…

要在Unreal Engine 5(UE5)中实现角色打击怪物并让怪物做出受击反应,

UE5系列文章目录 文章目录 UE5系列文章目录前言一、实现思路二、最终效果 前言 ue5角色受击没有播放受击动画&#xff0c;主角达到怪物身上没有反应 一、实现思路 要在Unreal Engine 5&#xff08;UE5&#xff09;中实现角色打击怪物并让怪物做出受击反应&#xff0c;你需要…

C++蓝桥杯基础篇(十一)

片头 嗨~小伙伴们&#xff0c;大家好&#xff01;今天我们来学习C蓝桥杯基础篇&#xff08;十一&#xff09;&#xff0c;学习类&#xff0c;结构体&#xff0c;指针相关知识&#xff0c;准备好了吗&#xff1f;咱们开始咯~ 一、类与结构体 类的定义&#xff1a;在C中&#x…

Leetcode 698-划分为k个相等的子集

给定一个整数数组 nums 和一个正整数 k&#xff0c;找出是否有可能把这个数组分成 k 个非空子集&#xff0c;其总和都相等。 示例 1&#xff1a; 输入&#xff1a; nums [4, 3, 2, 3, 5, 2, 1], k 4 输出&#xff1a; True 说明&#xff1a; 有可能将其分成 4 个子集&#…

Word 小黑第2套

对应大猫42 Word1 从文件中导入新样式 样式组 -管理样式 -导入导出 -关闭Normal文件 -打开文件 -修改文件 -选中所需 -复制 调整字符宽度 调整字符间距 -字体组 加宽 适当修改磅值 文字效果通过文字组修改 另起一页&#xff0c;分隔符&#xff08;布局 -分隔符 -分节符 -下一…

ctfshow做题笔记—栈溢出—pwn69~pwn72

目录 前言 一、pwn69(可以尝试用ORW读flag flag文件位置为/ctfshow_flag) 二、pwn70(可以开始你的个人秀了 flag文件位置为/flag) 三、pwn71(32位的ret2syscall) 四、pwn72 前言 学了一些新的东西&#xff0c;pwn69的文档忘保存了&#xff08;悲&#xff09;&#xff0c…

同盾v2 2025版 blackbox , wasm加解密,逆向协议算法生成,小盾安全

声明 本文章中所有内容仅供学习交流&#xff0c;抓包内容、敏感网址、数据接口均已做脱敏处理&#xff0c;严禁用于商业用途和非法用途&#xff0c;否则由此产生的一切后果均与作者无关&#xff0c;若有侵权&#xff0c;请联系我立即删除&#xff01; # 欢迎交流 wjxch1004

c++领域展开第十六幕——STL(vector容器的了解以及模拟实现、迭代器失效问题)超详细!!!!

文章目录 前言一、vector的介绍和使用1.1 vector的介绍1.2 vector的使用1.2.1 vector的定义1.2.2 vector iterator 的使用1.2.3 vector的空间增长问题1.2.4 vector的增删改查 二、vector在 oj 中的使用只出现一次的数删除有序数组中的重复项杨辉三角 总结 前言 在c专栏的上一篇…

ubuntu2404 安装 过程中 手动设置网络

ubuntu2404 安装 过程中 手动设置网络 https://blog.csdn.net/2401_83947353/article/details/138454379 6.1 可以直接Done&#xff08;不配置P&#xff09; 6.2 可以配置ip地址&#xff0c;选择manual 6.2.1 search domains填 6.2.2 search domains不填 6.3 更深层次的…

去北京的前端实习经历

趁现在对这部分还有深刻的感受记忆&#xff0c;赶紧记录下来。因为工作久了会发现真的对以前的事记不起来了。 公司&#xff1a; 北京的实习公司首先有学长学姐在&#xff0c;而且这个公司知名度还挺高的&#xff0c;但是工资比较低&#xff0c;3k左右吧&#xff0c;但是管2顿…

力扣热题 100:动态规划专题经典题解析

系列文章目录 力扣热题 100&#xff1a;哈希专题三道题详细解析(JAVA) 力扣热题 100&#xff1a;双指针专题四道题详细解析(JAVA) 力扣热题 100&#xff1a;滑动窗口专题两道题详细解析&#xff08;JAVA&#xff09; 力扣热题 100&#xff1a;子串专题三道题详细解析(JAVA) 力…

变量赋值汇编

一、核心概念 寄存器&#xff1a;CPU内部的高速存储单元&#xff08;如EAX、EBX、x86中的RAX、ARM中的R0等&#xff09; 内存地址&#xff1a;变量存储在内存中的位置&#xff08;如 0x1000&#xff09; 指令&#xff1a;操作寄存器和内存的命令&#xff08;如 MOV, STR, LDR…

页面白屏出现的原因

&#x1f916; 作者简介&#xff1a;水煮白菜王&#xff0c;一位前端劝退师 &#x1f47b; &#x1f440; 文章专栏&#xff1a; 前端专栏 &#xff0c;记录一下平时在博客写作中&#xff0c;总结出的一些开发技巧和知识归纳总结✍。 感谢支持&#x1f495;&#x1f495;&#…

【大模型统一集成项目】让 AI 聊天更丝滑:WebSocket 实现流式对话!

&#x1f31f; 在这系列文章中&#xff0c;我们将一起探索如何搭建一个支持大模型集成项目 NexLM 的开发过程&#xff0c;从 架构设计 到 代码实战&#xff0c;逐步搭建一个支持 多种大模型&#xff08;GPT-4、DeepSeek 等&#xff09; 的 一站式大模型集成与管理平台&#xff…

【2025】Electron Git Desktop 实战一(上)(架构及首页设计开发)

源代码仓库&#xff1a; Github仓库【electron_git】 Commit &#xff1a; bb40040 Github Desktop 页面分析 本节目标&#xff1a; 1、实现类似Github Desktop的「空仓库」提示页 2、添加本地仓库逻辑编写从 Github Desktop 我们看到 他的 主要页面分为三个区域 Head头部区域…

14 | fastgo 三层架构设计

提示&#xff1a; 所有体系课见专栏&#xff1a;Go 项目开发极速入门实战课&#xff1b; 在实现业务代码之前&#xff0c;还需要先设计一个合理的软件架构。一个好的软件架构不仅可以大大提高项目的迭代速度&#xff0c;还可以降低项目的阅读和维护难度。目前&#xff0c;行业中…

【机器学习-基础知识】统计和贝叶斯推断

1. 概率论基本概念回顾 1. 概率分布 定义: 概率分布(Probability Distribution)指的是随机变量所有可能取值及其对应概率的集合。它描述了一个随机变量可能取的所有值以及每个值被取到的概率。 对于离散型随机变量,使用概率质量函数来描述。对于连续型随机变量,使用概率…

面向对象Demo01

面向对象 什么是面向对象 回顾方法的定义 package oop; ​ import java.io.IOException; ​ public class Demo01 {public static void main(String[] args) {}//public String sayHello() {return "hello, world!";}public void sayHi() {return;}public int max(i…