在C#中保存一个从MySQL到Oracle的PDF文件,其间无需任何转换
本文关键字:文件 PDF 转换 任何 Oracle 保存 MySQL 一个 | 更新日期: 2023-09-27 18:20:17
嗨,我需要将存储在BLOB
类型中的PDF从MySQL传输到Oracle。我知道如何在byte[]
中转换为它,然后将其保存在Oracle中。
我的问题是,是否有其他选项可以避免这种转换并加快过程?任何类似于将MySQL文件保存在对象中直接将其提供给Oracle查询的操作?
如果您想将BLOB从一个RDBMS移动到另一个RDMS,您就无法逃离这些段落,因为您的程序必须:
- 从源读取二进制数据
- 将数据写入目标
如果您有批BLOB要转换,IMHO的更好方法是:
- 将转换步骤封装在方法中
- 根据您的系统功能对每个转换任务进行多线程处理
Oracle和MySQL是完全不同的系统。当你将二进制数据从一个移动到另一个时,你必须经历这个转换过程。
虽然MySql和ODP.Net都以流的形式访问Blob,但为了从一个Blob读取并向另一个Blob写入,您的程序需要说通用语言,而.Net中的通用语言是byte[]
。
现在,使用Oracle,您可以将文件存储为BFILE
,它只是一个文件系统文件,而不是由RDBMS管理的文件。如果您这样做,那么您可以将MySql中的所有Blob转储到这个答案中列出的目录中,然后完全跳过MySql的字节数组转换。
将BFILE添加到Oracle将是一个批处理作业,您可以在MySql转储完成后运行:
CREATE DIRECTORY test_dir AS '/tmp' -- replace tmp with actual my sql dump directory
-- Inserting the BFiles
INSERT INTO my_bfile_table VALUES (..., bfilename(test_dir, 'file1.pdf'));
INSERT INTO my_bfile_table VALUES (..., bfilename(test_dir, 'file2.pdf'));
...
注意,ODP.Net不允许您更新BFILE
s,所以您必须通过SQL命令插入它们,如上所示。不过,您可以通过JDBC和其他接口来实现。
如果文件很大,那么由于减少了事务日志活动,您实际上可以获得一些性能改进。当然,存储为BFILE
会带来一些折衷(如可管理性降低、需要单独备份文件系统等),因此您可能需要考虑这些问题。
如果你有选择,那么探索一下这个想法——跳过将PDF完全存储在数据库中(BLOB或BFILE),将它们移动到CDN,并在数据库中只存储CDN资产的定位器(URI)。不仅数据库将得到很大程度的缓解,最终用户体验也可能得到改善。当然,这取决于您的应用程序及其要求,但可能值得探索。
从MySql读取BLOB时,我认为您没有其他选择(以byte[]存储)。但是,如果在插入Oracle时有大量记录要移动,出于性能考虑,可以在ODP.NET中使用Oracle.DataAccess.Client.OracleBulkCopy。
http://docs.oracle.com/html/E10927_01/OracleBulkCopyClass.htm
如果我正确理解你的问题,你在MySQL数据库中有一个PDF文件,你想把它移到Oracle数据库中,保持数据类型为BLOB。
您需要做的第一件事是,将文件移动到Oracle可以读取它的目录位置。然后,您所需要做的就是将PDF加载到表的BLOB列中。
CREATE OR replace PROCEDURE Load_lob
AS
id NUMBER;
pdf1 BLOB;
locator BFILE;
bfile_len NUMBER;
bf_desc VARCHAR2(30);
bf_name VARCHAR2(30);
bf_dir VARCHAR2(30);
bf_typ VARCHAR2(4);
ctr INTEGER;
CURSOR get_id IS
SELECT bfile_id,
bfile_desc,
bfile_type
FROM pdf_table;
BEGIN
OPEN get_id;
LOOP
FETCH get_id INTO id, bf_desc, bf_typ;
EXIT WHEN get_id%NOTFOUND;
dbms_output.Put_line('ID: '
||To_char(id));
SELECT bfile_loc
INTO locator
FROM pdf_table
WHERE bfile_id = id;
dbms_lob.Filegetname(locator, bf_dir, bf_name);
dbms_output.Put_line('Dir: '
||bf_dir);
dbms_lob.Fileopen(locator, dbms_lob.file_readonly);
bfile_len := dbms_lob.Getlength(locator);
dbms_output.Put_line('ID: '
||To_char(id)
||' length: '
||To_char(bfile_len));
SELECT temp_blob
INTO pdf1
FROM temp_blob;
bfile_len := dbms_lob.Getlength(locator);
dbms_lob.Loadfromfile(pdf1, locator, bfile_len, 1, 1);
INSERT INTO internal_graphics
VALUES (id,
bf_desc,
pdf1,
bf_typ);
dbms_output.Put_line(bf_desc
||' Length: '
||To_char(bfile_len)
|| ' Name: '
||bf_name
||' Dir: '
||bf_dir
||' '
||bf_typ);
dbms_lob.Fileclose(locator);
END LOOP;
END;
/