微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

java-使用准备好的语句sql查询和包含的变量的动态列名

我的查询

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'

通过这个问题,我知道我无法通过准备好的语句添加动态列:https://stackoverflow.com/a/3136049/7794329

现在,真正的问题浮出水面:假设我是否将使用一个简单的更新查询,例如:jdbc dymanic sql query with variable containg ‘s

它说您不能在简单的SQL查询中使用来输入值,因为它将再次使查询语法错误,例如:

SELECT * FROM diseaseinfo WHERE diseaseName = 'Adult Still's disease' AND name = 'add';

在这里它不会执行,因为在“ Adult Still”上有“”

然后它将无法与简单查询一起使用.我现在应该怎么办?使用什么?要设置动态列,并注意查询中的.

我不担心sql注入,因为我在本地工作.我只希望执行查询.

解决方法:

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

我们可以将列名称动态地合并到sql文本中,如下所示:

  sql = "UPDATE diseaseinfo"
      + " SET `" + colname + "` = ?"
      + " WHERE companyname = 'mycom' AND diseaseName = ?";

并为剩余的两个绑定参数提供值

  preparedStmt.setString(1, attrData);
  preparedStmt.setString(2, medname);

您完全关心sql注入是正确的.

作为绑定值提供,就sql注入而言,attrData和medname值中的单引号不会成为问题.

但是,如果我们不能保证将colname包含在语句中,那么我提供的示例很容易通过将colname变量合并到sql文本中而受到攻击.

因此,我们需要为“安全”名称分配一个值.

我们可以使用几种方法来做到这一点.最安全的是“白名单”方法.该代码可以确保在将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的值通过将其括在反引号中进行转义.因此,只要colt中没有出现反引号字符,我们就可以防止将提供的值解释为标识符以外的任何内容.

对于使用硬编码反引号字符的更通用(更复杂)的方法,我们可以考虑使用java.sql.DatabaseMetaData类的supportsQuotedIdentifiers和getIdentifierQuoteString方法.

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

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐