SonarQube报告警告:'准​​备好的语句是从非常量字符串'生成的。

时间:2016-01-08 17:50:00

标签: java sonarqube prepared-statement

我在方法中使用下面的代码:

// These three code snippets mean the same thing. 
// If x is true according to groovy truth return x else return y
x ?: y

x ? x : y  // Standard ternary operator.

if (x) {
  return x
} else {
  return y
}

并在此行显示警告:final StringBuffer queryBuffer = new StringBuffer(100); queryBuffer.append("update ").append(tblContainerItem).append(" "); queryBuffer.append("set SENT_STATUS=").append(CaaConstants.STATUS_CI_SENT); queryBuffer.append(", SENT_DATE='").append(today.toString()).append("' "); final int len = containerItemIds.length; for (int i = 0; i < len; i++) { if (i == 0) { queryBuffer.append("where CI_ID="); } else { queryBuffer.append(" or CI_ID="); } queryBuffer.append(containerItemIds[i]); } try { conn = getConnection(); pstmt = conn.prepareStatement(queryBuffer.toString()); ...

如何避免此警告?我知道使用pstmt = conn.prepareStatement(queryBuffer.toString());,但这不是消除此错误的正确方法。

1 个答案:

答案 0 :(得分:4)

你正在构建的是动态sql,它通常被认为是固有的危险。例如,您似乎对要更新的表没有限制。相反,你应该做类似

的事情
String update = "update MY_TABLE set SENT_STATUS=?, SENT_DATE=? where CI_ID=?";
try {
  conn = getConnection();
  pstmt = conn.prepareStatement(update);
  pstmt.setString(1, CaaConstants.STATUS_CI_SENT);
  pstmt.setString(2, today.toString());
  pstmt.setString(3, containerItemIds[i]);
  //...

这有两件事

  1. 确保您确实更新了要更新的表格中的行
  2. 通过转义传递给查询的值来保护您免受恶意输入的侵害
  3. 请注意,如果您已将表名设置为动态,因为您有多个具有相同列的不同表,

    1. 您应该检查数据库结构是否有重构机会
    2. 你应该为每一个编写单独的代码。保存几行代码不值得更新您不想要的内容的风险。