无法通过存储过程检索选择的值

3
我正在尝试查找一条记录。它让我选择使用存储过程在我的数据库中查找现有记录。当我尝试搜索现有数据时,它没有给我想要的值。当我点击搜索按钮时,它没有将值打印到文本框中。 代码
private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {

  String searchSection = Section_SearchSection_Textfield.getText();
  String searchSection_Name = Section_SectionName_TextField.getText();
  int sectionID = 0;

  if (searchSection.isEmpty())
    {
        JOptionPane.showMessageDialog(null, "Please fill up this fields");
    }
  else 
        try (Connection myConn = DBUtil.connect())
        {   
            try (CallableStatement myFirstCs = myConn.prepareCall("{call getSECTION_NAME(?,?)}"))
            {
                myFirstCs.setInt(1, sectionID);// I set the ID for Primary Key
                myFirstCs.registerOutParameter(2, Types.VARCHAR);
                myFirstCs.setString(2, searchSection_Name);


                boolean hasresults = myFirstCs.execute();

            if (hasresults)
            {
            try (ResultSet myRs = myFirstCs.getResultSet())
            {
                int resultsCounter = 0;
                while (myRs.next())
                {
                    sectionID = myRs.getInt("SECTION_ID");
                    String sectionName = myRs.getString(2);
                    Section_SectionName_TextField.setText(sectionName);//Set the value of text
                    Section_SectionName_TextField.setEnabled(true);//Set to enable

                    resultsCounter++;

                }//end of while
               }//end of if
               }//end of resultset
            }//end of callablestatement
        }//end of connection
        catch (SQLException e) 
        {
            DBUtil.processException(e);
        }
}

存储过程
CREATE PROCEDURE getSECTION_NAME(IN ID INT, OUT NAME VARCHAR(50))
SELECT * FROM allsections_list WHERE SECTION_ID = ID AND SECTION_NAME = NAME

表格

CREATE TABLE
(
SECTION_ID INT PRIMARY KEY AUTO_INCREMENT,
SECTION_NAME VARCHAR(50) NOT NULL
)

任何帮助都将不胜感激!谢谢!更新!根据我所读的,存储过程可以返回结果集。我想检索OUT参数的值。
private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {                                         
    String searchSection = Section_SearchSection_Textfield.getText();
    String searchSection_Name = Section_SectionName_TextField.getText();

    if (searchSection.isEmpty())
    {
        JOptionPane.showMessageDialog(null, "Please fill up this fields");
    }
    else 
        try (Connection myConn = DBUtil.connect();
             CallableStatement myFirstCs = myConn.prepareCall("{call getSECTION_NAME(?,?)}"))
        {

             myFirstCs.setInt(1, sectionID);// I set the ID for Primary Key
             myFirstCs.registerOutParameter(2, Types.VARCHAR);

            boolean hasresults = myFirstCs.execute();

        if (hasresults)
        {
        try (ResultSet myRs = myFirstCs.getResultSet())
        {
            while (myRs.next())
            {
                sectionID = myRs.getInt("SECTION_ID");

                System.out.print(sectionID);
            }//end of while

        }//end of resultset
        }//end of if
                String sectionName = myFirstCs.getString(2);
                Section_SectionName_TextField.setText(sectionName);//Set the value of text
                Section_SectionName_TextField.setEnabled(true);//Set to enable
                System.out.print(sectionName);
        }//end of connection
        catch (SQLException e) 
        {
            DBUtil.processException(e);
        }

}

我将String sectionName = myRs.getString(2); Section_SectionName_TextField.setText(sectionName); Section_SectionName_TextField.setEnabled(true);从结果集块中移除并放入可调用语句块中。当我运行程序时,唯一的变化是文本字段变为启用状态,并打印出一个“null”值。

enter image description here

第二次更新! 如果我想返回OUT参数的值,我不应该使用结果集来检索它。因此,我按照@Gord Thompson的建议使用存储过程的Callable Statement参数和OUT参数。

private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {                                         
    String searchSection = Section_SearchSection_Textfield.getText();
    String searchSection_Name = Section_SectionName_TextField.getText();
    if (searchSection.isEmpty())
    {
        JOptionPane.showMessageDialog(null, "Please fill up this fields");
    }
    else 
        try (Connection myConn = DBUtil.connect();
             CallableStatement myFirstCs = myConn.prepareCall("{call getSECTION_NAME(?,?)}"))
        {

             myFirstCs.setInt(1, 2);// I set the ID for Primary Key
             myFirstCs.registerOutParameter(2, Types.VARCHAR);
             myFirstCs.execute();

             String sectionName = myFirstCs.getString(2);  // retrieve value from OUT parameter
             Section_SectionName_TextField.setText(sectionName);//Set the value of text
             Section_SectionName_TextField.setEnabled(true);//Set to enable
             System.out.println(sectionName);

        }//end of connection
        catch (SQLException e) 
        { 
            DBUtil.processException(e);
        }
}

它仍然给我一些空值,我不知道为什么会得到这个值。

enter image description here

我的GUI只有一个文本框变为可用状态,但它没有在下一个文本框中打印我想要的值。 :(

enter image description here

谢谢您的回复。随意发表评论。


@SashaSalauyou 你好!请查看我的最新帖子。谢谢 :) - Francisunoxx
当我运行查询时,它抛出一个错误。只有第3行附近的错误,没有显示“END;”。谢谢。 - Francisunoxx
顺便说一下,你的Java代码示例肯定不完整,因为它以一个没有“if”的“else”开始。而且它在代码中间结束了。这样很难帮助你。请至少提供完整的方法,如果可以的话,甚至提供整个类源代码。 - Lars Gendner
@LarsGendner,我刚刚剪切了我的源代码。谢谢你的回复。请查看我更新的帖子。我已经发布了整个代码。再次感谢。 - Francisunoxx
2个回答

2

如果你想要通过存储过程的OUT参数返回值,则不需要使用ResultSet,而需要使用与存储过程OUT参数相关联的CallableStatement参数。例如,对于test表:

CREATE TABLE `allsections_list` (
 `SECTION_ID` int(11) NOT NULL,
 `SECTION_NAME` varchar(50) DEFAULT NULL,
 PRIMARY KEY (`SECTION_ID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8

包含示例数据

SECTION_ID  SECTION_NAME
----------  ---------------
         1  one_section
         2  another_section

以及存储过程

CREATE PROCEDURE `getSECTION_NAME`(IN myID INT, OUT myName VARCHAR(50))
BEGIN
   SELECT SECTION_NAME INTO myName FROM allsections_list WHERE SECTION_ID = myID;
END

接下来是Java代码

try (CallableStatement myFirstCs = conn.prepareCall("{call getSECTION_NAME(?,?)}")) {
    myFirstCs.setInt(1, 2);  // set IN parameter "myID" to value 2
    myFirstCs.registerOutParameter(2, Types.VARCHAR);
    myFirstCs.execute();
    String sectionName = myFirstCs.getString(2);  // get value from OUT parameter "myName"
    System.out.println(sectionName);
}

打印

another_section

您好!请查看我的更新帖子。我按照你在这里发布的代码进行了操作,但仍然返回空值 :( 最后一个问题是为什么我应该在参数中放入2?myFirstCs.setInt(1, 2);//为什么我应该放入2? 谢谢您的回复。 - Francisunoxx
在我的示例代码中,我为第一个参数提供了值“2”,因此在存储过程“myID”中,myID将等于2,而SELECT将查找对应于SECTION_ID=2SECTION_NAME值。如果您想要您的代码查找对应于SECTION_ID=7SECTION_NAME值,则应使用myFirstCs.setInt(1, 7); - Gord Thompson
哦!你真是救星:))我已经明白了。所以参数的第二个值是列的索引号。我的最后一个问题是,如果我想根据我想要搜索的内容查找现有记录怎么办?而不是调用ID号码?再次感谢!:) - Francisunoxx
我不确定你的意思,但是如果你想通过SECTION_NAME而不是SECTION_ID进行搜索,那么你需要创建另一个存储过程,使用SELECT ... WHERE SECTION_NAME=myName,其中myName是一个输入参数而不是输出参数。 - Gord Thompson
是的,我确实想通过SECTION_NAME进行搜索。当我将myID设置为OUT参数并注册时,它会显示“过程未返回任何输出参数。”实际上,我将myID设置为输出参数,但没有返回值。非常感谢您的回复! - Francisunoxx

0

在创建过程时,您应该使用delimiter将分隔符更改为与“;”不同的内容:

delimiter //
CREATE PROCEDURE getSECTION_NAME(IN ID INT, OUT NAME VARCHAR(50)) 
BEGIN 
  SELECT SECTION_NAME INTO NAME FROM allsections_list WHERE SECTION_ID = ID; 
END    
//
delimiter ;

第一个delimiter语句将分隔符设置为“//”。这样,存储过程代码中的“;”就不再被解释为分隔符。您的CREATE PROCEDURE语句然后正确地在“//”处结束。之后,第二个delimiter语句将分隔符更改回“;”。


@Mia Legaspi,你能否请提供NullPointerException的堆栈跟踪信息?谢谢。 - Lars Gendner
抱歉,但是:你知道异常的堆栈跟踪是什么吗?请看这里:https://dev59.com/32865IYBdhLWcg3wFqnY - Lars Gendner
我的程序中没有空指针异常。 存储过程正常工作。 但是当我运行程序并尝试输入现有值时,它什么都没显示。 谢谢回复。 - Francisunoxx
@MiaLegaspi 好的,请使用调试器逐步执行您的方法,以查看发生了什么。 - Lars Gendner
让我们在聊天中继续这个讨论 - Lars Gendner

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接