oracle 外部表:如何确保我不加载相同的文件/数据

soat7uwm  于 2023-03-29  发布在  Oracle
关注(0)|答案(3)|浏览(176)

我想使用一个外部表来加载一个csv文件,因为它非常方便,但问题是我如何确保我不会连续加载同一个文件两次?我无法验证加载的数据,因为它可以是与以前相同的信息;例如,我需要找到一种方法来确保用户不会加载与2小时前相同的文件。我考虑过每次都用不同的名称上传文件,并发出alter table命令来更改外部表定义中的文件名称,但这听起来有点冒险。我还考虑过用序列标记文件中的每一行以帮助区分文件,但我怀疑客户端是否会接受它,因为他们需要手动这样做(文件是从某个地方导出的)。
有没有更好的方法来确保我不会在外部表中加载相同的文件,除了更改文件的名称并在表上执行alter?
谢谢你

yquaqz18

yquaqz181#

我只能想到这样一个解决方案:
1.在数据文件名中编码时间戳(如:YYYYMMDDHHMISS-file.csv),其中YYYYMMDDHHMISS是时间戳。
1.创建一个包含字段timestamp的表(如上所述)。

  • 创建一个shell脚本,该脚本:
  • 从数据文件名中提取时间戳。
  • 以timestamp作为参数调用sqlscript,如果该时间戳不存在,则返回0,如果时间戳已经存在,则返回〈〉0,在这种情况下,退出脚本并返回错误:文件:YYYYMMDDHHMISS-file.csv已加载。
  • 将YYYYMMDDDHHMISS文件.csv复制到输入文件. csv。
  • 运行sql加载器脚本,该脚本加载input-file.csv文件
  • 当成功时:运行具有参数timestamp的第二SQL脚本,其将记录插入数据库中以指示文件已加载,并将原始文件移动到备份文件夹。
  • 故障时:报告加载脚本失败。
v9tzhpje

v9tzhpje2#

当你把数据从external table带到你的数据库你可以使用MERGE命令代替insert .它让你不用担心重复的数据
关于The Oracle Merge Command的博客
此外,我们可以将整个转换过程打包到这个Oracle MERGE命令中,引用一个命令中的外部表和表函数作为MERGED Oracle数据的源。

alter session enable parallel dml;
merge /*+ parallel(contract_dim,10) append */
    into contract_dim d
    using TABLE(trx.go(
        CURSOR(select /*+ parallel(contracts_file,10) full (contracts_file) */ *
            from contracts_file ))) f
    on  d.contract_id = f.contract_id 
    when matched then
        update set desc              = f.desc,
                   init_val_loc_curr = f.init_val_loc_curr,
                   init_val_adj_amt  = f.init_val_adj_amt
    when not matched then
        insert values ( f.contract_id,
                        f.desc,
                        f.init_val_loc_curr,
                        f.init_val_adj_amt);

这样,我们就有了复杂的ETL功能,所有这些功能都包含在单个Oracle MERGE语句中。没有单独的SQL*Loader阶段,没有staging表,所有这些功能都通过管道并行加载

1rhkuytd

1rhkuytd3#

由于直接使用csv(来自test.csv)表(test.tbl)不是最佳选择,因此我从它创建了一个进程表(test_process.tbl),并且日常作业检查数据,如果它在进程表中(使用minus语法),并且在检查之后,我将文件移动到具有当前日期的/processed文件夹(/processed/test_2023_03_27.csv)。
我使用了一个过程,但是对于从csv创建表,必须使用'execute immediate',否则它将无效。

相关问题