java - 如何通过用户输入的表名和条件从oracle数据库中读取数据?

标签 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

异常(exception):

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

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

最佳答案

你的例子,提供的答案“有效”很容易受到 SQL injection attacks 的影响。 。 仔细阅读这种危险的做法。因此我建议您不要使用它。

您想使用PreparedStatement对于列字段。请阅读准备好的语句的重要性,因为它将帮助您为编写更安全的解决方案创造更美好的 future 做好准备。


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

这不仅不是一个好主意,而且 PreparedStatement 也不支持它。

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

除非您使用预先确定的白名单,否则您不能允许用户选择表名称,因为这将允许 SQL 注入(inject)。

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

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

这是您的固定尝试 block :

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();
}

如果你正在学习编码,无论谁告诉你按照你正在做的方式去做,都会让你一生都处于非常糟糕的编码实践中,这将导致你工作的公司遭到黑客攻击。

关于java - 如何通过用户输入的表名和条件从oracle数据库中读取数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35993345/

相关文章:

java - 如何使用 Jackson 的 objectMapper 反序列化接口(interface)字段?

java - 将旧式 if 用法转换为Optional.ifPresent() 时出现问题

sql - 如何增加非数字列的值?

java - 让 hibernate 记录 clob 参数

java - 如何序列化ArrayList中的对象?

java - JOGL 和 Swing 的问题

java - java中如何查找一个字符串对象重复了多少次?

mysql - 使用 join、distinct、count 和 where 的复杂 SQL 请求

sql - 在sql oracle中格式化单列中的名称

java - 在 Java 中使用 HikariCP 时如何指定数据库特定属性?