达梦数据库中插入导出图片的方法与应用
在数据库的现实应用场景中,图片存储是一项常见且重要的需求。以电商平台为例,商品展示图片是吸引消耗者的关键元素;而在社交软件里,用户头像更是个人形象的直观体现。针对达梦数据库,业界常用的图片存储计谋重要分为两大类。
第一种计谋是将图片存储于磁盘,数据库字段仅记录图片路径。这种方式的明显上风在于减轻了数据库的存储压力,因为数据库无需直接处置处罚图片的二进制数据。然而,它存在明显的范围性,一旦图片存储路径发生变更,大概存储磁盘出现故障,数据库应用在调用图片时就可能遭遇加载失败的问题。例如,若存储图片的磁盘分区因硬件故障损坏,依赖该路径的应用程序将无法正常显示相关图片。
第二种计谋是将图片以二进制形式直接存储于数据库。达梦数据库采用这种方式,并支持使用 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。
查看表
插入完成后,可通过以下语句查看表中的数据:
实验该查询语句后,可看到表中已乐成插入图片相关记录,其中图片字段显示为二进制数据。
在达梦数据库现实应用场景里,不仅会有往数据库表中插入图片的需求,有时也需要从数据库表中导出图片。下面将具体介绍在达梦数据库中导出图片的具体方法。
三、创建图片导出目录
在数据库中定义一个虚拟目录,用于指定图片导出的本地路径。实验以下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;
复制代码
- 参数说明:
- IN_TABLE_NAME:要从中导出图片的表名,数据范例为VARCHAR2(1000)。
- IN_ID:对应表中图片记录的ID,数据范例为INT。
- 变量定义:
- 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)。
- 重要逻辑:
- 构建动态SQL语句,根据传入的表名和ID查询对应的图片数据(BLOB范例)。
- 使用DBMS_LOB.GETLENGTH获取BLOB数据的长度。
- 使用UTL_FILE.FOPEN打开一个文件,文件名为传入的ID加上.JPG后缀,路径为之前定义的IMAGES虚拟目录对应的本地路径,以二进制写模式打开。
- 通过循环读取BLOB数据,并将读取的数据写入文件中。在循环过程中,根据剩余数据长度调整每次读取的字节数,确保完整读取BLOB数据。
- 操作完成后,使用UTL_FILE.FCLOSE关闭文件。
- 异常处置处罚:
- 如果在实验过程中发生其他异常,首先检查文件是否打开,如果打开则关闭文件,然后重新抛出异常,以便上层调用可以或许捕获并处置处罚异常。
五、调用存储过程导出全表图片
通过游标遍历表中全部记录的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;
复制代码
- 定义游标:使用CURSOR定义一个游标cur,用于查询IMAGE_LOB表中的全部T_ID。
- 循环调用存储过程:通过FOR循环遍历游标cur中的每一条记录,将表名IMAGE_LOB和当前记录的T_ID作为参数传递给DUMP_IMAGE_TO_DIR存储过程,实现逐张图片导出到指定目录。
通过以上步调,就可以在达梦数据库中实现从表中导出图片的功能。在现实操作过程中,请确保相关路径精确无误,并且数据库用户具有相应的权限,以保证导出操作的顺遂举行。
综上所述,在 达梦数据库中,开发者可依据现实需求和应用场景,机动选择使用 disql 或通过 manager 调用体系包的方式插入图片。以及使用存储过程的方式导出图片。不同方式各有优劣,在现实项目中,需综合考量数据量、性能要求以及管理维护的便捷性等多方面因素,从而确定最适宜的图片存储和插入方案。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |