关于Oracle中使用pljson及中文乱码解决方案
一、创建生成json的sql优化函数:
1 create or replace function sql_to_json_clob(i_sql varchar2,i_batch_rownum number default 100) return clob is 2 FunctionResult clob; 3 l_clob CLOB; --最终结果 4 l_sql2 VARCHAR2(30000); --排序SQL 5 l_col_name_str VARCHAR2(10000); --字段名串 6 l_sql3 VARCHAR2(30000); --分页SQL 7 l_row_count NUMBER; --已经处理的行数 8 l_sum_count NUMBER; --总行数 9 l_clob_tmp CLOB; --缓存 10 l_curid INTEGER; 11 l_cnt NUMBER; 12 l_desctab dbms_sql.desc_tab; 13 begin 14 --统计行数 15 EXECUTE IMMEDIATE 'select count(1) from (' || i_sql || ')' 16 INTO l_sum_count; 17 --如果没数据,返回空LIST 18 IF l_sum_count = 0 19 THEN 20 RETURN '[]'; 21 END IF; 22 23 --开始取字段名称 24 l_curid := dbms_sql.open_cursor(); 25 dbms_sql.parse(l_curid, i_sql, dbms_sql.native); 26 dbms_sql.describe_columns(l_curid, l_cnt, l_desctab); 27 FOR i IN 1 .. l_desctab.count LOOP 28 l_col_name_str := l_col_name_str || CASE 29 WHEN l_col_name_str IS NULL THEN 30 NULL 31 ELSE 32 ',' 33 END || '"' || l_desctab(i).col_name || '"'; 34 END LOOP; 35 --取字段名称结束 36 37 --组装排序SQL 38 l_sql2 := 'select t.*,row_number() over(order by ' || l_col_name_str || 39 ') rn from (' || i_sql || ') t order by ' || 40 to_char(l_desctab.count + 1); 41 --关闭游标 42 dbms_sql.close_cursor(l_curid); 43 -- dbms_output.put_line(l_sql2); 44 45 --初始化处理记录数 46 l_row_count := 0; 47 --初始化CLOB对象 48 l_clob := empty_clob(); 49 dbms_lob.createtemporary(l_clob, TRUE); 50 51 --开始进行分页处理 52 LOOP 53 --组装分页SQL 54 l_sql3 := 'select ' || l_col_name_str || ' from (' || l_sql2 || 55 ') where rn > ' || to_char(l_row_count) || ' and rn<=' || 56 to_char(l_row_count + i_batch_rownum); 57 -- dbms_output.put_line(l_sql3); 58 --初始化缓存对象 59 l_clob_tmp := empty_clob(); 60 dbms_lob.createtemporary(l_clob_tmp, TRUE); 61 62 --SQL转换成JSONLIST再转换成CLOB,存入缓存 63 pljson_list.to_clob(SELF => pljson_util_pkg.sql_to_json(l_sql3, 64 i_batch_rownum, 65 0), 66 buf => l_clob_tmp, 67 erase_clob => TRUE); 68 69 --将缓存复制到CLOB对象 70 dbms_lob.copy(dest_lob => l_clob, 71 src_lob => l_clob_tmp, 72 amount => dbms_lob.getlength(l_clob_tmp), 73 dest_offset => dbms_lob.getlength(l_clob) + 1, 74 src_offset => CASE 75 WHEN dbms_lob.getlength(l_clob) = 0 THEN 76 1 77 ELSE 78 2 79 END); 80 81 --已处理行数变大 82 l_row_count := l_row_count + i_batch_rownum; 83 84 --如果已处理行数小于总行数,把CLOB内的最后一个字符,由"]"变成"," ,否则退出循环 85 IF l_row_count < l_sum_count 86 THEN 87 dbms_lob.write(lob_loc => l_clob, 88 amount => 1, 89 offset => dbms_lob.getlength(l_clob), 90 buffer => ','); 91 ELSE 92 EXIT; 93 END IF; 94 95 END LOOP; 96 --返回最终结果 97 RETURN l_clob; 98 EXCEPTION 99 WHEN OTHERS THEN 100 raise_application_error(-20001, SQLERRM); 101 --return(FunctionResult); 102 end sql_to_json_clob;
通过plsql的command Window安装对应的pljosn包:
SQL> @C:/pljson/pljson-master/install.sql
使用pljosn过程中,会出现中文乱码,可以使用如下解决方案:
在程序包体中找到PLJSON_PRINTER,如下进行注释,添加else null,重新编译。
注:本人在重新编译之后,执行函数 sql_to_json_clob无效异常,关闭PLSQL,重新登录plsql即可解决。
二、通过pljosn包json_dyn.executeList,可将指定表转换成json数组对象:
declare ret json_list; begin ret := json_dyn.executeList('select bns_type,workflow_name from base_workflow group by bns_type,workflow_name'); ret.print; end;
输出结果为:
[{ "BNS_TYPE" : "500", "WORKFLOW_NAME" : "评估机构注销" }, { "BNS_TYPE" : "100", "WORKFLOW_NAME" : "协会品牌新建" }, { "BNS_TYPE" : "100", "WORKFLOW_NAME" : "经纪机构新建" }, { "BNS_TYPE" : "100", "WORKFLOW_NAME" : "行业检查新建1" }, { "BNS_TYPE" : "500", "WORKFLOW_NAME" : "品牌注销" }, { "BNS_TYPE" : "500", "WORKFLOW_NAME" : "窗口网签合同注销" }, { "BNS_TYPE" : "200", "WORKFLOW_NAME" : "荣誉申报变更" }, { "BNS_TYPE" : "100", "WORKFLOW_NAME" : "机构网签合同签订" }, { "BNS_TYPE" : "100", "WORKFLOW_NAME" : "协会推送机构新建" }, { "BNS_TYPE" : "200", "WORKFLOW_NAME" : "协会品牌变更"
通过json_dyn.executeObjec转换成json对象:
declare ret json; begin ret := json_dyn.executeObject('select bns_type,workflow_name from base_workflow group by bns_type,workflow_name'); ret.print; end;
输出结果为:
{ "names" : ["BNS_TYPE", "WORKFLOW_NAME"], "data" : [["500", "评估机构注销"], ["100", "协会品牌新建"], ["100", "经纪机构新建"], ["100", "行业检查新建1"], ["500", "品牌注销"], ["500", "窗口网签合同注销"], ["200", "荣誉申报变更"], ["100", "机构网签合同签订"], ["100", "协会推送机构新建"], ["200", "协会品牌变更"], ["100", "卖房委托新建(机构)"], ["100", "机构审批部门申请房源核验码"], ["500", "经纪机构注销"], ["200", "协会经纪机构变更"], ["500", "交易中心代办购房资格注销"], ["100", "行业检查新建"], ["100", "个人申请房源核验码"], ["200", "委卖协议变更-机构"], ["500", "网签合同注销"], ["100", "评估机构新建"], ["100", "123123123"], ["200", "经纪机构变更"], ["100", "荣誉申报新增"], ["200", "委买协议变更"], ["500", "卖房委托取消(机构)"], ["100", "个人用户新建投诉"], ["200", "协会经纪人变更"], ["100", "购房资格申请"], ["200", "评估人员变更"], ["100", "协会经纪人新建"], ["100", "交易中心代办购房资格新建"], ["500", "手拉手网签合同注销"], ["100", "租赁处投诉新建"], ["100", "经纪机构网签合同新建"], ["100", "评估人员新增"], ["100", "经纪机构审核密钥代办购房资格申请"], ["100", "窗口网签合同"], ["100", "经纪人新建"], ["100", "委卖协议新建"], ["200", "行业检查变更"], ["200", "委卖协议变更-卖方"], ["500", "协会经纪人注销"], ["500", "协会品牌注销"], ["100", "委买协议新建"], ["100", "品牌新建"], ["100", "经纪机构录入密钥代办购房资格新建"], ["100", "房源核验码申请"], ["500", "协会经纪机构注销"], ["100", "手拉手网签合同"], ["200", "品牌变更"], ["200", "经纪人变更"], ["500", "经纪人注销02"], ["500", "经纪人注销1"], ["100", "个人申请购房资格新建"], ["100", "测试流程"], ["200", "评估机构变更"], ["500", "评估人员注销"], ["500", "卖房委托取消(个人)"], ["500", "经纪人注销"], ["100", "机构录入部门申请核验码"], ["500", "个人注销购房资格申请"], ["500", "委卖协议注销"], ["500", "委买协议注销"], ["100", "卖房委托新建(个人)"]] }
构建json:
declare json_obj json; json_lst_100 json_list; json_lst_500 json_list; obj json; begin obj:=json(); --obj.put('新建',100); json_obj := json_dyn.executeObject('select bns_type,workflow_name from base_workflow group by bns_type,workflow_name'); json_lst_100:=json_dyn.executeList('select bns_type,workflow_name from base_workflow where bns_type=100 group by bns_type,workflow_name '); json_lst_500:=json_dyn.executeList('select bns_type,workflow_name from base_workflow where bns_type=500 group by bns_type,workflow_name'); --ret.put('children',ret); --obj.put('children',json_lst_100); obj.put('注销',500); obj.put('children',json_lst_500); obj.print; --ret.get_values().print; --ret.get_keys().print; end;
生命需要感动和奇迹。成功不易,放弃简单。每次感觉走不下去的时候,就是通往成功的节点。努力吧,奋斗吧,即使不被全世界看好。至少,也要做个坏孩子啊