【问题标题】:Missing IN or OUT parameter at index::索引处缺少 IN 或 OUT 参数::
【发布时间】:2022-01-21 10:22:46
【问题描述】:

这是我的 java 代码

String insertSql = "CALL INSERT_EXAMPLE(?, ?, ?)";
CallableStatement stmt = conn.prepareCall(insertSql);
this.stmt.setObject(1, nameText);
this.stmt.setObject(2, phoneText);
this.stmt.registerOutParameter(3, Types.INTEGER);
boolean results = stmt.execute();
Integer t_id = null;
if(results) {
    ResultSet rs = stmt.getResultSet();
    if(rs.next()) {
         t_id = stmt.getInt("id");
    }
}

这是我的程序

CREATE OR REPLACE PROCEDURE INSERT_EXAMPLE(
    name                              IN                        VARCHAR2,
    phone                             IN                        VARCHAR2, 
    OUT_RESULT_CODE                   OUT                       INTEGER
    )
AS 
    id       NUMBER;
BEGIN
  INSERT INTO USERS (
        T_NAME,
        T_PHONE
    ) VALUES (
        name,
        phone,
        ) RETURNING id INTO T_ID;
    COMMIT;
    OUT_RESULT_CODE := id;
END INSERT_EXAMPLE;

这是我的 sql

创建表 "DB_NAME"."USERS"(
“T_ID”NUMBER,
“T_NAME”VARCHAR2(400 字节),
"T_PHONE" VARCHAR2(400 字节),
约束“USERS_PK”主键(“T_ID”)
使用 INDEX PCTFREE 10 INITRANS 2 MAXTRANS 255 计算统计
存储(初始 65536 下一个 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 个 FREELISTS 1 个 FREELIST 组 1
BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
表空间“用户”启用
) 立即创建细分
PCTFREE 10 PCTUSED 40 INITRANS 1 MAXTRANS 255
NOCOMPRESS NOLOGGING
存储(初始 65536 下一个 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645
PCTINCREASE 0 个 FREELISTS 1 个 FREELIST 组 1
BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)
表空间“表空间 1”;
创建或替换 NONEDITIONABLE TRIGGER “DB_NAME”。“USERS_ON_INSERT”
在插入用户之前
每行开始
SELECT USERS_SEQ.NEXTVAL
INTO :new.T_ID FROM dual; 结尾; / ALTER TRIGGER "DB_NAME"."USERS_ON_INSERT" ENABLE;

错误:

java.sql.SQLException: 索引处缺少 IN 或 OUT 参数:: 1

这一行:boolean results = stmt.execute();

【问题讨论】:

  • 为什么是ResultSet rs = stmt.getResultSet();?该过程不生成结果集。
  • 您确定这是您调用的程序吗?它不应该编译 - RETURNING id INTO T_ID 应该是 RETURNING T_ID INTO id,当然;甚至跳过变量并使用RETURNING T_ID INTO OUT_RESULT_CODE?它有一个杂散的逗号。 (db<>fiddle)
  • 我以为在使用 RETURNING @MT0 时会得到它
  • this.stmtstmt 在您的代码中不是同一个对象
  • 不好意思,我写的时候改了。正确的拼写表示同样的错误。 @AlexPoole

标签: java oracle stored-procedures


【解决方案1】:

您的程序有几个错误:

  1. phone 后面的逗号在 VALUES 的末尾。
  2. idt_idRETURNING 子句中是错误的。

您可以将代码简化为:

CREATE OR REPLACE PROCEDURE INSERT_EXAMPLE(
    name            IN  USERS.T_NAME%TYPE,
    phone           IN  USERS.T_PHONE%TYPE,
    OUT_RESULT_CODE OUT USERS.T_ID%TYPE
)
AS 
BEGIN
  INSERT INTO USERS (
    T_NAME,
    T_PHONE
  ) VALUES (
    name,
    phone
  ) RETURNING t_id INTO OUT_RESULT_CODE;
  
  COMMIT;
END INSERT_EXAMPLE;
/

此外,您不应该在过程中使用 COMMIT,因为它允许您将多个过程调用链接到同一个事务中,然后将 COMMIT/ROLLBACK 链接在一起。如果您在过程中COMMIT 并且出现后续错误,那么您不能ROLLBACK 开始事务。相反,您应该将事务设置为在关闭时自动提交或在关闭连接之前显式提交。

db小提琴here


我目前无法测试 Java 代码,但我认为应该是:

String insertSql = "CALL INSERT_EXAMPLE(?, ?, ?)";
CallableStatement stmt = conn.prepareCall(insertSql);
stmt.setObject(1, nameText);
stmt.setObject(2, phoneText);
stmt.registerOutParameter(3, Types.INTEGER);
boolean results = stmt.execute();
Integer t_id = null;
if(results) {
  t_id = stmt.getInt(3);
}

顺便说一句,您已经使用"T_PHONE" VARCHAR2(400 BYTE) 定义了表;你真的希望一个 400 字节的电话​​号码字符串吗?

【讨论】:

  • 犯了同样的错误:(((这部分boolean results = stmt.execute();
猜你喜欢
  • 2014-04-26
  • 1970-01-01
  • 2012-08-05
  • 2022-01-20
  • 2014-03-19
  • 1970-01-01
  • 2022-08-22
  • 2018-01-31
  • 1970-01-01
相关资源
最近更新 更多