我有一个名为 multi_value 的字段,其中包含:
" 1700,4000,3485,9684,20394,39448"
我只需要将每个值分成一个字段,例如
multi_value1, multi_value2, multi_value3, multi_value4, multi_value5, multi_value6
需要考虑的事项:
有时,它可能只有3个值,也可能是2个值,但通常最多可以有6个值。
这些值目前由逗号分隔,如上所示。
值的大小可以从2个字符一直变化到10个。
如何使用Oracle实现这一目标?
谢谢!
答案 0 :(得分:1)
Oracle安装程序:
CREATE TYPE VARCHAR2_TABLE AS TABLE OF VARCHAR2(4000);
/
CREATE OR REPLACE FUNCTION split_String(
i_str IN VARCHAR2,
i_delim IN VARCHAR2 DEFAULT ','
) RETURN VARCHAR2_TABLE DETERMINISTIC
AS
p_result VARCHAR2_TABLE := VARCHAR2_TABLE();
p_start NUMBER(5) := 1;
p_end NUMBER(5);
c_len CONSTANT NUMBER(5) := LENGTH( i_str );
c_ld CONSTANT NUMBER(5) := LENGTH( i_delim );
BEGIN
IF c_len > 0 THEN
p_end := INSTR( i_str, i_delim, p_start );
WHILE p_end > 0 LOOP
p_result.EXTEND;
p_result( p_result.COUNT ) := SUBSTR( i_str, p_start, p_end - p_start );
p_start := p_end + c_ld;
p_end := INSTR( i_str, i_delim, p_start );
END LOOP;
IF p_start <= c_len + 1 THEN
p_result.EXTEND;
p_result( p_result.COUNT ) := SUBSTR( i_str, p_start, c_len - p_start + 1 );
END IF;
END IF;
RETURN p_result;
END;
/
查询1 :
SELECT split_string( '1700, 4000, 3485, 9684, 20394, 39448' )
FROM DUAL;
<强>输出强>:
MULTI_VALUE_STRING
---------------------------------------------------------------------
TEST.VARCHAR2_TABLE('1700',' 4000',' 3485',' 9684',' 20394',' 39448')
查询2 :
SELECT TO_NUMBER( TRIM( COLUMN_VALUE ) ) AS value
FROM TABLE( split_string( '1700, 4000, 3485, 9684, 20394, 39448' ) );
<强>输出强>:
VALUE
----------
1700
4000
3485
9684
20394
39448
查询3 :
WITH table_name( value ) AS (
SELECT '1700, 4000, 3485, 9684, 20394, 39448' FROM DUAL
)
SELECT TO_NUMBER( REGEXP_SUBSTR( value, '\d+', 1, 1 ) ) AS v1,
TO_NUMBER( REGEXP_SUBSTR( value, '\d+', 1, 2 ) ) AS v2,
TO_NUMBER( REGEXP_SUBSTR( value, '\d+', 1, 3 ) ) AS v3,
TO_NUMBER( REGEXP_SUBSTR( value, '\d+', 1, 4 ) ) AS v4,
TO_NUMBER( REGEXP_SUBSTR( value, '\d+', 1, 5 ) ) AS v5,
TO_NUMBER( REGEXP_SUBSTR( value, '\d+', 1, 6 ) ) AS v6,
TO_NUMBER( REGEXP_SUBSTR( value, '\d+', 1, 7 ) ) AS v7,
TO_NUMBER( REGEXP_SUBSTR( value, '\d+', 1, 8 ) ) AS v8,
TO_NUMBER( REGEXP_SUBSTR( value, '\d+', 1, 9 ) ) AS v9,
TO_NUMBER( REGEXP_SUBSTR( value, '\d+', 1, 10 ) ) AS v10
FROM table_name
<强>输出强>:
V1 V2 V3 V4 V5 V6 V7 V8 V9 V10
---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ----------
1700 4000 3485 9684 20394 39448
答案 1 :(得分:0)
正如我在你对你的问题的评论中提到的,分割字符串并不困难。这是它的完成方式 - 但请阅读我的评论并做出回应。
在下面的查询中,第一行只是设置测试数据;实际查询从第2行开始。
with test_data (input_str) as (select '1700, 4000, 3485, 9684, 20394, 39448' from dual)
select 'multi_value' || level as name,
regexp_substr(input_str, '\s?(\d*)(,|$)', 1, level, null, 1) as value
from test_data
connect by level <= regexp_count(input_str, ',') + 1
and prior sys_guid() is not null;
<强>输出强>:
NAME VALUE
---------------- -------------
multi_value1 1700
multi_value2 4000
multi_value3 3485
multi_value4 9684
multi_value5 20394
multi_value6 39448
或者 - 你的意思是这样的吗?
<强>输出强>:
MULTI_VALUE1 MULTI_VALUE2 MULTI_VALUE3 MULTI_VALUE4 MULTI_VALUE5 MULTI_VALUE6
------------ ------------ ------------ ------------ ------------ ------------
1700 4000 3485 9684 20394 39448
120 300 100000000
查询以实现此结果:
with test_data (input_str) as (
select '1700, 4000, 3485, 9684, 20394, 39448' from dual union all
select '120, 300, 100000000' from dual)
select to_number(regexp_substr(input_str, '\s?(\d*)(,|$)', 1, 1, null, 1)) as multi_value1,
to_number(regexp_substr(input_str, '\s?(\d*)(,|$)', 1, 2, null, 1)) as multi_value2,
to_number(regexp_substr(input_str, '\s?(\d*)(,|$)', 1, 3, null, 1)) as multi_value3,
to_number(regexp_substr(input_str, '\s?(\d*)(,|$)', 1, 4, null, 1)) as multi_value4,
to_number(regexp_substr(input_str, '\s?(\d*)(,|$)', 1, 5, null, 1)) as multi_value5,
to_number(regexp_substr(input_str, '\s?(\d*)(,|$)', 1, 6, null, 1)) as multi_value6
from test_data;