Oracle中的Clob数据归档替换问题

时间:2019-05-27 21:05:24

标签: sql json oracle

我的输入字符串

Employee[10|||Aryan|||CA|||USA|||URBAN|||IT 
ENGINEER+++20|||Arjun|||FA|||USA|||RULER|||DEVELOPER]

我的输出应该是

[
 {Employee Name : Aryan,Employee ID:10,Emploee Role:IT ENGINEER}
   ,
 {Employee Name : Arjun,Employee ID:20,Emploee Role:DEVELOPER}
]

我尝试了多种无法正常工作的情况

2 个答案:

答案 0 :(得分:0)

下面写的是假设您正在运行Oracle版本12c之前的版本,该版本添加了对JSON的支持。

通过简单的替换,您将无法做到这一点。

它必须是一个函数/过程。为了让您有所了解,请参见下面的匿名块,它只会输出字符串,如果需要的话,您需要对其进行修改以更新您的字段。

我在您的输入字符串中添加了第三行,作为第一行,最后一行,中间的行都需要以不同的方式处理,因此需要三条记录来进行完全测试。

注释CHR(13)=回车,CHR(10)=换行,CHR(9)=制表符。这些只是尝试并与您的格式匹配,如果不需要确切的格式,可以将其排除。

declare

v_input clob default 'Employee[10|||Aryan|||CA|||USA|||URBAN|||IT ENGINEER+++20|||Arjun|||FA|||USA|||RULER|||DEVELOPER+++30|||BOB|||FA|||USA|||RULER|||DEVELOPER]';
v_line  varchar2(32000) default null;
v_output clob default null;
v_exit boolean default false;

begin

loop -- loop until we have no more employees to process
  if instr(v_input, '+++') > 0 then -- not the last line
    if v_output is null then -- first line
      v_line  := substr(v_input, instr(v_input, 'Employee[') + 9, instr(v_input, '+++') -10); -- get a single employee row (first line)
    else
      v_line  := substr(v_input, 1, instr(v_input, '+++') -1); -- get a single employee row (not fist line)
    end if;
    v_input := substr(v_input, instr(v_input, '+++') + 3); -- trim off the stuff we have already processed.
  else
    v_line := substr(v_input, 1, length(v_line) - 2); -- get a single employee row (last line)
    v_exit := true;
  end if;
  if v_output is null then -- first line
    v_output := '['||chr(13)||chr(10)||chr(9)||'{'; -- start string
  else 
    v_output := v_output || chr(9) || '{'; -- add the opening brace
  end if;
  v_output := v_output ||'Employee Name : ' || substr(v_line, instr(v_line, '|||', 1, 1) + 3, instr(v_line, '|||', 1, 2)-6) || ','; -- add name
  v_output := v_output ||'Employee ID:' || substr(v_line, 1, 2) || ','; -- add ID
  v_output := v_output ||'Employee Role:' || substr(v_line, instr(v_line, '|||', 1, 5) + 3) || '}'; -- add role
  if v_exit then -- we are on last line so close it all out and exit loop
    v_output := v_output || chr(13) || chr(10) || ']';
    exit;
  else 
    v_output := v_output || CHR(13) || CHR(10) || CHR(9) || CHR(9) || ',' || chr(13) || chr(10); -- not last line so format ready to start new line
  end if;
end loop;
dbms_output.put_line(v_output);
end;
/

此输出为

[
    {Employee Name : Aryan,Employee ID:10,Employee Role:IT ENGINEER}
        ,
    {Employee Name : Arjun,Employee ID:20,Employee Role:DEVELOPER}
        ,
    {Employee Name : BOB,Employee ID:30,Employee Role:DEVELOPER}
]

答案 1 :(得分:0)

以下查询将适用于任意数量的条目。

SELECT
    '['
    || CHR(10)
    || RTRIM(XMLAGG(XMLELEMENT(E, INDVDL_ENTITY, CHR(10)
                                                 || ','
                                                 || CHR(10)).EXTRACT('//text()')
        ORDER BY
            L
    ).GETCLOBVAL(), CHR(10)
                    || ','
                    || CHR(10))
    || CHR(10)
    || ']'
FROM
    (
        SELECT
            '{Employee Name : '
            || REGEXP_SUBSTR(INDVDL_ENTITY, '[^(/|/|/|)]+', 1, 2)
            || ',Employee ID:'
            || REGEXP_SUBSTR(INDVDL_ENTITY, '[^(/|/|/|)]+', 1, 1)
            || ',Emploee Role:'
            || REGEXP_SUBSTR(INDVDL_ENTITY, '[^(/|/|/|)]+', 1, 6)
            || '}' AS INDVDL_ENTITY,
            L   AS L
        FROM
            (
                SELECT
                    REGEXP_SUBSTR(VAL, '[^\+\+\+]+', 1, LEVEL) AS INDVDL_ENTITY,
                    LEVEL   AS L
                FROM
                    (
                        SELECT
                            TRIM(TRAILING ']' FROM REGEXP_SUBSTR('Employee[10|||Aryan|||CA|||USA|||URBAN|||IT ENGINEER+++20|||Arjun|||FA|||USA|||RULER|||DEVELOPER]'
                            , '[^\[]+', 1, 2)) AS VAL
                        FROM
                            DUAL
                    )
                CONNECT BY
                    ( REGEXP_COUNT(VAL, '\+\+\+') + 1 ) >= LEVEL
            )
    );

查询的输出:

[
{Employee Name : Aryan,Employee ID:10,Emploee Role:IT ENGINEER}
,
{Employee Name : Arjun,Employee ID:20,Emploee Role:DEVELOPER}
]

随意在输入字符串中添加任意数量的条目。 (我也测试了五个条目,它工作正常):):)

根据Shaun的建议,使用CHR函数创建自己的格式。

谢谢。