How to get long type value stored under a blob type column using DBMS_LOB in Oracle

问题描述 投票:0回答:1

I have a BLOB column in one of the tables and it basically stores the following format data in BLOB format

[ { 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
来获得后续的偏移值,并读取了查询的全部返回。 But the long data I'm not able to view as the result of my query?
我正在做 - 

To get the offset

utl_raw.cast_to_varchar2

从偏移中获取长度值 -
DBMS_LOB.INSTR(
blob_column,
UTL_RAW.CAST_TO_RAW('INVOICE_ID'),
1,1
)

在这种情况下,有人可以指导我从Blob列中获取Invoice_ID的价值吗?考虑到格式相同,ivoice_id的值每次都会更改?
    

您可以尝试以下内容:
sql oracle-database blob
1个回答
0
投票
UTL_RAW.CAST_TO_VARCHAR2(DBMS_LOB.SUBSTR(blob_column, 100, 91)

使用问题中的函数在斑点中找到键中的键,然后查找值的末尾,它认为它是在下一个闭合支架或逗号之前。然后,它从键的末端到下一个闭合手柄或逗号之前读取斑点的部分,在开始时删除任何
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;
/
,然后返回其找到的文本。

当我运行此脚本(在Oracle 18C XE上)时,我得到以下输出:

=>

您可以通过更改分配给

SQL> @blob_text_find 503457986 PL/SQL procedure successfully completed.
的值来挑选其他值。我已经用其他几个键对其进行了测试,并选择了值。
但是,注意,如果与任何密钥相关的值是可能包含逗号或闭合支撑的字符串,则这将无法可靠。
    

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.