java程序中调用java存储过程

Posted

技术标签:

【中文标题】java程序中调用java存储过程【英文标题】:Java stored procedure calling in java program 【发布时间】:2013-12-13 09:02:13 【问题描述】:

我应该做的是创建一个 Java 存储过程,然后从 Java 程序中调用它。

我在执行 JAVA 程序时遇到问题 - 带有 1 个参数的 JDBCPiemers(下)(我需要取出字符串 Nosaukums)。错误:“列名无效”。

在 ORACLE 中调用过程可以正常工作。

这是我在数据库中加载的存储过程。

import java.sql.*;
import java.io.*;

public class BeerBeer 

  public static void getBreweryInfo (int Raz_ID) 
    throws SQLException 
     String sql = 
      "SELECT Nosaukums FROM Alus_razotaji WHERE ID = ?";//vaicajums
    try  Connection conn = DriverManager.getConnection("jdbc:default:connection:"); // Izveidojam savienojumu ar datubāzi
      PreparedStatement apstmt = conn.prepareStatement(sql);
      apstmt.setInt(1, Raz_ID); 
      ResultSet rset = apstmt.executeQuery();// SQL vaicājuma izpildīšana

      rset.close();
      apstmt.close(); //Savienojuma aizvēršana
       
    catch (SQLException e) System.err.println(e.getMessage()); //Kļūdu izvadīsana
      
  

我用 oracle 创建了以下包。

CREATE OR REPLACE PACKAGE BeerBeer AS
PROCEDURE getBreweryInfo(Raz_ID number);
END BeerBeer;

CREATE OR REPLACE PACKAGE BODY BeerBeer AS
PROCEDURE getBreweryInfo(Raz_ID number) AS Language Java
NAME 'BeerBeer.getBreweryInfo(int)';
END BeerBeer;

这是我的 Java 程序,我在其中调用了该过程。但是我无法让它工作。我收到错误:“列索引无效”

package client;

import java.sql.*;

public class JDBCPiemers 
    // Norādam URL draiverim un datu bāzei
    static final String JDBC_DRIVER = "oracle.jdbc.OracleDriver";
    static final String DB_URL = "jdbc:oracle:thin:@localhost:1521:ORCL";
    // Izveidojam norādi uz datu bāzes lietotājvārdu un paroli
    static final String USER = "SYSTEM";
    static final String PASS = "asdasd";
    private String sql;

    public static void main(String[] args) throws ClassNotFoundException, SQLException 
        Connection conn = null;
        CallableStatement stmt = null;
        try 
            //Reģistrējam JDBC draiveri
            Class.forName("oracle.jdbc.driver.OracleDriver");
            System.out.println("Izveidojam savienojumu ar datubazi ...");
            conn = DriverManager.getConnection(DB_URL, USER, PASS);
            // Vaicājuma izveide
            System.out.println("Komandas veidosana...");
            String SQL = "CALL BeerBeer.getBreweryInfo (?)";
            stmt = conn.prepareCall(SQL);
            int Raz_ID = 4;
            stmt.setInt(1, Raz_ID);
            stmt.registerOutParameter(2, java.sql.Types.VARCHAR);
            System.out.println("Izpildam JAVA glabajamo proceduru ...");
            // Vaicājuma izpilde
            stmt.execute();
            //Izgustam Alus_razotaja nosaukumu ar getXXX metodi.
            String Razotajs = stmt.getString(2);
            System.out.println("Izvadam rezultatus ...");
            System.out.println("Identifikatoram NR. " +Raz_ID + " atbilst Alus_Razotajs ar nosaukumu  '" + Razotajs + "'" );            
            stmt.close();
            conn.close(); 
            catch(SQLException se) 
                //Kludu apstrade JDBC
                se.printStackTrace(); 
            catch(Exception e) 
                //Kludu apstrade klasei Class.forName
                e.printStackTrace(); 
            finally 
                // Bloks, lai aizvērtu resursus
                try if(stmt!=null)
                stmt.close(); 
            catch(SQLException se2)  
                try if(conn!=null)
                conn.close(); 
                catch(SQLException se) se.printStackTrace(); 
                //finally bloka beigas
             // try 
            System.out.println("Darbu beidzam."); 

【问题讨论】:

注意。它的拼写不是“java”或“JAVA”而是“Java”。 @peter.petrov 该标签的存在,有 4 个关注者,表明并非如此。 当外部程序可以直接通过 JDBC 执行查询时,拥有一个仅执行 select 并从外部 Java 程序调用它的 Java 存储过程有什么意义?无论如何,尽管有“存储过程”名称,Java 方法也可以是一个函数——您已经在尝试return 一个值,这应该是一个线索。它应该是一个带有一个参数的函数,int,它返回一个String 是学校作业,需要使用JAVA存储过程。 @AlexPoole 我已经使用 1 个参数更新了代码。但是,我现在遇到问题要让它与我的程序一起使用。 【参考方案1】:

要返回一个值,你需要它是一个函数,而不是一个过程:

  public static String getBreweryInfo (int Raz_ID) 
  throws SQLException 
   
    String sql = 
      "SELECT Nosaukums FROM Alus_razotaji WHERE ID = ?";//vaicajums
    try 
      Connection conn = DriverManager.getConnection("jdbc:default:connection:");
      PreparedStatement apstmt = conn.prepareStatement(sql);
      apstmt.setInt(1, Raz_ID); 
      ResultSet rset = apstmt.executeQuery();// SQL vaicājuma izpildīšana

      if (rset.next()) 
          return rset.getString(1);
       
    
    catch (SQLException e) 
      System.err.println(e.getMessage()); //Kļūdu izvadīsana
     
    finally 
      rset.close();
      apstmt.close(); //Savienojuma aizvēršana
     
  

那么你的包裹就变成了:

CREATE OR REPLACE PACKAGE BODY BeerBeer AS
  FUNCTION getBreweryInfo(Raz_ID number) RETURN varchar2 AS Language Java
  NAME 'BeerBeer.getBreweryInfo(int) return java.lang.String';
END BeerBeer;

你这样称呼它:

        String SQL = "CALL ? = BeerBeer.getBreweryInfo (?)";
        stmt = conn.prepareCall(SQL);
        int Raz_ID = 4;
        stmt.registerOutParameter(1, java.sql.Types.VARCHAR);
        stmt.setInt(2, Raz_ID);
        System.out.println("Izpildam JAVA glabajamo proceduru ...");
        // Vaicājuma izpilde
        stmt.execute();
        //Izgustam Alus_razotaja nosaukumu ar getXXX metodi.
        String Razotajs = stmt.getString(1);

请注意,out 参数现在是索引 1,因为它是函数的返回值,因此您传入的值现在是索引 2。当然,所有未测试...

【讨论】:

【参考方案2】:
            CallableStatement stmt = null;
            String sql = "call movecartrecord(?)";
            try 
            
                stmt = conn.prepareCall(sql);
                stmt.setInt(1, order_id); //you can pass argument if procedure accepts
                stmt.execute();
                stmt.close();

                String name = stmt.getString(1);
                System.out.println("Name : " + name);
             
            catch (SQLException e)
                           
                e.printStackTrace();
            

这里的movecartrecord()是一个存储过程名,conn是一个连接对象。

这里 order_id 作为参数传递。 如果您的存储过程没有任何参数,则只需保留该行代码。

希望它能对您有所帮助。

这里有一个很棒的code,告诉你如何执行它。

【讨论】:

java.sql.SQLException:列索引无效。我确信返回 String Razotajs 有一些东西,因为我已将过程从 2 更改为 1 参数。但是,我不知道如何解决它。 1 个参数 - Raz_ID,我需要使用 JAVA 程序取出 String Razotajs。 尝试删除行stmt.registerOutParameter(2, java.sql.Types.VARCHAR);,因为您传递了 2 个参数。看***.com/questions/19236673/… 是的,但是如何在我的 JAVA 程序中输出字符串 razotajs 呢? 在我的回答中,我添加了一个带有链接的完整示例,您可以从那里获得问题的解决方案。

以上是关于java程序中调用java存储过程的主要内容,如果未能解决你的问题,请参考以下文章

mysql创建 存储过程 并通过java程序调用该存储过程

在 Java 中调用 Oracle 存储过程时如何避免核心转储

我们应该删除存储过程并从Java程序运行数据库调用

如何从 Java 调用 MSSQL 加密的存储过程?

Java中是如何调用存储过程的?

从 JDBC、Java 调用 Sqlserver 存储过程