我必须使用SQL Loader for Oracle加载46个包含数据的表。所有数据文件都是CSV。
CSV中的列顺序与表格中的列顺序相匹配。
我需要为每个表创建一个控制文件。
批量生产这些文件的最佳方式是什么?
答案 0 :(得分:1)
我知道这是一个老问题,但它仍然是一个相关的问题。对于未来的搜索者,这里是我添加到我们的实用程序包中的一个过程,它为表生成一个框架控制文件。将表名称传递给它,它会输出一个默认控制文件,您可以根据需要进行调整。您可能需要先进行编辑以满足您的需求。
这样打电话:
set serveroutput on;
exec utils.gen_ctl_file('TABLE_NAME');
程序:
/********************************************************************************************************
Name: GEN_CTL_FILE
Desc: Generates a skeleton control file from a table for loading data via SQL*Loader.
Args: tablename_in IN VARCHAR2, delim_in VARCHAR2 DEFAULT '|'
Returns: None.
Usage: utils.gen_ctl_file('tablename');
Notes: Prints a skeleton control file.
If a template for a fixed-length data file is desired, use 'FIXED' for the delim_in string.
Example usage:
set serveroutput on;
execute utils.gen_ctl_file('tablename');
************************************************************************************************************************/
PROCEDURE GEN_CTL_FILE(tablename_in IN VARCHAR2, delim_in VARCHAR2 DEFAULT '|') IS
ERRNULLTABLENAME CONSTANT NUMBER := -20103; -- User-defined error numbers and messages.
ERRNULLTABLENAMEMSG CONSTANT VARCHAR2(100) := 'A table name is required.';
USAGE CONSTANT VARCHAR2(100) := '* USAGE: UTILS.GEN_CTL_FILE(tablename_in IN VARCHAR2, fieldsep_in VARCHAR2 DEFAULT ''|'')';
v_delim VARCHAR2(20) := NVL(delim_in, '|');
err_nbr NUMBER;
err_msg VARCHAR2(1000);
CURSOR COL_CUR IS
SELECT COLUMN_NAME,
DECODE(COLUMN_ID, 1, ' ', ',') || RPAD(COLUMN_NAME, 32) || case upper(v_delim)
when 'FIXED' then 'POSITION(99:99) '
else NULL
end|| DECODE(DATA_TYPE,
'VARCHAR2', 'CHAR NULLIF(' || COLUMN_NAME || '=BLANKS)',
'CHAR', 'CHAR NULLIF(' || COLUMN_NAME || '=BLANKS)',
'FLOAT', 'DECIMAL EXTERNAL NULLIF(' || COLUMN_NAME || '=BLANKS)',
'NUMBER', DECODE( DATA_PRECISION,
0, 'INTEGER EXTERNAL NULLIF (' || COLUMN_NAME || '=BLANKS)',
DECODE(DATA_SCALE, 0, 'INTEGER EXTERNAL NULLIF (' || COLUMN_NAME || '=BLANKS)', 'DECIMAL EXTERNAL NULLIF (' || COLUMN_NAME || '=BLANKS)')),
'DATE', 'DATE "MM/DD/YYYY" NULLIF (' || COLUMN_NAME || '=BLANKS)',
data_type)
AS COL_DATA
FROM USER_TAB_COLUMNS
WHERE TABLE_NAME = UPPER(tablename_in)
ORDER BY COLUMN_ID;
BEGIN
IF tablename_in IS NULL THEN
RAISE_APPLICATION_ERROR(ERRNULLTABLENAME, ERRNULLTABLENAMEMSG || CHR(10) || USAGE);
END IF;
DBMS_OUTPUT.PUT_LINE('--');
DBMS_OUTPUT.PUT_LINE('-- NOTE - When using DIRECT=TRUE to perform block inserts to a table,');
DBMS_OUTPUT.PUT_LINE('-- the table''s triggers will not be used! Plan accordingly to');
DBMS_OUTPUT.PUT_LINE('-- manually perform the trigger actions after loading, if needed.');
DBMS_OUTPUT.PUT_LINE('--');
DBMS_OUTPUT.PUT_LINE('OPTIONS (DIRECT=TRUE)');
DBMS_OUTPUT.PUT_LINE('UNRECOVERABLE');
DBMS_OUTPUT.PUT_LINE('LOAD DATA');
DBMS_OUTPUT.PUT_LINE('APPEND');
DBMS_OUTPUT.PUT_LINE('INTO TABLE ' || UPPER(tablename_in));
DBMS_OUTPUT.PUT_LINE('EVALUATE CHECK_CONSTRAINTS');
if upper(v_delim) != 'FIXED' then
DBMS_OUTPUT.PUT_LINE('FIELDS TERMINATED BY ''' || v_delim || ''' TRAILING NULLCOLS');
end if;
DBMS_OUTPUT.PUT_LINE('(');
-- The cursor for loop construct implicitly opens and closes the cursor.
FOR COL IN COL_CUR
LOOP
DBMS_OUTPUT.PUT_LINE(COL.COL_DATA);
END LOOP;
DBMS_OUTPUT.PUT_LINE(')' || CHR(10));
EXCEPTION
WHEN OTHERS THEN
err_nbr := SQLCODE;
err_msg := SUBSTR(SQLERRM, 1, 1000);
-- if any error occurs, print the SQLCODE message.
DBMS_OUTPUT.PUT_LINE('ERROR: ' || err_nbr || ' occurred: ' || err_msg);
END; -- GEN_CTL_FILE
答案 1 :(得分:0)
我做过类似的事情(大约120个表,超过1500列)。我使用excel(因为我的工作结果是excel文件)
在Excel宏中,我按照Adam Musch的建议从DB中读取表元,然后填入表格。
我认为这对你也有用。
或者您可以使用熟悉的语言创建工具来执行相同的操作。