【问题标题】:Loading CSV file data into a Table Variable (Index-by table) in Oracle将 CSV 文件数据加载到 Oracle 中的表变量(索引表)中
【发布时间】:2017-02-26 16:42:40
【问题描述】:

我的要求是我需要读取 CSV 文件数据并使用数据库中的一个现有表对其进行查询以更新一些记录。我认为一种方法是创建一个新表(temp)并将 CSV 文件加载到该表中并使用现有表进行查询,但我发现我没有创建新表或目录的权限(对于外部表接近)。

然后我想通过表变量来执行此操作,但我不知道如何将数据加载到表变量中。我写了以下查询,但它说

'无效的表名'

DECLARE
  TYPE t IS TABLE OF VARCHAR2(15);
  UPDATEPARTYID t;
BEGIN
  SELECT *
    BULK COLLECT INTO UPDATEPARTYID
    FROM 'C:\Test\PartyID.csv';
END;

我以前在 Sql Server 上工作,所以对 Oracle 不太满意。我正在使用 Sql Developer 和 Oracle11g,.csv 文件中有数百万条记录。任何帮助,将不胜感激。

更新:

输入文件的结构:

OldID,NewID
015110044200015,099724838000015
069167641100015,099724838000015
016093943300015,099728485000015
033264160300015,099728485000015
035968914300015,099728485000015
087580324300015,099728485000015

现有表中有一个名为 PartyID (Varchar2(15)) 的列,我需要使用与输入文件的 OldID 匹配的新派对 ID 更新这些 ID。

新目标表的结构为:

  From Party ID (Varchar2 15)
  To Party ID     (Varchar2 15)
  Created Date  Sysdate
  Updated Date  Sysdate 
  Status              Char (1) S: Success, F: Failure 
  No.Of Tries      Integer(3) Default value 0

如果尝试次数超过 3 次,则将其标记为失败。

【问题讨论】:

  • 我建议使用最多 3 或 4 行的 csv 文件开始。
  • 如果您可以让某人为您创建一个临时表来存储数据,您最好的选择可能是使用 Oracle 的 SQL*Loader 实用程序来批量加载数据,之后您可以更新目标表.
  • 如果表中不存在记录,是插入还是不执行任何更新?无论哪种方式,@MickMnemonic 的建议都是可行的。如果你不能这样做,Oracle 确实有一些不错的 Oracle 批量更新功能。不过,首先了解您的约束条件会有所帮助。
  • @MickMnemonic 是的,Mick 我已经要求管理员创建一个临时表,以便我可以使用 SQL*Loader。谢谢。
  • @Hambone 在这种情况下,我不执行任何更新。感谢您的评论。我正在按照米克的建议去做。

标签: c# sql oracle oracle11g table-variable


【解决方案1】:

要将大量数据从文本文件加载到 Oracle,SQL*Loader utility 是一个不错的选择。该软件包含在 Oracle 客户端安装中(例如,您可以下载 here)。

设置

假设您要将数据导入具有结构的目标表 (target_table)

CREATE TABLE target_table (
     from_party VARCHAR2(15) NOT NULL,
     to_party   VARCHAR2(15) NOT NULL,
     created    DATE,
     updated    DATE,
     status     CHAR(1),
     tries      NUMBER(1)
)

并使用具有以下结构的两列源数据文件(在路径 /path/to/party_import.csv 中)

OldID,NewID
015110044200015,099724838000015
069167641100015,099724838000015
016093943300015,099728485000015
033264160300015,099728485000015
035968914300015,099728485000015
087580324300015,099728485000015

您可以使用带有以下内容的control file

OPTIONS (SKIP=1)
LOAD DATA
INFILE '/path/to/party_import.csv'
BADFILE 'import.bad'
INSERT
INTO TABLE target_table
fields terminated by ","  TRAILING NULLCOLS
(
  from_party,
  to_party,
  created sysdate
)

运行 SQL*Loader

要运行 SQL*Loader,您可以调用以下命令:

sqlldr username/pw@db_connection control=/path/to/control_file.ctl

这假设事先已完成以下设置:

  • Oracle 客户端(包括 SQL*Loader)已安装
  • sqlldr.exe 在路径中,或者使用了可执行文件的绝对路径
  • 您已通过 Oracle 的网络配置助手或手动提供 tnsnames.ora 文件并设置 TNS_ADMIN 环境变量(例如 here)配置了数据库连接 (db_connection)

默认情况下,仅在处理完整个文件后才提交事务。如果你想提交例如每 1000 行,您可以使用 ROWS 选项来执行此操作:

sqlldr username/pw@db_connection control=/path/to/control_file.ctl ROWS=1000

【讨论】:

  • 非常感谢 Mick 的详细回答。我想问一件事,有没有办法在控制文件中编写 Status 和 Tries 列的逻辑?如何跟踪这些列并插入表格,如果您有想法,请告诉我。 :)
  • 应该如何填充这些值?我不太明白应该如何使用这些列。
【解决方案2】:

仅使用 C# 的另一种方式:

使用 SQLBulkCopy 类将批量数据从 CSV 文件插入数据库表

https://www.c-sharpcorner.com/article/insert-bulk-data-from-csv-file-to-database-table-using-sqlbu/

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-11-19
    • 2017-12-07
    • 2013-07-29
    相关资源
    最近更新 更多