Chinaunix首页 | 论坛 | 博客
  • 博客访问: 266062
  • 博文数量: 34
  • 博客积分: 569
  • 博客等级: 中士
  • 技术积分: 380
  • 用 户 组: 普通用户
  • 注册时间: 2012-05-10 14:10
文章分类

全部博文(34)

文章存档

2016年(6)

2014年(1)

2013年(5)

2012年(22)

我的朋友

分类: Oracle

2013-11-28 11:21:43

场景说明

在oracle存储过程中需要输入自己拼装的字符串,但是该字符串太长,只能通过clob字段进行存储。但是解析clob字段和解析varchar2的方式很不一样。
拼装的结构暂定 1~a~101|1~b~101|1~xa~101|4~xc~133|5~a~0|。。。每段内容使用"|"分隔,每段内容里面的内容使用"~"进行分隔。

解决方法

1、设定每次读取clob字段的最大长度;
2、读取字段内容,并找到完整的拼装数据;
3、更新下一次读取clob字段的起始节点;
4、从1开始循环。

1.定义循环次数和读取clob字段的最大长度

  1. lv_tmp_offset := dbms_lob.getlength(v_elements);
  2. lv_count := ceil(lv_tmp_offset / lv_limit)+1;
  3. lv_limit := 3000;
2.读取内容。并更新下次读取的起始位置。
  1. dbms_lob.read(v_elements, lv_limit, lv_offset, lv_elements);
  2. lv_tmp_offset := instr(lv_elements, '|', -1, 1);
  3. lv_elements := substr(lv_elements, 0, lv_tmp_offset);
  4. lv_offset := lv_offset + lv_tmp_offset;

附上原过程

  1. PROCEDURE addtemplate_p(v_name IN VARCHAR2,
  2.                           v_expiredate IN VARCHAR2,
  3.                           v_status IN VARCHAR2,
  4.                           v_remark IN VARCHAR2,
  5.                           v_storeno IN VARCHAR2,
  6.                           v_elements IN CLOB,
  7.                           v_x0 IN VARCHAR2,
  8.                           v_y0 IN VARCHAR2,
  9.                           v_x1 IN VARCHAR2,
  10.                           v_y1 IN VARCHAR2,
  11.                           v_operid IN VARCHAR2,
  12.                           v_opername IN VARCHAR2,
  13.                           v_ret OUT NUMBER,
  14.                           v_desc OUT VARCHAR2) AS
  15.     lv_id NUMBER;
  16.     lv_eid NUMBER;
  17.     lv_x0 VARCHAR2(100);
  18.     lv_y0 VARCHAR2(100);
  19.     lv_x1 VARCHAR2(100);
  20.     lv_y1 VARCHAR2(100);
  21.     lv_type CHAR(1);
  22.     lv_style VARCHAR2(1000);
  23.     lv_value VARCHAR2(100);
  24.     lv_flag CHAR(1);
  25.     lv_elements VARCHAR2(3000);
  26.     lv_limit NUMBER;
  27.     lv_offset NUMBER;
  28.     lv_tmp_offset NUMBER;
  29.     lv_count NUMBER;
  30.     i NUMBER;
  31.     n NUMBER;
  32.     CURSOR cur_rec IS
  33.       SELECT column_value rec FROM TABLE(fn_split(lv_elements, '|'));
  34.     row_rec cur_rec%ROWTYPE;
  35.   BEGIN
  36.     SELECT seq_template_p_id.nextval INTO lv_id FROM dual;
  37.     lv_limit := 3000;
  38.     lv_offset := 1;
  39.     lv_count := 1;
  40.     i := 1;
  41.     n := 0;
  42.     IF v_elements IS NULL THEN
  43.       RETURN;
  44.     END IF;
  45.     lv_tmp_offset := dbms_lob.getlength(v_elements);
  46.     lv_count := ceil(lv_tmp_offset / lv_limit)+1;
  47.     WHILE i < lv_count
  48.     LOOP
  49.       BEGIN
  50.         IF i = lv_count - 1 THEN
  51.           lv_limit := MOD(dbms_lob.getlength(v_elements), lv_limit);
  52.         END IF;
  53.         dbms_lob.read(v_elements, lv_limit, lv_offset, lv_elements);
  54.         lv_tmp_offset := instr(lv_elements, '|', -1, 1);
  55.         lv_elements := substr(lv_elements, 0, lv_tmp_offset);
  56.         lv_offset := lv_offset + lv_tmp_offset;
  57.         i := i + 1;
  58.         OPEN cur_rec;
  59.         LOOP
  60.           FETCH cur_rec
  61.             INTO row_rec;
  62.           EXIT WHEN cur_rec%NOTFOUND OR cur_rec%NOTFOUND IS NULL;
  63.           SELECT seq_element_id.nextval INTO lv_eid FROM dual;
  64.           lv_x0 := rtrim(regexp_substr(row_rec.rec || '~', '.*?~', 1, 1),
  65.                          '~');
  66.           lv_y0 := rtrim(regexp_substr(row_rec.rec || '~', '.*?~', 1, 2),
  67.                          '~');
  68.           lv_x1 := rtrim(regexp_substr(row_rec.rec || '~', '.*?~', 1, 3),
  69.                          '~');
  70.           lv_y1 := rtrim(regexp_substr(row_rec.rec || '~', '.*?~', 1, 4),
  71.                          '~');
  72.           lv_type := rtrim(regexp_substr(row_rec.rec || '~', '.*?~', 1, 5),
  73.                            '~');
  74.           lv_style := rtrim(regexp_substr(row_rec.rec || '~', '.*?~', 1, 6),
  75.                             '~');
  76.           lv_value := rtrim(regexp_substr(row_rec.rec || '~', '.*?~', 1, 7),
  77.                             '~');
  78.           lv_flag := rtrim(regexp_substr(row_rec.rec || '~', '.*?~', 1, 8),
  79.                            '~');
  80.           --插入元素
  81.           INSERT INTO pop_element
  82.             (tid, eid, x0, y0, x1, y1, style, TYPE, VALUE, flag)
  83.           VALUES
  84.             (lv_id,
  85.              lv_eid,
  86.              lv_x0,
  87.              lv_y0,
  88.              lv_x1,
  89.              lv_y1,
  90.              lv_style,
  91.              lv_type,
  92.              lv_value,
  93.              lv_flag);
  94.         END LOOP;
  95.         CLOSE cur_rec;
  96.       END;
  97.     END LOOP;
  98.     --插入母版信息
  99.     INSERT INTO pop_temp_p
  100.       (id,
  101.        status,
  102.        expiredate,
  103.        NAME,
  104.        operid,
  105.        opername,
  106.        createdate,
  107.        storeno,
  108.        remark,
  109.        x0,
  110.        y0,
  111.        x1,
  112.        y1)
  113.     VALUES
  114.       (lv_id,
  115.        v_status,
  116.        to_date(v_expiredate, 'yyyy-mm-dd'),
  117.        v_name,
  118.        v_operid,
  119.        v_opername,
  120.        SYSDATE,
  121.        v_storeno,
  122.        v_remark,
  123.        v_x0,
  124.        v_y0,
  125.        v_x1,
  126.        v_y1);
  127.     --记录日志
  128.     INSERT INTO sys_log_pop
  129.       (module, operid, opername, operdate, key, remark)
  130.     VALUES
  131.       ('新增母版信息', v_operid, v_opername, SYSDATE, '', '新增母版信息');
  132.     COMMIT;
  133.     v_ret := 1;
  134.     v_desc := '操作成功';
  135.   EXCEPTION
  136.     WHEN OTHERS THEN
  137.       v_ret := -1;
  138.       v_desc := '操作失败,' || SQLERRM;
  139.       ROLLBACK;
  140.   END;




阅读(4738) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~