Java 使用预先准备好的语句的动态列名+;包含';s

Java 使用预先准备好的语句的动态列名+;包含';s,java,mysql,sql,jdbc,Java,Mysql,Sql,Jdbc,我的问题 attributes.replace(" ' ", ""); //also used SET "+attributes+" String sql; sql = "UPDATE diseaseinfo" + " SET ?=?" + "WHERE companyname = 'mycom' && diseaseName =?"; PreparedStatement preparedStmt = connects.prepareState

我的问题

attributes.replace(" ' ", "");
//also used SET "+attributes+" 
String sql;
sql = "UPDATE diseaseinfo"
        + " SET ?=?"
        + "WHERE companyname = 'mycom' && diseaseName =?";

PreparedStatement preparedStmt = connects.prepareStatement(sql);
preparedStmt.setString(1, attributes);
preparedStmt.setString(2, attrData);
preparedStmt.setString(3, medname);
System.out.println(preparedStmt);
这给了我一个错误,因为查询设置了字符串中的列名,所以在

 UPDATE diseaseinfo SET 'causes'='abc' WHERE companyname = 'mycom'  and diseaseName ='fever'
通过这个问题,我知道我不能通过预先准备的语句添加动态列:

现在,真正的问题出现了:假设我将使用一个简单的更新查询,如以下问题所示:

它表示您不能在简单sql查询中输入带的值,因为它会再次导致查询语法错误,例如:

SELECT * FROM diseaseinfo WHERE diseaseName = 'Adult Still's disease' AND name = 'add';
在这里它不会执行,因为“在”成人仍然是

那么它将无法处理简单的查询。我现在该怎么办?使用什么?要设置动态列,请在查询中考虑


我不担心SQL注入,因为我正在本地工作。我只想执行我的查询。

对。我们不能提供标识符作为绑定参数。列的名称必须是SQL文本的一部分

我们可以通过以下方式将列的名称动态合并到SQL文本中:

  sql = "UPDATE diseaseinfo"
      + " SET `" + colname + "` = ?"
      + " WHERE companyname = 'mycom' AND diseaseName = ?";
并为其余两个绑定参数提供值

  preparedStmt.setString(1, attrData);
  preparedStmt.setString(2, medname);
您对SQL注入的关注是绝对正确的

作为绑定值提供,
attrData
medname
的值中的单引号在SQL注入方面不会成为问题

但是,我提供的示例通过将
colname
变量合并到SQL文本中而容易受到攻击,如果我们不能保证
colname
可以“安全”地包含在语句中

因此,我们需要将一个值赋值给
colname
“safe”

我们可以使用几种方法来实现这一点。最安全的方法是“白名单”方法。代码可以确保在将
colname
包含到SQL文本中之前,只将特定允许的“安全”值分配给
colname

举个简单的例子:

  String colname;
  if (attributes.equals("someexpectedvalue") {
      colname = "columnname_to_be_used";
  } else if (attributes.equals("someothervalid") {
      colname = "valid_columname";
  } else {
     // unexpected/unsupported attributes value so
     // handle condition or throw an exception 
  }
一种更灵活的方法是确保反勾号字符不会出现在
colname
中。在本例中,
colname
的值通过将其包含在反勾号中进行转义。因此,只要反勾号字符没有出现在
colname
中,我们将防止提供的值被解释为标识符以外的任何内容

< >对于使用硬编码的回退字符的更通用(复杂)的方法,我们可以考虑使用<代码>支持方dioToosiers/Cuff>和 GeTyTristQuooToStc><代码> >方法>代码> java .SQL.DabaseMeMeistabue/Cux>类。p>

(在操作代码中,我们看不到
属性
内容的数据类型。我们看到对名为
replace
的方法的调用,以及提供给该方法的参数。假设
属性
是一个字符串,并且应该是一个列名,我们根本不清楚为什么会有“空格单引号空格”在字符串中,或者为什么我们需要删除它。除此之外,这个答案没有解决这个问题。)

了解防止SQL注入的准备语句。它还将转义特殊字符
,它还将转义特殊字符
,这正是我的问题。。我想你没有得到你想让你的字段更新为动态的问题,不要对它使用预先准备好的语句,只要做:
“update diseaseinfo SET”+avarwhiththefieldname+“=?”
并像你已经做的那样将实际参数作为PS传递。我已经尝试过了。。。它再次给了我“原因”,我同意@JorgeCampos为什么在你的专栏doe中使用