Golang中Pq库处理数组字面量"2024-04-05 00:00:00Z"报错问题

Golang中Pq库处理数组字面量"2024-04-05 00:00:00Z"报错问题 在PostgreSQL数据库中

{"2024-04-05 00:00:00","2024-04-10 00:00:00"}
func qSchBkg(w http.ResponseWriter, conn *sql.DB,start time.Time,end time.Time) (rows *sql.Rows, err error) {

    fmt.Println("qSchBkg start.. ", start)
    // start,end print 2024-04-06 00:00:00 +0000 UTC 2024-04-07 00:00:00 +0000 UTC
    rows,err = conn.Query("SELECT * FROM booking WHERE days_booking BETWEEN $1 AND $2", start,end)

    if err != nil {
        switch {
            case true:
            fmt.Fprintf(w, "Error: Query()..! : %+v\n", err)
            break
        }
        return
    }
    return rows,err
}

更多关于Golang中Pq库处理数组字面量"2024-04-05 00:00:00Z"报错问题的实战教程也可以访问 https://www.itying.com/category-94-b0.html

4 回复

尝试在 PostgreSQL 数据库客户端中运行相同的查询,以查看数据库返回的错误信息。

更多关于Golang中Pq库处理数组字面量"2024-04-05 00:00:00Z"报错问题的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


数据库中的字段是 WITH TIMESTAMP 吗?

正如 @Yamil_Bracho 所建议的,尝试在 SQL 提示符下运行并检查结果。

这显然不是一个“Go”语言的问题,而是一个Postgre问题。或者更准确地说,是对Postgres如何处理诸如Time这类类型存在误解。这不仅仅是匹配数据库中的字符串那么简单。你得到的字符串并非它在数据库中存储或比较的方式。你需要深入研究Postgres及其内部的实际工作原理。

在Golang中使用pq库处理PostgreSQL数组字面量时,"2024-04-05 00:00:00Z"这种格式确实会导致问题。PostgreSQL期望的是ISO 8601格式的数组,而pq库对时间数组有特定的处理方式。

主要问题是:pq库期望时间数组使用PostgreSQL的数组字面量格式,而不是JSON格式。以下是正确的处理方式:

import (
    "database/sql"
    "fmt"
    "time"
    "github.com/lib/pq"
)

func qSchBkg(w http.ResponseWriter, conn *sql.DB, start time.Time, end time.Time) (rows *sql.Rows, err error) {
    fmt.Println("qSchBkg start.. ", start)
    
    // 正确的方式:使用pq.Array()包装时间切片
    timeRange := []time.Time{start, end}
    
    rows, err = conn.Query(
        "SELECT * FROM booking WHERE days_booking BETWEEN $1 AND $2", 
        pq.Array(timeRange),
    )

    if err != nil {
        fmt.Fprintf(w, "Error: Query()..! : %+v\n", err)
        return nil, err
    }
    return rows, nil
}

如果需要在查询中使用时间数组字面量,应该这样处理:

// 方法1:使用pq.FormatTimestamp格式化时间
func queryWithTimeArray() {
    start := time.Date(2024, 4, 5, 0, 0, 0, 0, time.UTC)
    end := time.Date(2024, 4, 10, 0, 0, 0, 0, time.UTC)
    
    // 创建PostgreSQL兼容的时间数组字面量
    timeArray := fmt.Sprintf("ARRAY['%s','%s']", 
        start.Format("2006-01-02 15:04:05"), 
        end.Format("2006-01-02 15:04:05"))
    
    rows, err := conn.Query(
        "SELECT * FROM booking WHERE days_booking = ANY($1::timestamp[])",
        timeArray,
    )
}

对于BETWEEN查询,更推荐使用两个单独的参数:

func qSchBkgOptimized(w http.ResponseWriter, conn *sql.DB, start time.Time, end time.Time) (rows *sql.Rows, err error) {
    rows, err = conn.Query(
        "SELECT * FROM booking WHERE days_booking BETWEEN $1 AND $2", 
        start, 
        end,
    )

    if err != nil {
        fmt.Fprintf(w, "Error: Query()..! : %+v\n", err)
        return nil, err
    }
    return rows, nil
}

如果需要处理时间数组作为参数,应该这样:

func queryWithTimeSlice(times []time.Time) (*sql.Rows, error) {
    rows, err := conn.Query(
        "SELECT * FROM booking WHERE days_booking = ANY($1)", 
        pq.Array(times),
    )
    return rows, err
}

关键点:

  1. 对于时间数组,使用pq.Array()包装
  2. 避免直接使用JSON格式的时间字符串
  3. BETWEEN查询更适合使用两个单独的时间参数
  4. PostgreSQL时间数组字面量格式应该是:ARRAY['2024-04-05 00:00:00','2024-04-10 00:00:00']
回到顶部