JDBC 似乎在我的数字周围加上了单引号

Posted

技术标签:

【中文标题】JDBC 似乎在我的数字周围加上了单引号【英文标题】:JDBC seems to be putting single quotes around my numbers 【发布时间】:2017-02-28 19:38:24 【问题描述】:

我了解 SQL 中的最佳做法是不要在数值周围使用单引号,以避免将它们转换为字符串。但是,当我在 JDBC 中使用 PreparedStatement 并要求查看该语句时,单引号会放在我设置的所有值周围,包括数字。在下面的示例中,我发送三个列表 - 列名称列表为字符串,数据类型列表为字符串,值列表为字符串。当数据类型为“int”时,我将值转换为整数并在语句中使用 setInt(),否则我使用 setString()。但是,PreparedStatement.toString() 的 println 会导致在我使用 setInt() 的任何内容周围加上单引号。

  public void update(String tableName, String colName, String valName, List<String> columnList, List<String> typeList, List<String> valueList) 
    PreparedStatement stmt = null;
    try 
      String setterSet = columnList.get(0) + "=?";
      for (int cCol = 1; cCol < columnList.size(); cCol++) 
        setterSet += "," + columnList.get(cCol) + "=?";
      
      stmt = theConnection.prepareStatement("UPDATE " + tableName + " SET " + setterSet + " WHERE " + colName + " = ?;");
      for (int cCol = 1; cCol <= valueList.size(); cCol++) 
        if (typeList.get(cCol - 1).equals("int")) 
          stmt.setInt(cCol, Integer.parseInt(valueList.get(cCol - 1)));
        
        else 
          stmt.setString(cCol, valueList.get(cCol - 1));
        
      
      stmt.setString(valueList.size() + 1, valName);
      System.out.println("Prepared Statement: " + stmt.toString());
      int rows = stmt.executeUpdate();
      stmt.close();
    
    catch (Exception e) 
      logger.error("Problem with the database: " + e.getMessage());
    
  

标准输出如下所示:

Prepared Statement: UPDATE data_sources SET id_='e80c861c-bf6c-4300-80e0-3eab29e06cec',ds_name='test001',num_files='75' WHERE ds_name = 'test001'

引用 75 是否正常?

编辑:澄清一下,我使用的是 PostgreSQL,我的 JDBC 驱动程序是:

<dependency>
  <groupId>postgresql</groupId>
  <artifactId>postgresql</artifactId>
  <version>8.4-702.jdbc4</version>
</dependency>

【问题讨论】:

我不会,如果它是平常的,但它没有区别 PreparedStatement#toString() 的具体行为取决于实现。如果您想要的不仅仅是猜测,您应该 edit 您的问题来提及(并标记)您正在使用的 JDBC 驱动程序。 您是否检查过这是否也是发送到服务器的内容?我猜这只是 toString() 方法的幼稚实现,用于显示 some 信息 - 但不是发送到服务器的确切数据。 a_horse_with_no_name,服务器似乎正在正确更新,所以这更像是对真正的最佳实践是什么感到好奇。我怀疑您对 toString 实现的看法是正确的。 不相关,但是:你为什么使用这么过时的驱动版本? 【参考方案1】:

这只是信息。如果您在 PreparedStatement 的 PostgreSQL 实例上调用 toString(),它只会使用当前参数值呈现查询。它只是提供信息(例如用于日志记录),而不是查询发送到服务器的方式。

见:

PgPreparedStatement.toString()

返回替换当前模板值的 SQL 语句。

Query.toString(ParameterList parameters)

将此查询字符串化为人类可读的形式,用特定的参数值替换参数占位符。

这是特定于驱动程序的行为,因为某些实现将只返回准备好的语句字符串,而其他实现将返回默认的Object.toString()

旁注:您使用的是相当旧版本的 PostgreSQL JDBC 驱动程序,请注意 the driver version is not related to the server version。因此,如果由于某种原因您仍在使用 PostgreSQL 8.4,您仍然可以使用支持 PostgreSQL 8.2 及更高版本的最新驱动程序 (42.0.0)。

【讨论】:

以上是关于JDBC 似乎在我的数字周围加上了单引号的主要内容,如果未能解决你的问题,请参考以下文章

sql语句引号用法 数据库中引号的用法

自学Python——字符串

如何在 Excel 中的日期周围添加单引号以在 SQL 中使用?

redshift unload : 仅在字符字段中加上引号而不是数字

NamedParameterJdbcTemplate Oracle SQL,如何在命名查询中转义单引号?

DAO.Recordset MySQL 后端在字符串周围强制使用单引号