参数化查询在PostgreSQL中的使用

huangapple go评论127阅读模式
英文:

Parameterized query in PostgreSQL

问题

我是 PostgreSQL 新手,正在尝试使参数化查询起作用。我有以下 SQL 语句,其中类型 A 似乎是正常的,但类型 B 不起作用。

SQL 类型 A)

     StringBuilder buffer = new StringBuilder("Select * from JOB where")    
     buffer.append(" START_TIME ");
     buffer.append(" BETWEEN '2020-08-17' AND '2020-08-18'");
     String sql = buffer.toString();

  
SQL 类型 B)- 参数化 

     StringBuilder buffer = new StringBuilder("Select * from DA_JOB where")    
     buffer.append("START_TIME");
     buffer.append(" BETWEEN ? AND ?");
     String sql = buffer.toString();
    

根据类型执行查询 - 执行类型 A 是成功的,但类型 B 不成功
    
    try (Connection dbConnection = getConnection();
         PreparedStatement statement = dbConnection.prepareStatement(sql)) {
          if (typeB) {
                 // myHashMap<String, String> 保存一些键值

                  StringBuilder st = new StringBuilder("'");
                  String value = myHashMap.get("startTime");
                  st.append(value);
                  st.append("'");
                  statement.setString(1, st.toString());                
                  
                  StringBuilder st1 = new StringBuilder("'");
                  String value2 = myHashMap.get("endTime");
                  st1.append("'");
                  statement.setString(2, st1.toString());
          }
          try (ResultSet rs = statement.executeQuery()) {
                while (rs.next()) {
                     jobs.add(sanitize(rs));
                 }
            } 

     }

执行参数化查询(类型 B)时,我收到以下错误:

> "org.postgresql.util.PSQLException: ERROR: operator does not exist:
> timestamp without time zone >= character varying\n  Hint: No operator
> matches the given name and argument type(s). You might need to add
> explicit type casts.

这似乎是在设置字符串后最终查询中的引号问题。您有关于如何修复这个问题的任何提示吗?非常感谢。
英文:

I am new in PostgreSQL and trying to get parameterized query to work. I have following sql statements where type A seems to be ok but type B does not work.

sql type A)

 StringBuilder buffer = new StringBuilder("Select * from JOB where")    
 buffer.append(" START_TIME ");
 buffer.append(" BETWEEN '2020-08-17' AND '2020-08-18'");
 String sql = buffer.toString();

sql type B) - parameterized

 StringBuilder buffer = new StringBuilder("Select * from DA_JOB where")    
 buffer.append("START_TIME");
 buffer.append(" BETWEEN ? AND ?");
 String sql = buffer.toString();

execute query based on the type - executing type A is successful but type B is not

try (Connection dbConnection = getConnection();
     PreparedStatement statement = dbConnection.prepareStatement(sql)) {
      if (typeB) {
             //myHashMap<String, String> holds some key value

              StringBuilder st = new StringBuilder("'");
              String value = myHashMap.get("startTime")
              st.append(value);
              st.append("'");
              statement.setString(1, st.toString());                
              
              StringBuilder st1 = new StringBuilder("'");
              String value2 = myHashMap.get("endTime")
              st1.append("'");
              statement.setString(2, st1.toString());
      }
      try (ResultSet rs = statement.executeQuery()) {
            while (rs.next()) {
                 jobs.add(sanitize(rs));
             }
        } 

 }

the error I get from executing parameterized query which is type B is

> "org.postgresql.util.PSQLException: ERROR: operator does not exist:
> timestamp without time zone >= character varying\n Hint: No operator
> matches the given name and argument type(s). You might need to add
> explicit type casts.

which seams to be quotation problem in the final query after setting string.
Any tips on how I can fix this? It is really appriciated.

答案1

得分: 3

基本上,问题是数据库引擎拒绝将您的字符串转换为日期。您可以采取两种方法来解决这个问题。其中一种方法是在服务器端添加转换。BETWEEN ?::date AND ?::date 应该可以工作。:: 是 PostgreSQL 中的非标准转换符号;您也可以使用符合 SQL 标准的 CAST 语法。

另一种方法是使用 preparedStatement 的 setDate,从存储的字符串创建一个 java.sql.Date 对象(或将日期存储在您的 HashMap 中)。

英文:

Basically, the problem is that the DB engine is refusing to cast your string into a date. There are two approaches you can take to fix this. One is to add a cast server-side. BETWEEN ?::date AND ?::date should work. The :: is a PostgreSQL non-standard cast; you can also use SQL-compliant CAST syntax if you want.

An alternative would be to use preparedStatement's setDate, creating a java.sql.Date object from your stored String (or storing a Date in your HashMap).

huangapple
  • 本文由 发表于 2020年8月18日 09:58:36
  • 转载请务必保留本文链接:https://go.coder-hub.com/63460839.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定