由于您指定不想使用任何 JSON 库,如果格式是固定的,您可以将其强制转换为可以解析为 XML 的内容,首先剥离花括号,用等号替换冒号,然后删除每个名称/值对的第一部分的双引号:
select regexp_replace(regexp_replace(value, '(^{|}$)'),
'^"(.*)":(".*")($|,)', '\1=\2', 1, 0, 'm')
from tests_1;
REGEXP_REPLACE(REGEXP_REPLACE(VALUE,'(^{|}$)'),'^"(.*)":(".*")($|,)','\1=\2',1,0
--------------------------------------------------------------------------------
a="01/01/2015"
b="31/12/2015"
c="11111111111"
d="1111111111"
e="1234567890"
您可以将其用作虚拟 XML 节点的属性;将其转换为 XMLType,您可以使用 XMLTable 来提取属性:
select x.a, x.b, x.c, x.d, x.e
from tests_1 t
cross join xmltable('/tmp'
passing xmltype('<tmp ' ||regexp_replace(regexp_replace(value, '(^{|}$)'),
'^"(.*)":(".*")($|,)', '\1=\2', 1, 0, 'm') || ' />')
columns a varchar2(10) path '@a',
b varchar2(10) path '@b',
c number path '@c',
d number path '@d',
e number path '@e'
) x;
A B C D E
---------- ---------- ------------- ------------- -------------
01/01/2015 31/12/2015 11111111111 1111111111 1234567890
然后您可以在插入期间将字符串转换为日期:
insert into test_2 (a, b, c, d, e)
select to_date(x.a, 'DD/MM/YYYY'), to_date(x.b, 'DD/MM/YYYY'), x.c, x.d, x.e
from tests_1 t
cross join xmltable('/tmp'
passing xmltype('<tmp ' || regexp_replace(regexp_replace(value, '(^{|}$)'),
'^"(.*)":(".*")($|,)', '\1=\2', 1, 0, 'm') || ' />')
columns a varchar2(10) path '@a',
b varchar2(10) path '@b',
c number path '@c',
d number path '@d',
e number path '@e'
) x;
select * from test_2;
A B C D E
---------- ---------- ------------- ------------- -------------
2015-01-01 2015-12-31 11111111111 1111111111 1234567890
这将处理一些不存在的名称/值对,如果发生这种情况,您将得到空值。
如果所有对将始终存在,您可以标记字符串并提取相关部分:
select to_date(regexp_substr(value, '[^"]+', 1, 4), 'DD/MM/YYYY') as a,
to_date(regexp_substr(value, '[^"]+', 1, 8), 'DD/MM/YYYY') as b,
to_number(regexp_substr(value, '[^"]+', 1, 12)) as c,
to_number(regexp_substr(value, '[^"]+', 1, 16)) as d,
to_number(regexp_substr(value, '[^"]+', 1, 20)) as e
from tests_1;
A B C D E
---------- ---------- ------------- ------------- -------------
2015-01-01 2015-12-31 11111111111 1111111111 1234567890