【问题标题】:How can handle reserved character in SQL query如何处理 SQL 查询中的保留字符
【发布时间】:2016-01-12 08:28:24
【问题描述】:

我想从表中读取数据,但我收到错误,因为我要比较的值可能包含这样的词:abcd l'jdmd

我是这样尝试的:

String s = "select ref(ad) from adresse_tab ad where ad.ort='"+rs.getString(11)+"' and ad.plz='"+rs.getString(13)+"' and ad.land='"+rs.getString(14)+"'";
        
PreparedStatement stmt5 = nsdCon.prepareStatement(s);
ResultSet rs5 = stmt5.executeQuery();

查询可能如下所示:

select ref(ad) 
  from adresse_tab ad 
 where ad.ort='Frankfurt am Main' 
   and ad.plz='65301' 
   and ad.land='Deutschland' 
   and ad.strasse='almundo l'tare '

所以这个查询中的问题是这个比较:

ad.strasse='almundo l'tare '

如何处理 SQL 查询中的保留字符?

【问题讨论】:

  • 使用preparedStatement.setString .
  • 你刚刚得到的是一个sql注入的例子,考虑使用参数而不是字符串连接,这将转义你输入中的任何特殊字符

标签: java sql oracle object-oriented-database


【解决方案1】:

请避免使用字符串连接创建带有提供参数的 SQL 查询。相反,您可以继续使用 PreparedStatement,但对实际参数值使用占位符,并使用语句的 set<X>() 方法设置参数。这是official Oracle docs

您必须提供值来代替问号占位符(如果 有任何),然后才能执行 PreparedStatement 对象。做 这通过调用定义在 PreparedStatement 类。以下语句提供了两个 PreparedStatement 中名为 updateSales 的问号占位符:

updateSales.setInt(1, e.getValue().intValue()); updateSales.setString(2, e.getKey());每个参数的第一个参数 这些 setter 方法指定问号占位符。在这 例如,setInt 指定第一个占位符和 setString 指定第二个占位符。

对于您的情况:

String s = "select ref(ad) from adresse_tab ad where ad.ort=? and ad.plz=? and ad.land=?";

PreparedStatement stmt5 = nsdCon.prepareStatement(s);
stmt5.setString(1, rs.getString(11));
... and so on

【讨论】:

    【解决方案2】:

    使用prepared statement(为了更清楚命名绑定变量,您可以使用OraclePreparedStatement):

    String s = "select ref(ad) from adresse_tab ad where ad.ort=:ort and ad.plz=:plz and ad.land=:land";
    PreparedStatement st5 = nsdCon.prepareStatement(s);
    OraclePreparedStatement ost5 = (OraclePreparedStatement) st5;
    ost5.setStringAtName("ort",rs.getString(11))
    ost5.setStringAtName("plz",rs.getString(13))
    ost5.setStringAtName("land",rs.getString(14))
    ResultSet rs5 = st5.executeQuery();
    

    【讨论】:

    • 好点。命名参数更具可读性和可维护性。我希望 Java 能够开箱即用地提供它们,而不必依赖 external deps
    【解决方案3】:

    您不应将查询参数直接添加到查询字符串中。改用Prepared Statement 并在那里传递查询参数。另见Does the preparedStatement avoid SQL injection?

    【讨论】:

      【解决方案4】:

      准备好的语句的重点是在查询中使用参数,以便可以自动转义值:

      String s = "select ref(ad) from adresse_tab ad where ad.ort=? and ad.plz=? and ad.land=?";
      PreparedStatement stmt5 = nsdCon.prepareStatement(s);
      
      stmt5.setString(1, rs.getString(11));
      stmt5.setString(2, rs.getString(13));
      stmt5.setString(3, rs.getString(14));
      
      ResultSet rs5 = stmt5.executeQuery();
      

      【讨论】:

        【解决方案5】:
        ad.strasse='almundo l'''tare '
        

        【讨论】:

        • 问题是如果我事先不知道这种比较可能会发生,我该如何处理。
        • 如果您使用变量,oracle 会处理它,您不会有任何问题 - 但您已硬编码。
        • 请使用您问题的编辑链接以上下文、详细信息和/或代码示例对其进行补充。 发布答案按钮只能用于问题的完整答案
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2023-04-06
        • 1970-01-01
        • 2012-10-04
        • 1970-01-01
        • 1970-01-01
        • 2014-11-12
        • 1970-01-01
        相关资源
        最近更新 更多