我正在尝试从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
如何用条件读取用户指定表名的数据?
答案 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子句之前的空格。