《Oracle PL/SQL开发指南》学习笔记33——源码调试——大对象(第二部分,将文件读入内部存储的列)

这节内容的调试花费了很多时间,却还有个遗留问题——中文(多字节字符)文件的读取。

1. 以sys身份创建虚拟目录,将大对象源文件复制到该目录下

SQL> CREATE DIRECTORY generic AS 'D:\temp';

2. 为c##student用户授权

GRANT READ ON DIRECTORY generic TO c##student;

3. 创建存储过程

-- Create stored procedure to load a CLOB datatype.
CREATE OR REPLACE PROCEDURE load_clob_from_file
( src_file_name     IN VARCHAR2
, table_name        IN VARCHAR2
, column_name       IN VARCHAR2
, primary_key_name  IN VARCHAR2
, primary_key_value IN VARCHAR2) IS

  -- Define local variables for DBMS_LOB.LOADCLOBFROMFILE procedure.
  --src_csid number :=NLS_CHARSET_ID('UTF8'); added
  --ZHS16GBK, SIMPLIFIED CHINESE_CHINA.ZHS16GBK,AL16UTF16, AL32UTF8
  des_clob   CLOB;
  src_clob   BFILE := BFILENAME('GENERIC',src_file_name);
  des_offset NUMBER := 1;
  src_offset NUMBER := 1;
  src_csid number := dbms_lob.default_csid;
  ctx_lang   NUMBER := dbms_lob.default_lang_ctx;
  warning    NUMBER;
  
  -- Define a pre-reading size.
  src_clob_size NUMBER;
  
  -- Define local variable for Native Dynamic SQL.
  stmt VARCHAR2(2000);

BEGIN

  -- Opening source file is a mandatory operation.
  IF dbms_lob.fileexists(src_clob) = 1 AND dbms_lob.isopen(src_clob) = 0 THEN
    src_clob_size := dbms_lob.getlength(src_clob);
    dbms_lob.open(src_clob,DBMS_LOB.LOB_READONLY);
  END IF;
  
  -- Assign dynamic string to statement.
  stmt := 'UPDATE '||table_name||' '
       || 'SET    '||column_name||' = empty_clob() '
       || 'WHERE  '||primary_key_name||' = '||''''||primary_key_value||''' '
       || 'RETURNING '||column_name||' INTO :locator';

  -- Run dynamic statement.       
  EXECUTE IMMEDIATE stmt USING OUT des_clob;
 
  -- Read and write file to CLOB, close source file and commit.
  
  --bfile_csid   => dbms_lob.default_csid
  --CLOB CHARACTER SET ANY_CS
  dbms_lob.loadclobfromfile( dest_lob => des_clob
                           , src_bfile    => src_clob
                           , amount       => dbms_lob.getlength(src_clob)
                           , dest_offset  => des_offset
                           , src_offset   => src_offset
                           , bfile_csid   => src_csid
                           , lang_context => ctx_lang
                           , warning      => warning );

  -- Close open source file.
  dbms_lob.close(src_clob);

  -- Commit write and conditionally acknowledge it.
  IF src_clob_size = dbms_lob.getlength(des_clob) THEN
    $IF $$DEBUG = 1 $THEN
      dbms_output.put_line('Success!');
    $END
    COMMIT;
  ELSE
    $IF $$DEBUG = 1 $THEN
      dbms_output.put_line('Failure.');
    $END
    RAISE dbms_lob.operation_failed;
  END IF;
  
END load_clob_from_file;
/

4. 读入前测试

SQL> SELECT item_id
  2  ,      item_title
  3  ,      dbms_lob.getlength(item_desc) AS "SIZE"
  4  FROM   item
  5  WHERE  dbms_lob.getlength(item_desc) > 0;

ITEM_ID ITEM_TITLE                                               SIZE
------- -------------------------------------------------- ----------
   1037 The Lord of the Rings - Fellowship of the Ring              6
   1038 The Lord of the Rings - Fellowship of the Ring              6
   1039 The Lord of the Rings - Fellowship of the Ring              6

5. 读入大对象源文件到item_desc列(大对象)

SQL> -- Insert description in all matching rows.
SQL> BEGIN
  2    FOR i IN (SELECT item_id
  3              FROM   item
  4              WHERE  item_title = 'The Lord of the Rings - Fellowship of the Ring'
  5              AND    item_type IN (SELECT common_lookup_id
  6                                   FROM   common_lookup
  7                                   WHERE  common_lookup_table = 'ITEM'
  8                                   AND    common_lookup_column = 'ITEM_TYPE'
  9                                   AND    REGEXP_LIKE(common_lookup_type,'^(dvd|vhs)*','i'))) LOOP
 10      -- Call procedure for matching rows.
 11      load_clob_from_file( src_file_name     => 'LOTRFellowship.txt'
 12                         , table_name        => 'ITEM'
 13                         , column_name       => 'ITEM_DESC'
 14                         , primary_key_name  => 'ITEM_ID'
 15                         , primary_key_value => TO_CHAR(i.item_id)
 16     );
 17    END LOOP;
 18  END;
 19  /

PL/SQL 过程已成功完成。

6. 读入后测试

SQL> -- Check after load.
SQL> SELECT item_id
  2  ,      item_title
  3  ,      dbms_lob.getlength(item_desc) AS "SIZE"
  4  FROM   item
  5  WHERE  dbms_lob.getlength(item_desc) > 0;

ITEM_ID ITEM_TITLE                                               SIZE
------- -------------------------------------------------- ----------
   1037 The Lord of the Rings - Fellowship of the Ring           5056
   1038 The Lord of the Rings - Fellowship of the Ring           5056
   1039 The Lord of the Rings - Fellowship of the Ring           5056

7. Toad中验证

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值