在 PL/SQL 中读取大型 csv 文件
Reading large csv files in PL/SQL
Whosebug 上的第一个问题。
所以,我正在处理一个新项目,我需要从 PL/SQL 读取类似 CSV 的大型文件并将数据插入 table。这些文件每个大约有 400k 行,我不确定执行此操作的最佳方法。我在 PL/SQL 方面的专业知识对于这项任务来说有点短 :D
我见过有人使用 UTL_FILE.FOPEN。有没有一种方法可以分块读取大文件或使用更合适的工具?关于这个问题,我找不到任何有用的 post。
提前致谢!
您可以使用内联外部 table 或 APEX_DATA_PARSER 加载数据文件。这些技术通常比创建外部 table 更好,因为您不必管理那么多的架构对象。这些技术通常比使用像 sqlldr 这样的工具更好,因为这样你的程序就不会依赖于特定的外部程序、shell 脚本或操作系统。
内联外部Table
找到存放文件的目录:
select directory_path from all_directories where directory_name = 'DATA_PUMP_DIR';
在该目录中创建文件 test.csv:
Name,Salary
Alice,100
Bob,200
读取该文件而不创建外部文件table:
select *
from external
(
(
name varchar2(100),
salary number
)
default directory data_pump_dir
access parameters
(
records delimited by newline
skip 1
fields terminated by ','
)
location ('test.csv')
);
结果:
NAME SALARY
----- ------
Alice 100
Bob 200
APEX_DATA_PARSER
如果您的数据库上安装了 APEX,APEX_DATA_PARSER
包是查询文件的便捷方式。尽管此技术确实需要安装一个 PL/SQL 对象,该对象会将文件加载到 blob 中。有关函数 FILE_TO_BLOB
.
背后的代码,请参阅 this Oracle-Base article
select col001 name, col002 salary
from table
(
apex_data_parser.parse
(
p_content => file_to_blob('DATA_PUMP_DIR', 'test.csv'),
p_file_name => 'test.csv'
)
)
SQL 或 PL/SQL?
虽然您要求 PL/SQL 解决方案,但上述解决方案大多只是 SQL。但如果您甚至可以避免创建 PL/SQL 个对象,那也是一件好事。
如果您要在 PL/SQL 中使用此代码,将这些 select 语句放在这样的循环中是微不足道的:
begin
for lines in
(
select *
from external
(
(
name varchar2(100),
salary number
)
default directory data_pump_dir
access parameters
(
records delimited by newline
skip 1
fields terminated by ','
)
location ('test.csv')
)
) loop
--Do something with the results here.
dbms_output.put_line('Name: '||lines.name||',Salary: '||lines.salary);
end loop;
end;
/
Whosebug 上的第一个问题。
所以,我正在处理一个新项目,我需要从 PL/SQL 读取类似 CSV 的大型文件并将数据插入 table。这些文件每个大约有 400k 行,我不确定执行此操作的最佳方法。我在 PL/SQL 方面的专业知识对于这项任务来说有点短 :D
我见过有人使用 UTL_FILE.FOPEN。有没有一种方法可以分块读取大文件或使用更合适的工具?关于这个问题,我找不到任何有用的 post。
提前致谢!
您可以使用内联外部 table 或 APEX_DATA_PARSER 加载数据文件。这些技术通常比创建外部 table 更好,因为您不必管理那么多的架构对象。这些技术通常比使用像 sqlldr 这样的工具更好,因为这样你的程序就不会依赖于特定的外部程序、shell 脚本或操作系统。
内联外部Table
找到存放文件的目录:
select directory_path from all_directories where directory_name = 'DATA_PUMP_DIR';
在该目录中创建文件 test.csv:
Name,Salary
Alice,100
Bob,200
读取该文件而不创建外部文件table:
select *
from external
(
(
name varchar2(100),
salary number
)
default directory data_pump_dir
access parameters
(
records delimited by newline
skip 1
fields terminated by ','
)
location ('test.csv')
);
结果:
NAME SALARY
----- ------
Alice 100
Bob 200
APEX_DATA_PARSER
如果您的数据库上安装了 APEX,APEX_DATA_PARSER
包是查询文件的便捷方式。尽管此技术确实需要安装一个 PL/SQL 对象,该对象会将文件加载到 blob 中。有关函数 FILE_TO_BLOB
.
select col001 name, col002 salary
from table
(
apex_data_parser.parse
(
p_content => file_to_blob('DATA_PUMP_DIR', 'test.csv'),
p_file_name => 'test.csv'
)
)
SQL 或 PL/SQL?
虽然您要求 PL/SQL 解决方案,但上述解决方案大多只是 SQL。但如果您甚至可以避免创建 PL/SQL 个对象,那也是一件好事。
如果您要在 PL/SQL 中使用此代码,将这些 select 语句放在这样的循环中是微不足道的:
begin
for lines in
(
select *
from external
(
(
name varchar2(100),
salary number
)
default directory data_pump_dir
access parameters
(
records delimited by newline
skip 1
fields terminated by ','
)
location ('test.csv')
)
) loop
--Do something with the results here.
dbms_output.put_line('Name: '||lines.name||',Salary: '||lines.salary);
end loop;
end;
/