1

我有一个 java 应用程序,它使用 Oracle SQLLDR实用程序将 CSV 文件数据上传到 oracle 数据库。

有时,SQLLDR实用程序不提供返回/响应代码,而我们可以看到索引在表中被禁用(这确保调用 SQLLDR 实用程序),而且我在服务器中使用TOP命令来查找是否有任何 SQLLDR进程正在运行,但没有这样的进程。

此外,DBA 确认,数据库上没有与 SQLLDR 操作相关的活动会话。

在 oracle 表级别有什么需要检查的吗?请让我知道前进的方向。

4

1 回答 1

4

SQL

 connect scott/tiger;
 create table employee
(
  id integer,
  name varchar2(10),
  dept varchar2(15),
  salary integer,
  hiredon date
)

控制文件

load data
 infile '/home/db1212/x.txt'
 into table employee
 fields terminated by ","
 ( id, name, dept, salary )

x.txt

200,Jason,Technology,5500
300,Mayla,Technology,7000
400,Nisha,Marketing,9500
500,Randy,Technology,6000
501,Ritu,Accounting,5400

执行

$ sqlldr scott/tiger control=/home/db1212/x.ctl

返回

SQL*Loader: Release 12.1.0.2.0 - Production on Sat Oct 17 21:23:47 2020

Copyright (c) 1982, 2014, Oracle and/or its affiliates.  All rights reserved.

Path used:      Conventional
Commit point reached - logical record count 5

Table EMPLOYEE:
  5 Rows successfully loaded.

Check the log file:
  x.log
for more information about the load.

第二次执行产生错误

$ sqlldr scott/tiger control=/home/db1212/x.ctl

返回

SQL*Loader: Release 12.1.0.2.0 - Production on Sat Oct 17 21:25:39 2020

Copyright (c) 1982, 2014, Oracle and/or its affiliates.  All rights reserved.

Path used:      Conventional
SQL*Loader-601: For INSERT option, table must be empty.  Error on table EMPLOYEE

在 SQL*Plus 中截断表

truncate table employee;

从内部使用以下 Java 类

import java.io.BufferedReader;
import java.io.InputStreamReader;

public class t1 {

    public static void main(String[] args) {

        t1 obj = new t1();

        String output = obj.executeCommand();

        System.out.println(output);

    }

    private String executeCommand() {

        StringBuffer output = new StringBuffer();

        try {

            Process p = Runtime.getRuntime().exec(new String[]{"/bin/sh", "-c", "sqlldr scott/tiger control=/home/db1212/x.ctl"});
            p.waitFor();
            BufferedReader reader
                    = new BufferedReader(new InputStreamReader(p.getInputStream()));

            String line = "";
            System.out.println("Return code:"+p.exitValue()+"\n"); 
            while ((line = reader.readLine()) != null) {
                output.append(line + "\n");
            }

        } catch (Exception e) {
            e.printStackTrace();
        }

        return output.toString();

    }

}

构建并运行 t1.java

$ javac t1.java 
$ java t1

返回

Return code:0


SQL*Loader: Release 12.1.0.2.0 - Production on Sat Oct 17 21:30:31 2020

Copyright (c) 1982, 2014, Oracle and/or its affiliates.  All rights reserved.

Path used:      Conventional
Commit point reached - logical record count 5

Table EMPLOYEE:
5 Rows successfully loaded.

Check the log file:
x.log
for more information about the load.

第二次执行以模仿错误

$ java t1

返回

Return code:1


SQL*Loader: Release 12.1.0.2.0 - Production on Sat Oct 17 21:30:39 2020

Copyright (c) 1982, 2014, Oracle and/or its affiliates.  All rights reserved.

Path used:      Conventional

再次截断表

truncate table employee;

并更改输入文件 x.txt

200,Jason,Technology,5500
300,Mayla,Technology,7000
400,Nisha,MarketingAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA,9500
500,Randy,Technology,6000
A501,Ritu,Accounting,5400 

给予执行

$ java t1

以下输出

Return code:2


SQL*Loader: Release 12.1.0.2.0 - Production on Sat Oct 17 21:47:05 2020

Copyright (c) 1982, 2014, Oracle and/or its affiliates.  All rights reserved.

Path used:      Conventional
Commit point reached - logical record count 5

Table EMPLOYEE:
  3 Rows successfully loaded.

Check the log file:
  x.log
for more information about the load.

这表示:

所以万一

  • 成功执行 EX_SUCC = 0
  • 一般 SQL加载程序错误,例如“SQL Loader-601:对于 INSERT 选项,表必须为空。表 EMPLOYEE 上的错误”即执行不成功或参数给出 EX_FAIL = 1(Unix,Windows 返回 3)
  • 成功执行/加载,但出现 SQL 错误,例如“ORA-12899: value too large for column "SCOTT"."EMPLOYEE"."DEPT" (actual: 44, maximum: 15)" 返回 EX_WARN = 2

不幸的是,文档状态

SQL Loader 返回除零以外的任何退出代码,您应该查阅系统日志文件和 SQL Loader 日志文件以获取更详细的诊断信息。

这意味着没有其他方法可以直接将错误作为标准错误、管道等获取,如果 EX_FAIL 或 EX_WARN,您必须验证写入的日志文件。

于 2020-10-17T19:57:08.957 回答