Oracle PL/SQL处理CLOB字段的经验
2010-06-11 16:07
441 查看
http://space.itpub.net/111631/viewspace-605827
这段时间在客户现场处理SP处理模版内容替换的技术问题,如果是单点的处理,当然非常简单,使用replace就可以解决问题,但是需要将关键TAG替换成动态行数呢?这就比较麻烦了,下面是处理过程的记录
首先需要说明一下,其实这样的功能使用程序来处理会非常简单,但是处于对技术的追求,还是需要大胆的尝试一下的,哈哈
先想到的就是使用funcation来进行处理,将内容输入,替换后输出多简单,函数如下:
create or replace function Fun_GetTaFundnav_zj
---------------------------------------------------------------------------------------
-- 版 权: 上海XXXXXXXXXXX有限公司
-- 版 本: XXX
-- 开发人员: yeliang.wang
-- 创建日期: 20090609
-- 模块编号: 私有函数
-- 模块名称: XXXXXXX动态数据(邮件)
-- 描 述:
-- 输入参数: 过滤前模板内容
-- 输出参数: 过滤后模板内容
---------------------------------------------------------------------------------------
-- 修改作者:
-- 修改日期:
-- 修改内容:
---------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------
(
--i_content clob, --过滤前模板内容
i_fundcode varchar2, --产品编号
i_tradedate varchar2 ---服务类型
)
return clob
as
newClob clob;
srcClob clob;
v_content VARCHAR2 (32767);
vBuffer VARCHAR2 (32767);
l_amount BINARY_INTEGER := 32767;
l_pos PLS_INTEGER := 1;
l_clob_len PLS_INTEGER;
--对XXXXXX进行定位
cursor r_cust is select * from XX_XX t1 where t1.XX = i_XXX and t1.XXX in ('0','9') and t1.date = i_date;
begin
select DESCRIPTION into srcClob from products where productid = 1;
v_content := '<TR>';
--生成HTML代码--
for r in r_cust loop
v_content := v_content||'<TD class=thtop2 vAlign=center align=middle>'||r.fundcode||'</TD>'
||'<TD class=thtop2 vAlign=center align=middle>'||r.fundname||';</TD>'
||'<TD class=thtop2 vAlign=center align=middle>'||r.updatedate||';</TD>'
||'<TD class=thtop2 vAlign=center align=middle>'||r.fundnav||';</TD>'
||'<TD class=thtop2 vAlign=center align=middle>'||r.totfundnav||';</TD>'
||'<TD class=thtop2_right vAlign=center align=middle>'||r.fundrate||';</TD>';
end loop;
v_content := v_content||'</TR>';
--模板转换
--v_result := replace(i_content,'${fund_replace}',v_content);
return newClob;
end Fun_GetTaFundnav_zj;
执行结果:ORA-03127: 在活动操作结束之前不允许进行操作
晕。。难道是不能使用自定义函数对CLOB进行替换吗?查了相关资料,也没有最后的头绪。。。突发奇想的把问题定位于FUNCTION本身,那么就使用Procedure来处理吧,并且结合dbms_lob来对clob进行处理
存储过程如下:
replaceClob_new --处理CLOB替换过程:
CREATE OR REPLACE PROCEDURE replaceClob_new (
srcClob IN CLOB,
replaceStr IN VARCHAR2,
replaceWith IN VARCHAR2,
newClob OUT CLOB
)
IS
vBuffer VARCHAR2 (32767);
l_amount BINARY_INTEGER := 32767;
l_pos PLS_INTEGER := 1;
l_clob_len PLS_INTEGER;
BEGIN
newClob := EMPTY_CLOB;
-- initalize the new clob
dbms_lob.createtemporary(newClob,TRUE);
--newClob := EMPTY_CLOB;
--srcClob := EMPTY_CLOB;
l_clob_len := dbms_lob.getlength(srcClob);
WHILE l_pos < l_clob_len
LOOP
dbms_lob.read(srcClob, l_amount, l_pos, vBuffer);
IF vBuffer IS NOT NULL THEN
-- replace the text
vBuffer := replace(vBuffer, replaceStr, replaceWith);
-- write it to the new clob
dbms_lob.writeappend(newClob, LENGTH(vBuffer), vBuffer);
END IF;
l_pos := l_pos + l_amount;
END LOOP;
EXCEPTION
WHEN OTHERS THEN
RAISE;
END;
PR_INSERT --先将自己造的测试数据插入:
create or replace procedure pr_insert
is
begin
insert into tmp_XXX_info1
(
..相关字段
)
select seq_XXXX.nextval as id ,
c.subject ,
1,
'2222@aaa.com' ,
c.CONTENT,
1,
1,
1 ,
1,
to_char(sysdate,'yyyy-mm-dd hh24:mi:ss') ,
-1 ,
'',
'' ,
1 ,
1 ,
'',
'',
'',
'',
''
from XXX c;
commit;
PR_CLOB_TEST('373010','20090121');
end pr_insert;
PR_CLOB_TEST --将模版内容进行替换:
CREATE OR REPLACE PROCEDURE PR_CLOB_TEST
(
i_fundcode varchar2, --产品编号
i_tradedate varchar2 ---服务类型
)
IS
LnewClob CLOB := EMPTY_CLOB;
LsrcClob CLOB := EMPTY_CLOB;
varC clob;
ln number(4);
vStrt number(4);
v_content clob;
CURSOR CURSOR_TEMP_CATAN IS
select content from tmp_email_info1;
BEGIN
vStrt := 5;
-- initalize the new clob
FOR r IN (select * from XXX t1 where t1.code = i_code and t1.status in ('0','9') and t1.date = i_date and rownum < 10)
loop
v_content := v_content||'<TR><TD class=thtop2 vAlign=center align=middle>'||r.fundcode||'</TD>'
||'<TD class=thtop2 vAlign=center align=middle>'||r.fundname||'</TD>'
||'<TD class=thtop2 vAlign=center align=middle>'||r.updatedate||'</TD>'
||'<TD class=thtop2 vAlign=center align=middle>'||r.fundnav||'</TD>'
||'<TD class=thtop2 vAlign=center align=middle>'||r.totfundnav||'</TD>'
||'<TD class=thtop2_right vAlign=center align=middle>'||r.fundrate||'</TD>'
||'</TR>';
end loop;
OPEN CURSOR_TEMP_CATAN;
LOOP
FETCH CURSOR_TEMP_CATAN INTO
LsrcClob;
EXIT WHEN CURSOR_TEMP_CATAN%NOTFOUND;
REPLACECLOB_NEW(LsrcClob,'&{fund_replace}',v_content,LnewClob);
select content into varC from tmp_email_info1 for update;
ln := Length(LnewClob);
dbms_lob.write(varC, ln, vStrt, LnewClob);
commit;
END LOOP;
EXCEPTION
WHEN OTHERS THEN
RAISE;
END;
最终结果:测试成功
总结:整个过程就是将一个HTML模版进行关键字的HTML片段替换,是用来给数据网关发送邮件用的,在开发的过程中间遇到了很多问题(在这里不一一例举了),由于PL/SQL在处理超长字符的时候会比较多的限制,用PL/SQL来对这样的功能进行处理真的有点得不偿失,嗨。。。但是最终还是完成了,哈哈。。记录下相关操作和部分代码大家参考
这段时间在客户现场处理SP处理模版内容替换的技术问题,如果是单点的处理,当然非常简单,使用replace就可以解决问题,但是需要将关键TAG替换成动态行数呢?这就比较麻烦了,下面是处理过程的记录
首先需要说明一下,其实这样的功能使用程序来处理会非常简单,但是处于对技术的追求,还是需要大胆的尝试一下的,哈哈
先想到的就是使用funcation来进行处理,将内容输入,替换后输出多简单,函数如下:
create or replace function Fun_GetTaFundnav_zj
---------------------------------------------------------------------------------------
-- 版 权: 上海XXXXXXXXXXX有限公司
-- 版 本: XXX
-- 开发人员: yeliang.wang
-- 创建日期: 20090609
-- 模块编号: 私有函数
-- 模块名称: XXXXXXX动态数据(邮件)
-- 描 述:
-- 输入参数: 过滤前模板内容
-- 输出参数: 过滤后模板内容
---------------------------------------------------------------------------------------
-- 修改作者:
-- 修改日期:
-- 修改内容:
---------------------------------------------------------------------------------------
---------------------------------------------------------------------------------------
(
--i_content clob, --过滤前模板内容
i_fundcode varchar2, --产品编号
i_tradedate varchar2 ---服务类型
)
return clob
as
newClob clob;
srcClob clob;
v_content VARCHAR2 (32767);
vBuffer VARCHAR2 (32767);
l_amount BINARY_INTEGER := 32767;
l_pos PLS_INTEGER := 1;
l_clob_len PLS_INTEGER;
--对XXXXXX进行定位
cursor r_cust is select * from XX_XX t1 where t1.XX = i_XXX and t1.XXX in ('0','9') and t1.date = i_date;
begin
select DESCRIPTION into srcClob from products where productid = 1;
v_content := '<TR>';
--生成HTML代码--
for r in r_cust loop
v_content := v_content||'<TD class=thtop2 vAlign=center align=middle>'||r.fundcode||'</TD>'
||'<TD class=thtop2 vAlign=center align=middle>'||r.fundname||';</TD>'
||'<TD class=thtop2 vAlign=center align=middle>'||r.updatedate||';</TD>'
||'<TD class=thtop2 vAlign=center align=middle>'||r.fundnav||';</TD>'
||'<TD class=thtop2 vAlign=center align=middle>'||r.totfundnav||';</TD>'
||'<TD class=thtop2_right vAlign=center align=middle>'||r.fundrate||';</TD>';
end loop;
v_content := v_content||'</TR>';
--模板转换
--v_result := replace(i_content,'${fund_replace}',v_content);
return newClob;
end Fun_GetTaFundnav_zj;
执行结果:ORA-03127: 在活动操作结束之前不允许进行操作
晕。。难道是不能使用自定义函数对CLOB进行替换吗?查了相关资料,也没有最后的头绪。。。突发奇想的把问题定位于FUNCTION本身,那么就使用Procedure来处理吧,并且结合dbms_lob来对clob进行处理
存储过程如下:
replaceClob_new --处理CLOB替换过程:
CREATE OR REPLACE PROCEDURE replaceClob_new (
srcClob IN CLOB,
replaceStr IN VARCHAR2,
replaceWith IN VARCHAR2,
newClob OUT CLOB
)
IS
vBuffer VARCHAR2 (32767);
l_amount BINARY_INTEGER := 32767;
l_pos PLS_INTEGER := 1;
l_clob_len PLS_INTEGER;
BEGIN
newClob := EMPTY_CLOB;
-- initalize the new clob
dbms_lob.createtemporary(newClob,TRUE);
--newClob := EMPTY_CLOB;
--srcClob := EMPTY_CLOB;
l_clob_len := dbms_lob.getlength(srcClob);
WHILE l_pos < l_clob_len
LOOP
dbms_lob.read(srcClob, l_amount, l_pos, vBuffer);
IF vBuffer IS NOT NULL THEN
-- replace the text
vBuffer := replace(vBuffer, replaceStr, replaceWith);
-- write it to the new clob
dbms_lob.writeappend(newClob, LENGTH(vBuffer), vBuffer);
END IF;
l_pos := l_pos + l_amount;
END LOOP;
EXCEPTION
WHEN OTHERS THEN
RAISE;
END;
PR_INSERT --先将自己造的测试数据插入:
create or replace procedure pr_insert
is
begin
insert into tmp_XXX_info1
(
..相关字段
)
select seq_XXXX.nextval as id ,
c.subject ,
1,
'2222@aaa.com' ,
c.CONTENT,
1,
1,
1 ,
1,
to_char(sysdate,'yyyy-mm-dd hh24:mi:ss') ,
-1 ,
'',
'' ,
1 ,
1 ,
'',
'',
'',
'',
''
from XXX c;
commit;
PR_CLOB_TEST('373010','20090121');
end pr_insert;
PR_CLOB_TEST --将模版内容进行替换:
CREATE OR REPLACE PROCEDURE PR_CLOB_TEST
(
i_fundcode varchar2, --产品编号
i_tradedate varchar2 ---服务类型
)
IS
LnewClob CLOB := EMPTY_CLOB;
LsrcClob CLOB := EMPTY_CLOB;
varC clob;
ln number(4);
vStrt number(4);
v_content clob;
CURSOR CURSOR_TEMP_CATAN IS
select content from tmp_email_info1;
BEGIN
vStrt := 5;
-- initalize the new clob
FOR r IN (select * from XXX t1 where t1.code = i_code and t1.status in ('0','9') and t1.date = i_date and rownum < 10)
loop
v_content := v_content||'<TR><TD class=thtop2 vAlign=center align=middle>'||r.fundcode||'</TD>'
||'<TD class=thtop2 vAlign=center align=middle>'||r.fundname||'</TD>'
||'<TD class=thtop2 vAlign=center align=middle>'||r.updatedate||'</TD>'
||'<TD class=thtop2 vAlign=center align=middle>'||r.fundnav||'</TD>'
||'<TD class=thtop2 vAlign=center align=middle>'||r.totfundnav||'</TD>'
||'<TD class=thtop2_right vAlign=center align=middle>'||r.fundrate||'</TD>'
||'</TR>';
end loop;
OPEN CURSOR_TEMP_CATAN;
LOOP
FETCH CURSOR_TEMP_CATAN INTO
LsrcClob;
EXIT WHEN CURSOR_TEMP_CATAN%NOTFOUND;
REPLACECLOB_NEW(LsrcClob,'&{fund_replace}',v_content,LnewClob);
select content into varC from tmp_email_info1 for update;
ln := Length(LnewClob);
dbms_lob.write(varC, ln, vStrt, LnewClob);
commit;
END LOOP;
EXCEPTION
WHEN OTHERS THEN
RAISE;
END;
最终结果:测试成功
总结:整个过程就是将一个HTML模版进行关键字的HTML片段替换,是用来给数据网关发送邮件用的,在开发的过程中间遇到了很多问题(在这里不一一例举了),由于PL/SQL在处理超长字符的时候会比较多的限制,用PL/SQL来对这样的功能进行处理真的有点得不偿失,嗨。。。但是最终还是完成了,哈哈。。记录下相关操作和部分代码大家参考
相关文章推荐
- 拼组SQL中,Oracle插入超4000字节的CLOB字段的处理方法
- PL/SQL Oracle 用sql query查询,中文字段内容显示异常的处理
- 处理CLOB字段的动态PL/SQL
- Oracle PL/SQL开发基础(第三十六弹:异常处理的一些经验)
- Oracle使用PL/SQL脚本给表结构相同的动态表添加字段
- openjpa实体类中大数据集(oracle clob)的字段处理
- 在64位Win7下安装Oracle 10g客户端,以及PL/SQL Developer的经验
- Oracle PL/SQL之处理index不连续的table类型变量
- "ORA-06502: PL/SQL: 数字或值错误 : 字符串缓冲区太小"的解决,总结一下oracle开发的小经验
- 109---oracle的oracle的PL/SQL,异常处理, 游标(CURSOR), 子程序,存储过程
- 如何通过sql的insert语句插入大量字符串到oracle的clob字段?
- oracle 定长字段查询问题 ,ibatis 与pl/sql查询的char类型字段查询不同
- Oracle PL/SQL 非预定义异常、自定义异常处理、RAISE_APPLICATION_ERROR
- 如何在PL/SQL中修改ORACLE的字段顺序
- Oracle 学习:PL/SQL循序渐进全面学习教程--最后一课 异常处理
- 经验分享--免安装Oracle客户端使用PL/SQL
- 工作总结15 sql的insert语句插入大量字符串到oracle的clob字段
- oracle 中clob数据在Java类 里sql处理
- .Net处理Oracle中Clob类型字段总结
- jdbc处理oracle的clob字段