【问题标题】:Java: Calling a stored procedure in an oracle databaseJava:在 oracle 数据库中调用存储过程
【发布时间】:2025-12-30 18:35:06
【问题描述】:

编辑:虽然这个问题中的一些答案可能会帮助其他人解决不同的问题,但该解决方案实际上与数据库连接上的自动提交功能的一些错误有关!执行查询后强制提交会导致数据库反映更改,因此下面显示的代码是调用此类存储过程的正确方法

我正在尝试在 oracle 数据库中调用一个简单的存储过程。

过程如下:

procedure clear_orderProcDtlByOrdId(p_order_id in order_header.order_id%type,
                                    p_transaction_id in sl_order_processing_dtl.transaction_id%type DEFAULT NULL,
                                    p_item_action_id in sl_order_processing_dtl.item_action_id%type DEFAULT NULL )
...

我遇到问题的 java 代码如下所示

    try 
    {
        CallableStatement storedProc = conn.prepareCall("{call PKG_PI_FRAUD.clear_orderProcDtlByOrdId(?)}");
        storedProc.setString(1, orderID);
        storedProc.execute();
    } 
    catch (SQLException e) 
    {
        e.printStackTrace();
    }

我没有收到任何错误,但是没有反映数据库更改。当我在 SQL Developer 中运行该过程时,我看到了结果。我认为这可能是因为提交问题,但我建立的连接处于自动提交模式。

任何帮助将不胜感激!

【问题讨论】:

  • 在 DB 中 orderID 设置为 VARCHAR 吗?
  • @PremGenError orderID 是数据库中的 VARCHAR2
  • 尝试在参数周围加上引号,然后在第 2 行:storedProc.setString("1", "orderID");
  • @twoleggedhorse 这会导致PLS-00707: unsupported construct or internal error [2603]
  • @user2076524 如果从参数名称中删除引号,您是否仍然收到错误? storedProc.setString("1", orderID);

标签: java sql oracle stored-procedures jdbc


【解决方案1】:

虽然这个问题中的一些答案可能会帮助其他人解决不同的问题,但该解决方案实际上与数据库连接上的自动提交功能的一些错误有关!执行查询后强制提交会导致数据库反映更改,因此问题中显示的代码是调用此类存储过程的正确方法!

【讨论】:

    【解决方案2】:

    为了能够在Oracle数据库中捕获过程的返回,试试这个。

    public static void main(String[] args) {
    
            try {
    
                Class.forName("oracle.jdbc.driver.OracleDriver");
                String url = "jdbc:oracle:thin:@localhost:1521:xe";
                Connection con = DriverManager.getConnection(url, db_user, password);
                System.out.println("Connected to database");
    
                SimpleDateFormat simpleDateFormat = new SimpleDateFormat("dd/MM/yyyy");
                Date now = new java.sql.Date(simpleDateFormat.parse("12/02/2001").getTime());
    
                String command = "{call SALDOS(?,?)}";
                CallableStatement cstmt = con.prepareCall(command);
                cstmt.registerOutParameter(2, Types.DECIMAL);
    
                cstmt.setDate(1, now);
                cstmt.execute();
                Double str = cstmt.getDouble(2);
    
                cstmt.close();
                System.out.println("Retorno: " + str);
    
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    

    如果您以这种方式使用不同的 Returns Map SimpleJdbcCall:

        SimpleJdbcCall call = Util.getSimpleJdbcCallInstance();
        call.setProcedureName("PROCED_CONDOMINIAL");
        call.declareParameters(
                new SqlParameter("CONDOMINIO", Types.VARCHAR),
                new SqlParameter("BLOCO", Types.VARCHAR),,
                new SqlOutParameter("P_NUMERO", Types.NUMERIC),
                new SqlOutParameter("P_LOG", Types.VARCHAR));
    
        Map<String, Object> parametros = new HashMap<String, Object>();
        parametros.put("CONDOMINIO_IC", descricaoCondominio);
        parametros.put("BLOCO_IC", imovelCondominial.getBloco());
    
        Map<String, Object> out = call.execute(parametros);
        BigDecimal chave = (BigDecimal) out.get("P_NUMERO");
        imovelCondominial.setId(chave.longValue());
    

    以及过程的声明

    create or replace PROCEDURE         PROCED_CONDOMINIAL
                   (CONDOMINIO            VARCHAR2,
                    BLOCO                 VARCHAR2,
                    NUMERO                OUT NUMBER,
                    LOG                   OUT VARCHAR2)      -- PARAMETROS DE SAIDAS (OUT).-
    

    在这里工作。看看这个博客。

    http://jameajudo.blogspot.com.br/2009/03/call-procedure-oracle-with-java-and.html

    在 Oracle 10xe 和 11xe 上测试。

    【讨论】: