问题:如何正确扫描Golang中array_agg函数的结果?

在我的 Golang (1.15) 应用程序中,我使用sqlx包来处理 PostgreSQL 数据库 (PostgreSQL 12.5)。

我的 SQL 请求有一个array_agg函数,该函数返回字符串数组,如果为空则返回 null。

我正在尝试Scan这个 SQL 请求的结果,但它在我的程序中引发了下一个错误:

sql:列索引 3 上的扫描错误,名称“organization_ids”:不支持扫描,将驱动程序.Value 类型字符串存储到类型 *[]string

代码片段:

type Channel struct {
    ChannelId           *string   `db:"channel_id" json:"channelId"`
    ChannelName         *string   `db:"channel_name" json:"channelName"`
    OrganizationsIds    *[]string `db:"organizations_ids" json:"organizationsIds"`
}

var channel Channel

row := db.QueryRow(`
    select
        channels.channel_id::text,
        channels.channel_name::text,
        array_agg(distinct channels_organizations_relationship.organization_id)::text[] organizations_ids
    from
        channels
    left join channels_organizations_relationship on
        channels.channel_id = channels_organizations_relationship.channel_id
    where
        channels.channel_id = $1
    group by
        channels.channel_id
    limit 1;`, *channelId)

if err := row.Scan(&channel.ChannelId, &channel.ChannelName, &channel.OrganizationsIds); err != nil {
    fmt.Println(err)
}

return &channel

我还尝试将github.com/lib/pq包中Channel结构中OrganizationsIds字段的数据类型更改为*pg.StringArray。在这种情况下,当我Scan时,我的程序中出现以下错误:

sql:列索引 3 上的扫描错误,名称“organizations_ids”:不支持扫描,将驱动程序.Value 类型字符串存储到类型 *[]pq.StringArray

我的任务是为该列向客户端返回字符串列表或 null/nil。

有人可以解释如何解决这种奇怪的行为吗?

解答

好吧,终于我找到了我的问题的解决方案。

我注意到array_agg函数返回[null]。我稍微更改了 SQL 请求以返回null而不是[null]。我通过以下更改做到了:

array_agg(distinct channels_organizations_relationship.organization_id) filter (where channels_organizations_relationship.organization_id is not null)

在这篇文章中(Postgres 返回 [null] 而不是 [] for array_agg of join table),您可以找到许多不同的解决方案来解决这个问题。

然后您可以使用以下解决方案之一:

第一个选项

我们可以在 struct 中使用OrganizationsIds pq.StringArray,然后在扫描时执行 row.Scan(..., &channel.OrganizationIds

第二个选项

我们可以在结构体中使用OrganizationsIds []string,然后在扫描时执行row.Scan(..., (*pq.StringArray)(&channel.OrganizationIds))

Logo

PostgreSQL社区为您提供最前沿的新闻资讯和知识内容

更多推荐