调用Java过程时的Oracle ORA-01722

时间:2018-06-03 08:07:11

标签: java oracle jdbc

我要做的是从控制台获取输入并通过过程调用将它们插入到数据库中。发生的事情是每次我尝试运行它时都会收到错误。

  

ORA-01722:无效的号码   ORA-06512:at" xxxxxxxx.CREATE_APPLICATIONS",第16行   ORA-06512:第1行

这是我尝试运行的程序:

private String insert_application() {
    try {
        Connection conn = cf.getConnection();
        String sql = "{call create_applications (?,?,?,?,?,?,?,?,?,?,?,?)}";

        CallableStatement call = conn.prepareCall(sql);

        call.setString(1, this.getFirst_name());
        call.setString(2, this.getLast_name());
        call.setString(3, this.getAddress());
        call.setString(4, this.getCity());
        call.setString(5, this.getState());
        call.setInt(6, Integer.parseInt(this.getZipcode()));
        call.setString(7, this.getUsername());
        call.setString(8, this.getPassword());
        call.setInt(9, Integer.parseInt(this.getPhone()));
        call.setInt(10, Integer.parseInt(this.getSSN()));
        call.setString(11, this.getStatus());
        call.setString(12, this.getAccount_type());

        call.execute();
    } catch (SQLException e) {
        e.printStackTrace();
        return "Error: Having issues with the database. Please try again later! Inserting error";
    }

    return "File created!";
}

这是存储过程:

CREATE OR REPLACE PROCEDURE create_applications
  ( FIRST_NAME IN BANKING_APPLICATIONS.FIRST_NAME%TYPE,
    LAST_NAME IN BANKING_APPLICATIONS.LAST_NAME%TYPE,
    ADDRESS IN BANKING_APPLICATIONS.ADDRESS%TYPE,
    CITY IN BANKING_APPLICATIONS.CITY%TYPE,
    STATE IN BANKING_APPLICATIONS.STATE%TYPE,
    ZIPCODE IN BANKING_APPLICATIONS.ZIPCODE%TYPE,
    USERNAME IN BANKING_APPLICATIONS.USERNAME%TYPE,
    PASSWORD IN BANKING_APPLICATIONS.PASSWORD%TYPE,
    SSN IN BANKING_APPLICATIONS.SSN%TYPE,
    PHONE IN BANKING_APPLICATIONS.PHONE%TYPE,
    STATUS IN BANKING_APPLICATIONS.STATUS%TYPE,
    ACCOUNT_TYPE IN BANKING_APPLICATIONS.ACCOUNT_TYPE%TYPE)
AS
BEGIN
    INSERT INTO BANKING_APPLICATIONS
    VALUES (APPLICATION_SEQ.NEXTVAL, FIRST_NAME, LAST_NAME, ADDRESS, CITY, 
    STATE, ZIPCODE, USERNAME, PASSWORD, PHONE, SSN, STATUS, 
    CLAIM_NUMBER_SEQ.NEXTVAL, ACCOUNT_TYPE); 
    COMMIT;
END;
/

以下是两个序列:

CREATE SEQUENCE APPLICATION_SEQ START WITH 1;

CREATE OR REPLACE TRIGGER APPLICATION_BIR 
   BEFORE INSERT ON BANKING_APPLICATIONS 
   FOR EACH ROW
BEGIN
   SELECT APPLICATION_SEQ.NEXTVAL
   INTO   :new.APPLICATION_ID
   FROM   dual;
END;
/

CREATE SEQUENCE CLAIM_NUMBER_SEQ START WITH 1;

CREATE OR REPLACE TRIGGER CLAIM_NUMBER_BIR  
   BEFORE INSERT ON BANKING_APPLICATIONS 
   FOR EACH ROW
BEGIN
   SELECT CLAIM_NUMBER_SEQ.NEXTVAL
   INTO   :new.CLAIM_NUMBER
   FROM   dual;
END;
/

以下是表格定义:

CREATE TABLE "BANKING_APPLICATIONS" 
("APPLICATION_ID" NUMBER(15,0) NOT NULL ENABLE, 
 "FIRST_NAME" VARCHAR2(15 BYTE) NOT NULL ENABLE, 
 "LAST_NAME" VARCHAR2(25 BYTE) NOT NULL ENABLE, 
 "ADDRESS" VARCHAR2(50 BYTE) NOT NULL ENABLE, 
 "CITY" VARCHAR2(25 BYTE) NOT NULL ENABLE, 
 "STATE" VARCHAR2(30 BYTE) NOT NULL ENABLE, 
 "ZIPCODE" NUMBER(5,0) NOT NULL ENABLE, 
 "USERNAME" VARCHAR2(15 BYTE) NOT NULL ENABLE, 
 "PASSWORD" VARCHAR2(15 BYTE) NOT NULL ENABLE, 
 "PHONE" NUMBER(10,0) NOT NULL ENABLE, 
 "SSN" NUMBER(9,0) NOT NULL ENABLE, 
 "CLAIM_NUMBER" NUMBER(15,0) NOT NULL ENABLE, 
 "STATUS" VARCHAR2(20 BYTE) NOT NULL ENABLE, 
 "ACCOUNT_TYPE" VARCHAR2(20 BYTE) NOT NULL ENABLE
);

2 个答案:

答案 0 :(得分:1)

INSERT语句的VALUES部分如下所示:

SSN, 
STATUS, 
CLAIM_NUMBER_SEQ.NEXTVAL,
ACCOUNT_TYPE
);

您尚未指定目标投影,因此VALUES按列位置顺序映射到表格。如果我们查看您的表格,我们可以看到您的表格如下:

"SSN" NUMBER(9,0) NOT NULL ENABLE, 
"CLAIM_NUMBER" NUMBER(15,0) NOT NULL ENABLE, 
"STATUS" VARCHAR2(20 BYTE) NOT NULL ENABLE, 
"ACCOUNT_TYPE" VARCHAR2(20 BYTE) NOT NULL ENABLE

因此,您的INSERT会尝试将status参数应用于claim number列,反之亦然。问题是status是字符串,claim number是数字,这就是ORA-01722: invalid number的原因。

  

如何指定目标投影?

通过在VALUES子句之前列出目标列:

INSERT INTO BANKING_APPLICATIONS(
  APPLICATION_ID, 
  FIRST_NAME, 
  LAST_NAME, 
  ADDRESS, 
  CITY, 
  STATE,
  ZIPCODE, 
  USERNAME, 
  PASSWORD, 
  PHONE, 
  SSN, 
  STATUS, 
  CLAIM_NUMBER, 
  ACCOUNT_TYPE)
VALUES (
  APPLICATION_SEQ.NEXTVAL,
  FIRST_NAME,
  LAST_NAME,
  ADDRESS,
  CITY, 
  STATE, 
  ZIPCODE, 
  USERNAME, 
  PASSWORD, 
  PHONE, 
  SSN, 
  STATUS, 
  CLAIM_NUMBER_SEQ.NEXTVAL, 
  ACCOUNT_TYPE)

此处目标项目与VALUES子句中属性的顺序匹配,而不是与表位置匹配。

顺便说一句,你会注意到我列出了每行一个元素的语句。这使得查看错误变得简单。整洁的布局不仅仅是迂腐。可读性是一项功能,具有该功能的代码更容易诊断(并且可以说最初不容易出现错误)。

答案 1 :(得分:1)

这是您的CREATE TABLE声明,略有缩写:

CREATE TABLE "JONATHANWISNIEWSKI"."BANKING_APPLICATIONS" 
(
  ...
"SSN" NUMBER(9,0) NOT NULL ENABLE, 
"CLAIM_NUMBER" NUMBER(15,0) NOT NULL ENABLE, 
"STATUS" VARCHAR2(20 BYTE) NOT NULL ENABLE, 
"ACCOUNT_TYPE" VARCHAR2(20 BYTE) NOT NULL ENABLE
) ...

这是您的INSERT声明,有点缩写:

INSERT INTO BANKING_APPLICATIONS
 VALUES (..., SSN, STATUS, 
 CLAIM_NUMBER_SEQ.NEXTVAL, ACCOUNT_TYPE); 

看到问题?

您的STATUSCLAIM_NUMBER列方式错误。 CLAIM_NUMBER是数字,但STATUS不是,因此您尝试将非数字状态值放入数字声明编号列时会出错。

要解决此问题,请在INSERT声明中指定要插入的列的列表:

INSERT INTO BANKING_APPLICATIONS 
  (APPLICATION_ID, FIRST_NAME, LAST_NAME, ... )
VALUES (APPLICATION_SEQ.NEXTVAL, FIRST_NAME, LAST_NAME, ...)

这样,表中列的排序并不重要。只要列名称的顺序和INSERT语句中值的顺序匹配,您就可以了。