本文来自李明子csdn博客(http://blog.csdn.net/free1985),商业转载请联系博主获得授权,非商业转载请注明出处!
5.8 转换字符串
对于JSON、JSON_LIST和JSON_VALUE都可以通过to_char函数转换为字符串。to_char函数有两个参数,其中“spaces”表示是否填充空格,默认为“true”;“chars_per_line”表示每行的字符数,默认值为“0”,表示不限制。
to_char函数在以上几节(如对象构造)的示例中已多次出现,此处不再单独给出示例。
5.9 处理大文本
很多时候,json对象中会包含大文本,此时已超过varchar2的限制,只能使用clob类型。JSON、JSON_LIST和JSON_VALUE均包含方法to_clob。下面是该方法的使用示例:
--JSON大文本示例
procedure EG_CLOB is
--json对象
aJsonObj json;
--源文本
srcClob clob;
--目标文本
desClob clob;
begin
--对于实际应用,目标文本的指针应从已建立的记录中获取,
--这里简化为新建clob对象
desClob := empty_clob();
dbms_lob.createtemporary(desClob, true);
--假设json对象key1的值是个大文本
aJsonObj := json('{"key1":"a long long text..."}');
--直接用pljson存入会在clob值的两侧有双引号
srcClob := empty_clob();
dbms_lob.createtemporary(srcClob, true);
aJsonObj.get('key1').to_clob(srcClob, true);
dbms_lob.copy(desClob, srcClob, dbms_lob.getlength(srcClob) - 2, 1, 2);
dbms_lob.freetemporary(srcClob);
dbms_output.put_line(desClob);
dbms_lob.freetemporary(desClob);
end;
5.10 使用JSON PATH导航
JSON和JSON_LIST对象都包含一组导航方法用于直接操作JSON或JSON数组中指定位置的值。其中,path方法用于获取指定位置的值;path_put方法用于添加或修改指定位置的值;path_remove方法用于删除指定位置的值。
以上方法的核心参数是用于导航的path字符串。这个path字符串是按层次组成的一组“[]”序列。其中,每个“[]”中放置该层次中的序号(名值对序号或数组中的元素序号)或key值。
比如图5-2所示的JSON字符串,[1][2]代表的导航过程如图5-3所示,[1][2][1]代表的导航过程如图5-4所示,[“L1K1”][1][“L2K1”]代表的导航过程如图5-5所示。
图5-2 JSON PATH导航示例
图5-3 [1][2]代表的导航过程
图5-4 [1][2][1]代表的导航过程
图5-5 [“L1K1”][1][“L2K1”]代表的导航过程
JSON PATH的示例代码如下:
--JSON PATH示例
procedure EG_PATH is
--json对象
aJsonObj json;
--另一个json对象
anotherJsonObj json;
begin
aJsonObj := json('{"Level1Key1":[{"Level2Key1":"a"},{"Level2Key1":"b"}]
,"Level1Key2":123}');
--输出为{"Level2Key1":"b"}
aJsonObj.path('[1][2]').print;
--输出为b
aJsonObj.path('[1][2][1]').print;
--输出为a
aJsonObj.path('["Level1Key1"][1]["Level2Key1"]').print;
anotherJsonObj := json(aJsonObj.path('[1][1]'));
anotherJsonObj.put('Level2Key2', true);
aJsonObj.path_put('[1][1]', anotherJsonObj);
--输出为{"Level1Key1":[{"Level2Key1":"a","Level2Key2":true},
--{"Level2Key1":"b"}],"Level1Key2":123}
aJsonObj.print;
aJsonObj.path_put('[1][2]["Level2Key2"]', false);
--输出为{"Level1Key1":[{"Level2Key1":"a","Level2Key2":true},
--{"Level2Key1":"b","Level2Key2":false}],"Level1Key2":123}
aJsonObj.print;
aJsonObj.path_remove('["Level1Key1"][2]');
--输出为{"Level1Key1":[{"Level2Key1":"a","Level2Key2":true}],"Level1Key2":123}
aJsonObj.print;
end;
5.11 关于NULL
PLJSON支持JSON名值对的值为null。对于字符串类型(VARCHAR2),与PL/SQL类似,null与空字符串(“”)等价。对于其它值类型,用null表示空值。示例代码如下:
--JSON null值示例
procedure EG_NULL is
--json对象
aJsonObj json;
--一个verchar2
aVerchar2 varchar2(200);
--一个number
aNumber number;
begin
aJsonObj := json('{"key1":null,"key2":""}');
aJsonObj.put('key3', '');
aVerchar2 := null;
aJsonObj.put('key4', aVerchar2);
aNumber := null;
aJsonObj.put('key5', aNumber);
--输出为{"key1":null,"key2":"","key3":"",
--"key4":"","key5":null}
aJsonObj.print;
end;
5.12 值引用 or 对象引用?
将JSON对象加入其它JSON对象或者JSON数组时涉及到值引用和对象引用的问题。即A对象被加入B对象,之后A对象被修改,B对象里包含的A对象会跟着修改吗?答案是否定的。即在JSON对象和JSON数组中引入其它JSON对象或JSON数组时是值引用的。下面是一个测试示例:
--JSON引用示例
procedure EG_Refrence is
--json对象
aJsonObj json;
--json数组
aJsonArray json_list;
begin
aJsonObj := json('{"key1":"1","key2":"2"}');
aJsonArray := json_list();
aJsonArray.append(aJsonObj.to_json_value, 1);
--输出为[{"key1":"1","key2":"2"}]
aJsonArray.print;
aJsonObj.put('key1', 'a');
--输出为[{"key1":"1","key2":"2"}]
aJsonArray.print;
end;
6 对源码的改造
PLJSON对字符进行了一些处理,有时我们可能需要通过修改源码改变默认行为。这些修改主要集中在JSON_PRINTER.escapeString中。修改内容涉及到对特殊符号的转义及对Unicode字符的处理。下面是修改示例:
--20150512屏蔽,避免对双引号添加转义字符
--when chr(34) then buf := '\"';
when chr(47) then
if (escape_solidus) then
buf := '\/';
end if;
when chr(92) then
--20150820修改,避免clob对“\”字符的添加转义字符
--buf := '\\';
null;
else
null;
/*20150314屏蔽,避免将汉字转换为utf8码值
if(ascii(buf) < 32) then
buf := '\u'||replace(substr(to_char(ascii(buf), 'XXXX'),2,4), ' ', '0');
elsif (ascii_output) then
buf := replace(asciistr(buf), '\', '\u');
end if;
*/
(完)