Oracle - 派生 table,将值插入新的 table
Oracle - Derived table, Inserting values into a new table
我有一个函数可以读取字段中的逗号分隔值列表。此函数的结果将创建派生的 table.
示例:
派生Table:
现在,我需要将此数据插入 new/existing table。我创建了对象 type/package,它具有派生 table 的所有列,但是,我不确定如何 add/reference 可以将此数据插入到 new/existing table.
return 嵌套 table 的函数可以通过使用 TABLE
函数从 table 函数中选择来转换为常规行和列。 (在最新版本的 Oracle 中,TABLE
运算符是可选的。)
例如:
SQL> create or replace function get_columns return sys.odcivarchar2list is
2 begin
3 return sys.odcivarchar2list('355352', 'Yes');
4 end;
5 /
Function created.
SQL> select column_value from table(get_columns);
COLUMN_VALUE
--------------------------------------------------------------------------------
355352
Yes
现在该函数可以在任何地方使用,例如插入:insert into some_table select column_value from table(get_columns);
如果结果包含多个列,或者您有多个结果集等,您的具体解决方案可能会更复杂。如果您仍然需要帮助,请使用有关函数和类型的更多详细信息编辑您的问题。
编辑: 下面是在列中存储 CSV 值的完整示例,创建一个将 CSV 转换为 VARRAY 的函数,调用该函数进行透视,然后再次进行透视分为多列:
create table table_1
(
request_id number,
service varchar2(100),
method varchar2(100),
request_date date,
process_date date,
te_suid number,
status varchar2(100),
params varchar2(4000)
);
create or replace type params_varray is varray(48) of varchar2(4000);
--Example function that converts comma-separated lists into VARRAYS.
--(Not tested for nulls, consecutive commas, etc.)
create or replace function get_columns(p_params varchar2, p_delimiter varchar2) return params_varray is
v_array params_varray := params_varray();
begin
for i in 1 .. regexp_count(p_params, p_delimiter) + 1 loop
v_array.extend;
v_array(v_array.count) := regexp_substr(p_params, '[^'||p_delimiter||']+', 1, i);
end loop;
return v_array;
end;
/
insert into table_1 values(1,1,1,sysdate,sysdate,1,1,'1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48');
insert into table_1 values(2,2,2,sysdate,sysdate,2,2,'49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96');
--Convert CSV into multiple columns.
--
--Convert rows back into multiple columns.
select request_id, service, method, request_date, process_date, te_suid, status
,max(case when param_index = 1 then param_value else null end) value1
,max(case when param_index = 2 then param_value else null end) value2
,max(case when param_index = 3 then param_value else null end) value3
--Repeat for 4 through 48.
from
(
--Convert CSV to rows.
select request_id, service, method, request_date, process_date, te_suid, status,
row_number() over (partition by table_1.rowid order by rownum) param_index,
column_value param_value
from table_1
cross join get_columns(table_1.params, ',')
)
group by request_id, service, method, request_date, process_date, te_suid, status;
您可以 运行 db<>fiddle 上的示例。
但是如果您在这件事上有任何选择,我强烈建议您对 table 进行非规范化,并且永远不要将分隔值存储在数据库中。
我有一个函数可以读取字段中的逗号分隔值列表。此函数的结果将创建派生的 table.
示例:
派生Table:
现在,我需要将此数据插入 new/existing table。我创建了对象 type/package,它具有派生 table 的所有列,但是,我不确定如何 add/reference 可以将此数据插入到 new/existing table.
return 嵌套 table 的函数可以通过使用 TABLE
函数从 table 函数中选择来转换为常规行和列。 (在最新版本的 Oracle 中,TABLE
运算符是可选的。)
例如:
SQL> create or replace function get_columns return sys.odcivarchar2list is
2 begin
3 return sys.odcivarchar2list('355352', 'Yes');
4 end;
5 /
Function created.
SQL> select column_value from table(get_columns);
COLUMN_VALUE
--------------------------------------------------------------------------------
355352
Yes
现在该函数可以在任何地方使用,例如插入:insert into some_table select column_value from table(get_columns);
如果结果包含多个列,或者您有多个结果集等,您的具体解决方案可能会更复杂。如果您仍然需要帮助,请使用有关函数和类型的更多详细信息编辑您的问题。
编辑: 下面是在列中存储 CSV 值的完整示例,创建一个将 CSV 转换为 VARRAY 的函数,调用该函数进行透视,然后再次进行透视分为多列:
create table table_1
(
request_id number,
service varchar2(100),
method varchar2(100),
request_date date,
process_date date,
te_suid number,
status varchar2(100),
params varchar2(4000)
);
create or replace type params_varray is varray(48) of varchar2(4000);
--Example function that converts comma-separated lists into VARRAYS.
--(Not tested for nulls, consecutive commas, etc.)
create or replace function get_columns(p_params varchar2, p_delimiter varchar2) return params_varray is
v_array params_varray := params_varray();
begin
for i in 1 .. regexp_count(p_params, p_delimiter) + 1 loop
v_array.extend;
v_array(v_array.count) := regexp_substr(p_params, '[^'||p_delimiter||']+', 1, i);
end loop;
return v_array;
end;
/
insert into table_1 values(1,1,1,sysdate,sysdate,1,1,'1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48');
insert into table_1 values(2,2,2,sysdate,sysdate,2,2,'49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96');
--Convert CSV into multiple columns.
--
--Convert rows back into multiple columns.
select request_id, service, method, request_date, process_date, te_suid, status
,max(case when param_index = 1 then param_value else null end) value1
,max(case when param_index = 2 then param_value else null end) value2
,max(case when param_index = 3 then param_value else null end) value3
--Repeat for 4 through 48.
from
(
--Convert CSV to rows.
select request_id, service, method, request_date, process_date, te_suid, status,
row_number() over (partition by table_1.rowid order by rownum) param_index,
column_value param_value
from table_1
cross join get_columns(table_1.params, ',')
)
group by request_id, service, method, request_date, process_date, te_suid, status;
您可以 运行 db<>fiddle 上的示例。
但是如果您在这件事上有任何选择,我强烈建议您对 table 进行非规范化,并且永远不要将分隔值存储在数据库中。