【问题标题】:Split the given column in oracle sql拆分oracle sql中的给定列
【发布时间】:2021-10-20 20:38:20
【问题描述】:

我想拆分下表

column
{"senderName":"John David", "senderCountry":"LKA", "senderAddress":"No 230,ABS,11200}

我想使用 oracle sql 获取下表

senderName senderCountry senderAddress
John David LKA No 230,ABS,11200

我尝试了以下代码

SELECT
regexp_substr(column,'[^:]+', 1, 1) As senderName,
regexp_substr(column,'[^:]+', 1, 2) As senderCountry,
regexp_substr(column,'[^:]+', 1, 3) As senderAddress  
From table

但我得到了下表

senderName senderCountry senderAddress
"senderName" "John David", "senderCountry" "LKA", "senderAddress"

谁能帮帮我?

谢谢

【问题讨论】:

  • 是否总是 JSON 格式?您使用的是 18c 版或更高版本吗?
  • 我的是12C版

标签: sql oracle oracle12c


【解决方案1】:

如果您使用的是 18c 或更高版本,则可以使用 JSON_TABLE

WITH test_data (json) AS
(
  SELECT '{"senderName":"John David", "senderCountry":"LKA", "senderAddress":"No 230,ABS,11200"}' FROM DUAL
)
SELECT jt.*
FROM test_data td,
JSON_TABLE(td.json,
           '$'
           COLUMNS (senderName VARCHAR2(100) PATH '$.senderName',
                    senderCountry VARCHAR2(100) PATH '$.senderCountry',
                    senderAddress VARCHAR2(100) PATH '$.senderAddress')) jt

这会产生以下结果:

SENDERNAME SENDERCOUNTRY SENDERADDRESS
John David LKA No 230,ABS,11200

这是一个显示此工作的 DBFiddle (Link)

【讨论】:

  • ORA-00406: COMPATIBLE parameter needs to be 12.0.0.0.0 or greater 00406. 00000 - "COMPATIBLE parameter needs to %s or greater" *原因:COMPATIBLE初始化参数不够高允许操作。允许该命令将使数据库与当前 COMPATIBLE 参数指定的版本不兼容。 *操作:使用更高的兼容性设置关闭和启动。行错误:24 列:1 @Del
  • 这对我不起作用....我们可以使用 regexp_substr()
  • 对于具有json_* 函数的版本,cross join lateral 更具可读性和明确性。当相关子查询为空时(通过更改为left join lateral)不需要减少数据集时,我可能非常有用
  • @LochanaT 甚至 12.1 版本在一年后就到了End Of Life,所以compatible 参数绝对应该从古代级别值增加。使用自定义正则表达式解析 JSON 很痛苦,容易出错
【解决方案2】:

您应该为此使用JSON_TABLE

如果你不能并且你的 JSON 非常简单(即键只会出现一次并且你没有复杂的解析路径)那么你可以使用正则表达式(但如果你可以使用适当的JSON解析器如JSON_TABLE):

SELECT REPLACE(
         REGEXP_SUBSTR(
           column_name,
           '"senderName":\s*"((\\"|[^"])*)"',
           1,
           1,
           NULL,
           1
         ),
         '\"',
         '"'
       ) AS senderName,
       REPLACE(
         REGEXP_SUBSTR(
           column_name,
           '"senderCountry":\s*"((\\"|[^"])*)"',
           1,
           1,
           NULL,
           1
         ),
         '\"',
         '"'
       ) AS senderCountry,
       REPLACE(
         REGEXP_SUBSTR(
           column_name,
           '"senderAddress":\s*"((\\"|[^"])*)"',
           1,
           1,
           NULL,
           1
         ),
         '\"',
         '"'
       ) AS senderAddress  
FROM   table_name;

其中,对于样本数据:

CREATE TABLE table_name (column_name CHECK (column_name iS JSON)) AS
SELECT '{"senderName":"John David", "senderCountry":"LKA", "senderAddress":"No 230,ABS,11200"}' FROM DUAL UNION ALL
SELECT '{"senderName":"Jane Smith", "senderAddress":"No 42,\"Home\", XYZ, 98765", "senderCountry":"ABC"}' FROM DUAL;

注意:您的 JSON 无效,因为它缺少结束 "

输出:

SENDERNAME SENDERCOUNTRY SENDERADDRESS
John David LKA No 230,ABS,11200
Jane Smith ABC No 42,"Home", XYZ, 98765

db小提琴here

【讨论】:

    【解决方案3】:

    "拆分更容易

    with tab1 as (
    select '{"senderName":"John David", "senderCountry":"LKA", "senderAddress":"No 230,ABS,11200"}' col from dual
    )
    select replace(regexp_substr(t1.col, '"[^"]+"',1, 2), '"', ''),
           replace(regexp_substr(t1.col, '"[^"]+"',1, 4), '"', ''),
           replace(regexp_substr(t1.col, '"[^"]+"',1, 6), '"', '')
      from tab1 t1
    

    【讨论】:

    • JSON 数据不保证顺序一致。它还可以在字符串中包含转义的引号。这将有很多可能出错。 db<>fiddle
    猜你喜欢
    • 1970-01-01
    • 2015-08-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-17
    • 2017-01-12
    • 2014-07-02
    • 1970-01-01
    相关资源
    最近更新 更多