【问题标题】:Oracle Split Delimited String Into RowsOracle 将分隔字符串拆分为行
【发布时间】:2020-10-30 00:43:12
【问题描述】:

这里很难。我们正在运行 11g,所以我们现在不支持 JSON。我的目标是将分隔符上的 JSON 字符串拆分为行,然后过滤每一行。这可能吗?这是一个例子:

{
   "section_1": {
      "section_publish": true,
       "section_body": "<p style=\"text-align: justify;\">
    },
   "section_2": {
      "section_publish": false,
       "section_body": "<p style=\"text-align: justify;\">
    },
   "section_3": {
      "section_publish": true,
       "section_body": "<p style=\"text-align: justify;\">
    }
}

所以,基本上我希望在 } 上拆分这些部分,然后,一旦它们在“section_publish”上的“行”过滤器中:true,然后过滤那些。

JSON 字符串保存在一个表中,因此这将成为 SELECT 语句的一部分:

SELECT id, name.....
FROM json_table
WHERE {json result from above} LIKE '%string to compare%';

这有意义吗?这可以在 SQL 中完成吗?

【问题讨论】:

    标签: json string oracle split


    【解决方案1】:

    以下示例可能不适用于您可能拥有的所有 JSON 变体,但此查询确实适用于提供的示例 JSON。

    查询

    WITH
        json_test (json_val) AS (SELECT EMPTY_CLOB () || '{
      "section_1": {
        "section_publish": true,
        "section_body": "<p style=\"text-align: justify;\">"
      },
      "section_2": {
        "section_publish": false,
        "section_body": "<p style=\"text-align: justify;\">"
      },
      "section_3": {
        "section_publish": true,
        "section_body": "<p style=\"text-align: justify;\">"
      }
    }' FROM DUAL),
        json_split
        AS
            (    SELECT TRIM ('"' FROM REGEXP_SUBSTR (json_val,
                                                      '".*"',
                                                      1,
                                                      1 + ((LEVEL - 1) * 3)))    AS section,
                        TRIM (TRIM (',' FROM SUBSTR (REGEXP_SUBSTR (json_val,
                                                                    '"section_publish".*',
                                                                    1,
                                                                    LEVEL),
                                                     19)))                       AS section_publish,
                        REPLACE (
                            TRIM ('"' FROM TRIM (TRIM (',' FROM SUBSTR (REGEXP_SUBSTR (json_val,
                                                                                       '"section_body".*',
                                                                                       1,
                                                                                       LEVEL),
                                                                        16)))),
                            '\"',
                            '"')                                                 AS section_body
                   FROM json_test
             CONNECT BY LEVEL < REGEXP_COUNT (json_val, '{'))
    SELECT TO_CHAR (section)             AS section,
           TO_CHAR (section_publish)     AS section_publish,
           TO_CHAR (section_body)        AS section_body
      FROM json_split
     WHERE TO_CHAR (section_publish) = 'true';
    

    结果

         SECTION    SECTION_PUBLISH                        SECTION_BODY
    ____________ __________________ ___________________________________
    section_1    true               <p style="text-align: justify;">
    section_3    true               <p style="text-align: justify;">
    

    【讨论】:

    • 这很好用。谢谢。我有 2 个问题:我从表中选择的实际列是 CLOB,并且将 > 4000 字节。如果我更改查询:SELECT json_content FROM messages WHERE article_id = 297727 然后我得到:ORA-00932:不一致的数据类型:预期 - 得到 CLOB。有什么方法可以查询 CLOB 列吗? -- 非常感谢!
    • @LandonStatis,我更新了查询以显示如何使用逻辑,因为您的 JSON 是 CLOB
    • 谢谢,但它给了我一个不同的错误:ORA-01482:不支持的字符集
    • 如果我改成这样: WITH json_test (json_val) AS (SELECT EMPTY_CLOB () || json_content FROM message_lobs WHERE article_id = 297727),然后我得到这个:ORA-22835: CLOB 的缓冲区太小到 CHAR 或 BLOB 到 RAW 的转换(实际:18485,最大值:4000)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-12-12
    • 2016-04-18
    • 2012-08-09
    • 1970-01-01
    相关资源
    最近更新 更多