我尝试创建PreparedStatement:
stmt = conn.prepareStatement("SELECT POLBRP, POLTYP, POLNOP, INCPTP, TRMTHP, " +
"CLTKYP , CANDTP, POLSTP, EXPRYP, OINCPP, CANRNP, PAYMDP,
KCNFLP, KCRTSP, KACADP, KSCHMP, EXPRYP FROM "
+ POLHDR + " WHERE POLNOP = " + idNumber +
" AND POLBRP = " + branch + " AND POLTYP = " + product +
" AND OINCPP <= "+date );
这会抛出一个SQLException:[SQL0206]列AD不在指定的表中。
我不知道它是从哪里获取列AD,因为我从未在select子句中指定它(除非我完全失明和愚蠢)
有人可以帮忙吗?
答案 0 :(得分:4)
如果您的变量是字符串,例如branch
" AND POLBRP = " + branch + " ...
然后你忘了引用值
" AND POLBRP = '" + branch + "' ...
但真正的解决方案是使用占位符
... AND POLBRP = ? ...
这将一劳永逸地防止这些问题,这就是PreparedStatement为
设计的答案 1 :(得分:1)
Preventing SQL Injection in Java显示正确使用PreparedStatement
:
准备好的语句变量作为参数传递给准备好的 JDBC驱动程序将自动转义语句。
示例:ps.1
String selectStatement = "SELECT * FROM User WHERE userId = ? ";
PreparedStatement prepStmt = con.prepareStatement(selectStatement);
prepStmt.setString(1, userId);
ResultSet rs = prepStmt.executeQuery();
来自同一来源,请参阅同一部分:
尽管Prepared Statements有助于防范SQL注入, 有可能通过不适当的SQL注入攻击 使用准备好的声明。下面的例子解释了这样一个 输入变量直接传递到的场景 准备好的声明,从而为 SQL注入攻击铺平道路。
示例:ps.2
String strUserName = request.getParameter("Txt_UserName");
PreparedStatement prepStmt = con.prepareStatement("SELECT * FROM user WHERE userId = '+strUserName+'");
答案 2 :(得分:1)
尝试将您的查询更改为:
SELECT
POLBRP,
POLTYP,
POLNOP,
INCPTP,
TRMTHP,
CLTKYP,
CANDTP,
POLSTP,
EXPRYP,
OINCPP,
CANRNP,
PAYMDP,
KCNFLP,
KCRTSP,
KACADP,
KSCHMP,
EXPRYP
FROM TableName WHERE POLNOP = ? AND POLBRP = ? AND POLTYP = ? AND OINCPP <= ?";
然后使用:
stmt.setString(1, "ValueOfPOLNOP");
...
执行查询时?
将替换为您传递给PreparedStatement#setString(int, String)方法的值