i在其中一个表中有一个斑点列,它基本上以blob格式存储以下格式数据
[
{ ANYTIME_INDICATOR => 0,
CUSTOMER_NODE_ID => 40324148,
ENTITY_ID => 40065721,
ENTITY_TYPE => 37,
IGNORE_NTRE => 0,
IGNORE_ZERO_CHARGE => 0,
INVOICE_ID => 503457986,
SUMMARY_INDICATOR => 1
},
{ }
]
现在,我正在尝试从中获取503457986值,到目前为止,我已经使用了DBMS_LOB.INSTR
,它使我的位置为
INVOICE_ID
的位置,最重要的是使用
DBMS_LOB.SUBSTR
来获得后续的偏移值,并读了查询的整个返回。但是,我无法查看的长度数据是我查询的结果吗? 我正在做类似的事情。要偏移
utl_raw.cast_to_varchar2
从偏移中获得长的价值:
DBMS_LOB.INSTR(
blob_column,
UTL_RAW.CAST_TO_RAW('INVOICE_ID'),
1,1
)
在这种情况下,有人可以指导我从Blob列中获取
UTL_RAW.CAST_TO_VARCHAR2(DBMS_LOB.SUBSTR(blob_column, 100, 91)
的价值吗?考虑到格式相同,并且每次都会改变的价值?
您可以尝试以下内容:
INVOICE_ID
使用问题中的函数在斑点中找到键中的键,然后查找值的末尾,它认为它是在下一个闭合支架或逗号之前。然后,它从键的末端到下一个闭合手柄或逗号之前读取斑点的部分,在开始时删除任何INVOICE_ID
SET SERVEROUTPUT ON
DECLARE
l_blob BLOB;
l_key VARCHAR2(100 CHAR) := 'INVOICE_ID';
l_start_pos INTEGER;
l_comma_pos INTEGER;
l_brace_pos INTEGER;
l_end_pos INTEGER;
l_text VARCHAR2(4000 CHAR);
BEGIN
l_blob := UTL_RAW.CAST_TO_RAW('[ { ANYTIME_INDICATOR => 0, CUSTOMER_NODE_ID => 40324148, ENTITY_ID => 40065721, ENTITY_TYPE => 37, IGNORE_NTRE => 0, IGNORE_ZERO_CHARGE => 0, INVOICE_ID => 503457986, SUMMARY_INDICATOR => 1 }, { } ]');
l_start_pos := DBMS_LOB.INSTR(l_blob, UTL_RAW.CAST_TO_RAW(l_key));
IF l_start_pos = 0 THEN
raise_application_error(-20001, 'Did not find key ''' || l_key || '''.');
END IF;
-- Move l_start_pos past the name of the key.
l_start_pos := l_start_pos + LENGTHB(l_key);
-- Look for the end of the value. Find the next comma or closing brace after the key,
-- and take the least of their positions if both are found.
l_comma_pos := DBMS_LOB.INSTR(l_blob, UTL_RAW.CAST_TO_RAW(','), l_start_pos);
l_brace_pos := DBMS_LOB.INSTR(l_blob, UTL_RAW.CAST_TO_RAW('}'), l_start_pos);
IF l_comma_pos = 0 AND l_brace_pos = 0 THEN
raise_application_error(-20001, 'Did not find terminating comma or closing brace');
ELSIF l_comma_pos = 0 THEN
l_end_pos := l_brace_pos;
ELSIF l_brace_pos = 0 THEN
l_end_pos := l_comma_pos;
ELSE
l_end_pos := LEAST(l_comma_pos, l_brace_pos);
END IF;
l_text := TRIM(UTL_RAW.CAST_TO_VARCHAR2(DBMS_LOB.SUBSTR(l_blob, l_end_pos - l_start_pos, l_start_pos)));
IF l_text LIKE '=>%' THEN
l_text := TRIM(SUBSTR(l_text, 3));
END IF;
dbms_output.put_line(l_text);
END;
/
您可以通过更改分配给=>
的值来挑选其他值。我已经用其他几个键对其进行了测试,并选择了值。 但是,注意,如果与任何密钥相关的值是可能包含逗号或闭合支撑的字符串,则这将无法可靠。