我试图在我的 Java 程序中防止 SQL 注入。我想使用 PreparedStatements 来执行此操作,但我事先不知道列数或其名称(该程序允许管理员在表中添加和删除列)。我是新手,所以这可能是一个愚蠢的问题,但我想知道这种方法是否安全:
public static int executeInsert( String table, Vector<String> values)
{
Connection con;
try {
con = connect();
// Construct INSERT statement
int numCols = values.size();
String selectStatement = "INSERT INTO " + table + " VALUES (?";
for (int i=1; i<numCols; i++) {
selectStatement += ", ?";
}
selectStatement += ")";
PreparedStatement prepStmt = con.prepareStatement(selectStatement);
// Set the parameters for the statement
for (int j=0; j<numCols; j++) {
prepStmt.setString(j, values.get(j));
}
System.out.println( "SQL: " + prepStmt) ;
int result = prepStmt.executeUpdate();
con.close() ;
return( result) ;
} catch (SQLException e) {
System.err.println( "SQL EXCEPTION" ) ;
System.err.println( "Inserting values " + values + " into " + table);
e.printStackTrace();
}
return -1;
}
基本上,我根据传入的值的数量(以及表中有多少列)动态地为语句创建字符串。我觉得它是安全的,因为 PreparedStatement 直到创建此字符串后才真正创建。我可能会制作类似的函数,它们接受实际的列名并将它们合并到 SQL 语句中,但这些将由我的程序生成,而不是基于用户输入。