【问题标题】:Oracle select JSON column as key / value table [duplicate]Oracle 选择 JSON 列作为键/值表 [重复]
【发布时间】:2021-12-19 17:37:09
【问题描述】:

在 Oracle 12c 中,有一列包含这种格式的 JSON 数据:

{
  "user_name": "Dave",
  "phone_number": "13326415",
  "married": false,
  "age": 18
}

我怎样才能以这种格式选择它:

key                val
--------------     ----------
"user_name"        "Dave"
"phone_number"     "13326415"
"married"          "false"
"age"              "18"

【问题讨论】:

  • 仅使用 SQL,您无法获取 JSON 键作为值。您需要知道键并使用JSON_TABLE 之类的东西来获取每个键的值。使用 JSON_OBJECT_T 类型的 GET_KEYS 函数可以使用 PL/SQL 获取您要查找的内容
  • 只需对为您的previous question 提供的答案应用一些操作,例如this one由于问题被标记为重复,我无法回答)跨度>

标签: json oracle select oracle12c


【解决方案1】:

如评论中所述,仅使用 SQL 无法获取 JSON 对象的键。使用 PL/SQL,您可以创建一个流水线函数来获取您需要的信息。下面是一个非常简单的流水线函数,它将获取 JSON 对象的键并打印每个键的类型,以及键名和值。

首先,您需要创建函数将使用的类型

CREATE OR REPLACE TYPE key_value_table_rec FORCE AS OBJECT
(
    TYPE VARCHAR2 (100),
    key VARCHAR2 (200),
    VALUE VARCHAR2 (200)
);
/

CREATE OR REPLACE TYPE key_value_table_t AS TABLE OF key_value_table_rec;
/

接下来,创建流水线函数,该函数将以上面定义的类型的格式返回信息。

CREATE OR REPLACE FUNCTION get_key_value_table (p_json CLOB)
    RETURN key_value_table_t
    PIPELINED
AS
    l_json           json_object_t;
    l_json_keys      json_key_list;
    l_json_element   json_element_t;
BEGIN
    l_json := json_object_t (p_json);
    l_json_keys := l_json.get_keys;

    FOR i IN 1 .. l_json_keys.COUNT
    LOOP
        l_json_element := l_json.get (l_json_keys (i));
        PIPE ROW (key_value_table_rec (
                      CASE
                          WHEN l_json_element.is_null THEN 'null'
                          WHEN l_json_element.is_boolean THEN 'boolean'
                          WHEN l_json_element.is_number THEN 'number'
                          WHEN l_json_element.is_timestamp THEN 'timestamp'
                          WHEN l_json_element.is_date THEN 'date'
                          WHEN l_json_element.is_string THEN 'string'
                          WHEN l_json_element.is_object THEN 'object'
                          WHEN l_json_element.is_array THEN 'array'
                          ELSE 'unknown'
                      END,
                      l_json_keys (i),
                      l_json.get_string (l_json_keys (i))));
    END LOOP;

    RETURN;
EXCEPTION
    WHEN OTHERS
    THEN
        CASE SQLCODE
            WHEN -40834
            THEN
                --JSON format is not valid
                NULL;
            ELSE
                RAISE;
        END CASE;
END;
/

最后,您可以从 SELECT 语句中调用流水线函数

SELECT * FROM TABLE (get_key_value_table (p_json => '{
  "user_name": "Dave",
  "phone_number": "13326415",
  "married": false,
  "age": 18
}'));

      TYPE             KEY       VALUE
__________ _______________ ___________
string     user_name       Dave
string     phone_number    13326415
boolean    married         false
number     age             18

如果您的 JSON 值存储在表的列中,您可以使用 CROSS JOIN 查看键/值

WITH
    sample_table (id, json_col)
    AS
        (SELECT 1, '{"key1":"val1","key_obj":{"nested_key":"nested_val"},"key_bool":false}'
           FROM DUAL
         UNION ALL
         SELECT 2, '{"key3":3.14,"key_arr":[1,2,3]}' FROM DUAL)
SELECT t.id, j.*
  FROM sample_table t CROSS JOIN TABLE (get_key_value_table (p_json => t.json_col)) j;

   ID       TYPE         KEY    VALUE
_____ __________ ___________ ________
    1 string     key1        val1
    1 object     key_obj
    1 boolean    key_bool    false
    2 number     key3        3.14
    2 array      key_arr

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-10-13
    • 2020-10-24
    • 2018-10-21
    • 2019-09-16
    • 1970-01-01
    • 1970-01-01
    • 2021-11-01
    • 2013-11-28
    相关资源
    最近更新 更多