在C#中保存一个从MySQL到Oracle的PDF文件,其间无需任何转换

本文关键字:文件 PDF 转换 任何 Oracle 保存 MySQL 一个 | 更新日期: 2023-09-27 18:20:17

嗨,我需要将存储在BLOB类型中的PDF从MySQL传输到Oracle。我知道如何在byte[]中转换为它,然后将其保存在Oracle中。

我的问题是,是否有其他选项可以避免这种转换并加快过程?任何类似于将MySQL文件保存在对象中直接将其提供给Oracle查询的操作?

在C#中保存一个从MySQL到Oracle的PDF文件,其间无需任何转换

如果您想将BLOB从一个RDBMS移动到另一个RDMS,您就无法逃离这些段落,因为您的程序必须:

  1. 从源读取二进制数据
  2. 将数据写入目标

如果您有BLOB要转换,IMHO的更好方法是:

  1. 将转换步骤封装在方法中
  2. 根据您的系统功能对每个转换任务进行多线程处理

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不允许您更新BFILEs,所以您必须通过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; 
/