Postgres异常 - 内部声明是正确的,但查询失败

时间:2013-09-12 21:04:06

标签: postgresql datetime timezone

我正在使用以下内容将记录插入我的数据库:

        PreparedStatement stmt = null;
        Connection conn = null;

        HashMap<String, Object> hoursMap = new HashMap<String, Object>();



        hoursMap.put("PLACE_ID", hours.getPlaceID());
        hoursMap.put("DAY", hours.getDayID());
        hoursMap.put("TIME_OPEN", hours.getTimeOpen());
        hoursMap.put("TIME_CLOSE", hours.getTimeClose());

        String insertStr = StatementCreator.insertQueryGenerator("HOURS",
                hoursMap);


        try {
            conn = ConnectionManager.getConnection();
            stmt = StatementCreator.createStatement(conn, insertStr, hoursMap,
                    false);

            returnVal = stmt.execute();
            ConnectionManager.closeStatement(stmt);
            System.out.println("Created");
        } catch (SQLException e) {
            System.out.println("ERROR");
            e.printStackTrace();
        } finally {
            ConnectionManager.closeConnection(conn);
        }

        return returnVal;
    }

但是,运行此操作时出现以下错误:

  

org.postgresql.util.PSQLException:错误:列“TIME_OPEN”是   键入时区与时区,但表达式的类型字符不同
  提示:您需要重写或转换表达式。位置:71

我无法弄清楚为什么?我说的原因是,如果我进入调试模式并查看内部预处理语句,我会看到以下内容:

INSERT INTO "HOURS" ("TIME_OPEN","DAY","TIME_CLOSE","PLACE_ID")VALUES('11:30:00-0400',6,'23:59:59-0400',541)

我将其复制/粘贴到我的SQL编辑器中,然后运行并插入记录。

我有什么遗失的吗?

2 个答案:

答案 0 :(得分:2)

字符串文字varchar类型的变量之间存在微妙但决定性的差异。

'11:30:00-0400'这样的字符串文字没有分配类型。但是您的函数显然会返回varchar,这与'11:30:00-0400'::varchar相同。 与错误消息一样,您需要在这种情况下添加显式强制转换

'11:30:00-0400'::varchar::timetz

或者,在你的情况下可能:

hours.getTimeOpen())::timetz

(不确定您使用的语法类型。)
或者让你的函数返回正确的类型开始。

不要使用timetz

顺便说一下,我强烈建议不要使用time with timezone(简称timetz)。这是一个逻辑上破碎的类型。 Postgres仅提供标准兼容性,但提供反对其使用的建议。我引用the manual here

  

为解决这些困难,我们建议使用日期/时间类型   包含使用时区的日期和时间。我们不推荐   使用类型time with time zone(尽管它受到支持   PostgreSQL用于遗留应用程序并符合SQL标准)

here

  

类型time with time zone由SQL标准定义,但是   定义表现出导致可疑用途的特性。   在大多数情况下,datetimetimestamp without time zonetimestamp with time zone的组合应提供完整的范围   任何应用程序所需的日期/时间功能。

答案 1 :(得分:1)

如果您只存储时间+时区而没有日期部分,则应将PostgreSQL一侧的数据类型声明为timetz(或time with time zone)而不是timestamptz(或{{ 1}})。