为啥准备好的语句在java中不起作用?

Posted

技术标签:

【中文标题】为啥准备好的语句在java中不起作用?【英文标题】:Why the prepared statement not working in java?为什么准备好的语句在java中不起作用? 【发布时间】:2016-12-28 10:04:12 【问题描述】:

我正在尝试通过提供来自 db 的卷号和介质来获取学生信息。摆动应用程序执行时没有任何错误,但是当我输入卷号和中号时,它会进入“未找到学生”的 else 循环。

我猜是 get string 或prepared statements 的问题。请帮助我找出问题。

import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
import java.sql.*;

public class Searchdb extends JFrame implements ActionListener 

//Initializing Components
    JLabel lb,lbd,lb1, lb2, lb3, lb5;
    JTextField tf1, tf2,tf3,tf5,tfd;
    JButton btn;

    //Creating Constructor for initializing JFrame components
    Searchdb() 
        //Providing Title
        super("Fetching Roll Information");
        lb5 = new JLabel("Roll Number:");
        lb5.setBounds(20, 20, 100, 20);
        tf5 = new JTextField(20);
        tf5.setBounds(130, 20, 200, 20);

        lbd = new JLabel("Date:");
        lbd.setBounds(20, 50, 100, 20);
        tfd = new JTextField(20);
        tfd.setBounds(130, 50, 200, 20);


        btn = new JButton("Submit");
        btn.setBounds(50, 50, 100, 20);
        btn.addActionListener(this);

        lb = new JLabel("Fetching Student Information From Database");
        lb.setBounds(30, 80, 450, 30);
        lb.setForeground(Color.black);
        lb.setFont(new Font("Serif", Font.PLAIN, 12));
        setVisible(true);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setSize(500, 500);

        lb1 = new JLabel("Name:");
        lb1.setBounds(20, 120, 100, 20);
        tf1 = new JTextField(50);
        tf1.setBounds(130, 120, 200, 20);
        lb2 = new JLabel("Fathername:");
        lb2.setBounds(20, 150, 100, 20);
        tf2 = new JTextField(100);
        tf2.setBounds(130, 150, 200, 20);
        lb3 = new JLabel("State:");
        lb3.setBounds(20, 180, 100, 20);
        tf3 = new JTextField(50);
        tf3.setBounds(130, 180, 200, 20);

        setLayout(null);

        //Add components to the JFrame
        add(lb5);
        add(tf5);
        add(lbd);
        add(tfd);
        add(btn);

        add(lb);
        add(lb1);
        add(tf1);
        add(lb2);
        add(tf2);
        add(lb3);
        add(tf3);


        //Set TextField Editable False
        tf1.setEditable(false);
        tf2.setEditable(false);
        tf3.setEditable(false);

    

    public void actionPerformed(ActionEvent e) 
        //Create DataBase Coonection and Fetching Records

        try 
            String str = tf5.getText();

            Datestri = tfd.getText();//Getting the unable to convert String to Date error

            System.out.println(str);
            System.out.println(stri);

            Class.forName("oracle.jdbc.driver.OracleDriver");
            Connection con = DriverManager.getConnection("jdbc:oracle:thin:@//host:port/servicename","username","password");
            PreparedStatement st = con.prepareStatement("select Name,Fathername,State from student_db where roll_number=? and medium=?");
            System.out.println(st);
            st.setString(1, str);
            st.setDate(2, stri);



            //Excuting Query
            ResultSet rs = st.executeQuery();
            System.out.println(rs);

            if (rs.next()) 
                String s = rs.getString(1);
                String s1 = rs.getString(2);
                String s2 = rs.getString(3);


                //Sets Records in TextFields.
                tf1.setText(s);
                tf2.setText(s1);
                tf3.setText(s2);

             else 
                JOptionPane.showMessageDialog(null, "Student not Found");
            

            //Create Exception Handler
         catch (Exception ex) 

            System.out.println(ex);
        
    
//Running Constructor

    public static void main(String args[]) 
        new Searchdb();
    

sql查询:

select Name,Fathername,State from student_db where roll_number='1441' and medium='2016-12-18';

结果:

Name Fathername State 
SA     TH        YA

假设如果我没有在查询中传递“Stri”变量,我会得到结果。

【问题讨论】:

您是否尝试过使用 Oracle SQLDeveloper 或 SQL*Plus 手动执行 SQL 语句,并使用您知道正确的值? 您确定您从 UI 中正确的文本字段中获取输入吗? stri 由名为 tfd 的字段填充,该字段似乎是某种日期字段,而不是您在查询中使用的“中等”字段。请记住始终为变量提供描述性名称。 是的,我正在从 db @Powerlord 获取值 假设如果我只使用 str 则我得到结果,如果我使用两者都不起作用@MickMnemonic st.setString(2, stri); >> 如果您的第二个参数是日期,请使用st.setDate(2, dt);,dt 类型为java.sql.Date 【参考方案1】:

我已经更新了下面的代码并且它工作正常,当我检查数据库类型的中间列名它是 varchar2(40),所以我决定只使用 getString。

使用此代码获得适当的响应,

import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
import java.sql.*;

public class Searchdb extends JFrame implements ActionListener 

//Initializing Components
    JLabel lb,lbd,lb1, lb2, lb3, lb5;
    JTextField tf1, tf2,tf3,tf5,tfd;
    JButton btn;

    //Creating Constructor for initializing JFrame components
    Searchdb() 
        //Providing Title
        super("Fetching Roll Information");
        lb5 = new JLabel("Roll Number:");
        lb5.setBounds(20, 20, 100, 20);
        tf5 = new JTextField(20);
        tf5.setBounds(130, 20, 200, 20);

        lbd = new JLabel("Date:");
        lbd.setBounds(20, 50, 100, 20);
        tfd = new JTextField(20);
        tfd.setBounds(130, 50, 200, 20);


        btn = new JButton("Submit");
        btn.setBounds(50, 50, 100, 20);
        btn.addActionListener(this);

        lb = new JLabel("Fetching Student Information From Database");
        lb.setBounds(30, 80, 450, 30);
        lb.setForeground(Color.black);
        lb.setFont(new Font("Serif", Font.PLAIN, 12));
        setVisible(true);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setSize(500, 500);

        lb1 = new JLabel("Name:");
        lb1.setBounds(20, 120, 100, 20);
        tf1 = new JTextField(50);
        tf1.setBounds(130, 120, 200, 20);
        lb2 = new JLabel("Fathername:");
        lb2.setBounds(20, 150, 100, 20);
        tf2 = new JTextField(100);
        tf2.setBounds(130, 150, 200, 20);
        lb3 = new JLabel("State:");
        lb3.setBounds(20, 180, 100, 20);
        tf3 = new JTextField(50);
        tf3.setBounds(130, 180, 200, 20);

        setLayout(null);

        //Add components to the JFrame
        add(lb5);
        add(tf5);
        add(lbd);
        add(tfd);
        add(btn);

        add(lb);
        add(lb1);
        add(tf1);
        add(lb2);
        add(tf2);
        add(lb3);
        add(tf3);


        //Set TextField Editable False
        tf1.setEditable(false);
        tf2.setEditable(false);
        tf3.setEditable(false);

    

    public void actionPerformed(ActionEvent e) 
        //Create DataBase Coonection and Fetching Records

        try 
            String str = tf5.getText();

            String stri = tfd.getText();

            System.out.println(str);
            System.out.println(stri);

            Class.forName("oracle.jdbc.driver.OracleDriver");
            Connection con = DriverManager.getConnection("jdbc:oracle:thin:@//host:port/servicename","username","password");

            String str1 ="select Name,Fathername,State from student_db where roll_number='"+str+"' and medium='"+stri+"'";

            PreparedStatement st = con.prepareStatement(str1);
            System.out.println(st);
            st.setString(1, str);
            st.setString(2, stri);



            //Excuting Query
            ResultSet rs = st.executeQuery();
            System.out.println(rs);

            if (rs.next()) 
                String s = rs.getString(1);
                String s1 = rs.getString(2);
                String s2 = rs.getString(3);


                //Sets Records in TextFields.
                tf1.setText(s);
                tf2.setText(s1);
                tf3.setText(s2);

             else 
                JOptionPane.showMessageDialog(null, "Student not Found");
            

            //Create Exception Handler
         catch (Exception ex) 

            System.out.println(ex);
        
    
//Running Constructor

    public static void main(String args[]) 
        new Searchdb();
    

【讨论】:

如果您没有在准备好的语句中使用参数,您至少可以做的是清理输入。这意味着用两个单引号替换一个单引号。就像str.replace("'","''") 在将其插入字符串之前一样。它是对这样的 SQL 注入的防范。否则你很快就会得到bobby tabled。

以上是关于为啥准备好的语句在java中不起作用?的主要内容,如果未能解决你的问题,请参考以下文章

为啥此语句在 java x ^= y ^= x ^= y 中不起作用;

为啥 HttpServletRequest.getRemoteAddr() 在 Java servlet 中不起作用? [复制]

为啥 flex 属性在反应样式的组件中不起作用?

准备好的语句的 setString 不起作用

JDBC 准备好的语句不起作用 [关闭]

带有准备好的语句的 PDO bindParam() 不起作用