plsql代码无需使用第三方库即可解析JSON

时间:2019-04-16 07:24:15

标签: json oracle plsql

只需使用正则表达式之类的PL / SQL代码就可以解析JSON,以从中获取sentimentconfidence值。

类似于this

[
   {
      "sentiment":"negative",
      "confidence":0.6211975044276729
   },
   {
      "sentiment":"neutral",
      "confidence":0.3510681601407111
   },
   {
      "sentiment":"positive",
      "confidence":0.027734335431616075
   }
]

需要解析JSON之上的内容,以获取其中的sentimentconfidence

2 个答案:

答案 0 :(得分:3)

JSON_TABLE函数从Oracle Database 12c第1版(12.1.0.2)开始可用。

SET NUMWIDTH 20 --Use this if SQL*Plus/ SQL developer truncates digits.

--test data
WITH t ( json_col ) AS ( SELECT '[
   {
      "sentiment":"negative",
      "confidence":0.6211975044276729
   },
   {
      "sentiment":"neutral",
      "confidence":0.3510681601407111
   },
   {
      "sentiment":"positive",
      "confidence":0.027734335431616075
   }
]'
  FROM dual
) --test data ends
SELECT j.*
FROM t
CROSS JOIN
     JSON_TABLE ( json_col,'$[*]'
          COLUMNS (
               sentiment  VARCHAR2(20) PATH '$.sentiment',
               confidence NUMBER       PATH '$.confidence'
          )
     )
j;


SENTIMENT                      CONFIDENCE
-------------------- --------------------
negative                .6211975044276729
neutral                 .3510681601407111
positive              .027734335431616075

答案 1 :(得分:0)

如果您真的不想使用任何内置的JSON函数,并且您的输入不涉及任何嵌套对象,则可以将SQL与递归子查询分解子句一起使用:

Oracle设置

CREATE TABLE test_data ( json ) AS
SELECT '[
   {
      "sentiment":"negative",
      "confidence":0.6211975044276729
   },
   {
      "confidence":0.3510681601407111,
      "sentiment":"neutral"
   },
   {
      "sentiment":"positive",
      "confidence":0.027734335431616075
   }
]' FROM DUAL

查询

WITH rsqfc ( json, obj, lvl, cnt ) AS (
  SELECT json,
         REGEXP_SUBSTR( json, '\{(.*?)\}', 1, 1, 'n' ),
         1,
         REGEXP_COUNT( json, '\{(.*?)\}', 1, 'n' )
  FROM   test_data
  WHERE  REGEXP_COUNT( json, '\{(.*?)\}', 1, 'n' ) > 1
UNION ALL
  SELECT json,
         REGEXP_SUBSTR( json, '\{(.*?)\}', 1, LVL + 1, 'n' ),
         lvl + 1,
         cnt
  FROM   rsqfc
  WHERE  lvl < cnt
)
SELECT REGEXP_SUBSTR( obj, '"sentiment":\s*"(negative|neutral|positive)"', 1, 1, 'n', 1 ) AS sentiment,
       TO_NUMBER( REGEXP_SUBSTR( obj, '"confidence":\s*(\d+(\.\d*)?)', 1, 1, 'n', 1 ) ) AS confidence
FROM   rsqfc

输出

SENTIMENT |          CONFIDENCE
:-------- | ------------------:
negative  |   .6211975044276729
neutral   |   .3510681601407111
positive  | .027734335431616075

PL / SQL

或使用PL / SQL:

DECLARE
  json CLOB := '[
   {
      "sentiment":"negative",
      "confidence":0.6211975044276729
   },
   {
      "confidence":0.3510681601407111,
      "sentiment":"neutral"
   },
   {
      "sentiment":"positive",
      "confidence":0.027734335431616075
   }
]';
  cnt PLS_INTEGER;
  obj VARCHAR2(4000);
  sentiment VARCHAR2(20);
  confidence NUMBER;
BEGIN
  cnt := REGEXP_COUNT( json, '\{(.*?)\}', 1, 'n' );
  FOR i IN 1 .. cnt LOOP
    obj        := REGEXP_SUBSTR( json, '\{(.*?)\}', 1, i, 'n' );
    sentiment  := REGEXP_SUBSTR( obj, '"sentiment":\s*"(negative|neutral|positive)"', 1, 1, 'n', 1 );
    confidence := TO_NUMBER( REGEXP_SUBSTR( obj, '"confidence":\s*(\d+(\.\d*)?)', 1, 1, 'n', 1 ) );
    DBMS_OUTPUT.PUT_LINE( sentiment || ' - ' || confidence );
  END LOOP;
END;
/

输出

dbms_output:
negative - .6211975044276729
neutral - .3510681601407111
positive - .027734335431616075

db <>提琴here