如何通过用户输入的表名来读取oracle数据库中的数据?

时间:2016-03-14 16:46:40

标签: java oracle

我正在尝试从oracle数据库读取数据,用户将在其中输入表名。这里没有问题。但是当我添加任何条件时,它显示错误。代码在下面给出了堆栈跟踪。

    package jdbc_test;

    import java.sql.*;
    import java.util.Scanner;

    public class JDBC_Test {
        public static void main(String[] args) {

            String tableName=null;
            Scanner input = new Scanner(System.in);
            int id=8;

            System.out.println("Enter the table name: ");
            tableName = input.nextLine();

            try
            {

                Connection con = DriverManager.getConnection(
                        "jdbc:oracle:thin:@localhost:1521:oracle12c", "system", "oracle12c");


                Statement stmt = con.createStatement();


                ResultSet rs = stmt.executeQuery("select * from "+tableName+"where id='"+id+"'");

                System.out.printf("%15s%15s","Name","ID");

                while (rs.next())
                {
                    System.out.printf("\n%15s",rs.getString("name"));
                }

                con.close();
                stmt.close();
            }
            catch (Exception e)
            {
                System.out.println(e);
            }
          }
      }

控制台:

Enter the table name: 
t

例外:

java.sql.SQLSyntaxErrorException: ORA-00933: SQL command not properly ended

如何用条件读取用户指定表名的数据?

2 个答案:

答案 0 :(得分:9)

您的示例提供的答案"有效"容易受到SQL injection attacks的攻击。 阅读这个危险的做法。因此,我建议你不要使用它。

您想对列字段使用PreparedStatement。请阅读准备好的陈述的重要性,因为它将为您在编写更安全的解决方案方面的更好未来做好准备。

允许用户输入表名是一个好主意

这不仅不是一个好主意,它甚至不受PreparedStatement的支持。

您不能在预准备语句中将表名用作参数(?)。您必须找到另一种方法将其放在那里,例如字符串连接,这很危险。

除非您使用预先确定的白名单,否则不能允许用户选择表名,因为这样可以进行SQL注入。

存储库中的凭据是另一个安全风险。

您还应该避免将用户名和密码直接放入getConnection()。使用秘密管理器,或者至少从属性文件中读取(如果使用秘密管理器加密,则获得奖励积分),这些文件并未提交到存储库。

这是您固定的尝试块:

try
{
    Connection con = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:oracle12c", username, password);

    // You want to prepare a statement so you can pass parameters.
    PreparedStatement stmt = con.prepareStatement();

    // The first question mark (?)
    // Assuming this is an INT type. If not, there is setString, setLong, etc.
    ps.setInt(1, id);

    // Note the first question mark is where the ID is supposed to be. This is a parameter.
    ResultSet rs = stmt.executeQuery("select * from tableName where id = ?");

    while (rs.next())
    {
        // Replace "column_name" with the name of your column
        System.out.println(rs.getString("column_name"));
    }

    con.close();
    stmt.close();
}

如果您正在学习编码,无论是谁告诉您按照您的方式进行编码,都会为您设置一段非常糟糕的编码习惯,这将导致您工作的公司成为黑客攻击。

答案 1 :(得分:-4)

"select * from "+tableName+"where id='"+id+"'"更改为"select * from " + tableName + " where id='" + id + "'"

注意where子句之前的空格。