我遇到了一个需要解决的问题,我不知道该怎么做。
我正在使用Oracle 10g数据库导入五种类型的文件。此文件为CSV格式。 我知道在文件1中,字段名称位于第1个位置,在第2个文件中,我知道字段名称位于4位......依此类推。基本上相同的字段在所有文件中但在不同的位置。 我将文件导入数据库中的表(让我们称之为x_table),其中包含ipl_c1,ipl_c2,ipl_c3等字段...
我在数据库表中的字段位置信息中得到了这个信息(我们称之为x_param_table)。 现在我将这些数据迁移到不同的表中(每种文件类型一个表)。 我的问题是:我必须制定程序来处理每个文件?这可以动态做吗?
我正在做的是,我创建了一个基于命运表的类型,如下所示:
i_table destiny_table%rowtype;
i_source_table x_table%rowtype;
接下来我迭代记录为(i_source_table
)的表,但每个文件使用不同的过程。
如果我在文件1中,那么我
i_table(i).name := i_source_table(idx).ipl_c1
如果我在文件2中,那么我
i_table(i).name := i_source_table(idx).ipl_c4
因为我在数据库(x_param_table)中获得了该字段的位置而无法执行类似
的操作i_table(i).name := i_source_table(idx).ipl_c||x_param_table.position
也许我看错的方式......但我相信可以在一个程序中做到这一点。
有人可以帮忙吗?
答案 0 :(得分:1)
您可以考虑将源表转换为XMLTYPE,以便您能够动态获取特定列的值。通过这种方式,您只需要定义很少的过程来完成要求。
例如:
DECLARE
SRC XMLTYPE;
BEGIN
SRC := dbms_xmlgen.getxmltype('SELECT * FROM ALL_OBJECTS WHERE ROWNUM < 5');
FOR R IN (SELECT COLUMN_VALUE
FROM TABLE(XMLSEQUENCE(EXTRACT(SRC, '/ROWSET/ROW')))) LOOP
DBMS_OUTPUT.PUT_LINE('Objet name: ' || R.COLUMN_VALUE.EXTRACT('/ROW/OBJECT_NAME/text()')
.GETSTRINGVAL);
DBMS_OUTPUT.PUT_LINE('The fifth column value is: ' || R.COLUMN_VALUE.EXTRACT('/ROW/*[5]/text()')
.GETSTRINGVAL);
END LOOP;
END;
输出结果为:
Objet name: ICOL$
The fifth column value is: TABLE
Objet name: TAB$
The fifth column value is: TABLE
Objet name: I_USER2
The fifth column value is: INDEX
Objet name: I_CCOL2
The fifth column value is: INDEX
有几种方法可以将select语句转换为xml - xmltype(cursor(...)),dbms_xmlquery等。
您甚至可以使用dbms_xmlsave和dbms_xmlstore而不是insert或update语句更新dest表。
答案 1 :(得分:0)
您可以为每个导入文件创建一个视图,例如
create or replace view file_1 as
select ipl_c1, ipl_c3, ipl_c2, ipl_c5, ipl_c4
from x_table;
create or replace view file_2 as
select ipl_c5, ipl_c2, ipl_c1, ipl_c3, ipl_c4
from x_table;
create or replace view file_3 as
select ipl_c3, ipl_c1, ipl_c2, ipl_c4, ipl_c5
from x_table;
etc.
然后您可以在这些视图中进行简单的插入。每个文件都使用关联的视图:
For file type #1
insert into file_1 values (col_1, col_2, col_3, col_4 ,col_5);
For file type #2
insert into file_2 values (col_1, col_2, col_3, col_4 ,col_5);
etc.
然后你不必在你的专栏周围洗牌。