无法使用存储过程检索我想要选择的值

Posted

技术标签:

【中文标题】无法使用存储过程检索我想要选择的值【英文标题】:Cannot retrieve the value I desired to Select using Stored Procedure 【发布时间】:2016-07-12 00:47:29 【问题描述】:

我正在尝试查找记录。这让我可以选择使用存储过程在我的数据库中查找现有记录。当我尝试搜索现有数据时,它并没有给我想要的值。当我点击搜索按钮时,它不会将值打印到文本字段。

代码

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); 移出 Result Set 块并将其放入 Callable Statement 块中。当我运行程序时。唯一的变化是启用了文本字段并打印了一个“空”值。

第二次更新! 我想返回 OUT 参数的值,我不应该使用 Result Set 来检索它。所以我根据@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);
        

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

对我的 GUI 的唯一更改是启用了文本字段,并且它没有在以下文本字段中打印我想要的值。 :(

感谢您的回复。欢迎发表评论。

【问题讨论】:

@SashaSalauyou 嗨!请看我更新的帖子。谢谢:) @SashaSalauyou 当我运行查询并引发错误时。 '结束;'不只显示第 3 行附近的错误。谢谢。 顺便说一下,您的 Java 代码示例肯定不完整,因为它以“else”开头而没有“if”。它在代码中间结束。这样,很难帮助你。请至少提供完整的方法,如果不是整个类的源代码。 @LarsGendner 我刚刚剪切了我的源代码。感谢您的回复。请看我更新的帖子。我已经发布了整个代码。再次感谢。 【参考方案1】:

您应该使用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 语句正确地以“//”结束。之后,第二个delimiterstatement 将分隔符改回“;”。

【讨论】:

@Mia Legaspi 您能否发布 NullPointerException 的堆栈跟踪?谢谢 对不起,但是:你知道异常的堆栈跟踪是什么吗?看这里:***.com/questions/3988788/… 我的程序中还没有 NullPointerException。存储过程正常工作。但是当我运行我的程序并尝试输入现有值时,它什么也没有显示。感谢您的回复。 @MiaLegaspi 好的,那么请使用调试器逐步执行您的方法,看看发生了什么。 让我们continue this discussion in chat.【参考方案2】:

如果您想要通过存储过程的 OUT 参数返回的值,则不要使用 ResultSet,而是使用与存储过程的 OUT 参数关联的 CallableStatement 参数。比如对于测试表

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);//Why should I put 2? 感谢您的回复。 在我的示例代码中,我为第一个参数提供了值2,因此在存储过程中myID 将等于2SELECT 将查找对应的SECTION_NAME 值到SECTION_ID=2。如果您希望您的代码查找与SECTION_ID=7 对应的SECTION_NAME 值,那么您将使用myFirstCs.setInt(1, 7); 哦!你的救命稻草:))我已经明白了。所以参数的第二个值是列索引的#。我的最后一个问题。如果我想根据要搜索的内容查找现有记录怎么办?不调用 ID 号?再次感谢! :) 我不确定你的意思,但如果你想通过 SECTION_NAME 而不是 SECTION_ID 进行搜索,那么你需要创建另一个存储过程来执行 SELECT ... WHERE SECTION_NAME=myName,其中 myName 是一个 IN 参数而不是一个 OUT 参数。 是的,我想按 SECTION_NAME 进行搜索。当我将我的myID 设置为 OUT 参数并注册它时。它说No output parameters returned by procedure. 实际上我将myID 设置为输出参数但没有返回值。非常感谢您的回复!

以上是关于无法使用存储过程检索我想要选择的值的主要内容,如果未能解决你的问题,请参考以下文章

无法使用存储过程检索我想要选择的值

无法使用 OracleManagedDataAccess 从 oracle 存储过程中检索出参数

数据集可以使用存储过程返回多少个表

无法使用 oracle 存储过程在水晶报表 2013 中创建报表

MVC-5 对存储过程使用复杂类型的函数;创建视图给出错误:'无法检索 MyProject.Models.Movies_Result 的元数据

无法使用存储过程获得确切的结果,因为它返回带有增量的值[关闭]