sql - 如何在 Golang 中正确扫描 array_agg 函数的结果?

标签 sql postgresql go

在我的 Golang (1.15) 应用程序中,我使用 sqlx用于 PostgreSQL 数据库 (PostgreSQL 12.5) 的软件包。

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

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

sql: Scan error on column index 3, name "organization_ids": unsupported Scan, storing driver.Value type string into type *[]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

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

sql: Scan error on column index 3, name "organizations_ids": unsupported Scan, storing driver.Value type string into type *[]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 returns [null] instead of [] for array_agg of join table ) 中,您可以找到针对此问题的许多不同解决方案。

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

第一个选项

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

2个选项

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

关于sql - 如何在 Golang 中正确扫描 array_agg 函数的结果?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67000043/

相关文章:

sql - 在 PostgreSQL 中将分钟转换为小时

SQL Server : how to get a database name as a parameter in a stored procedure

macos - 无法在 Mac Snow Leopard 上 brew install postgresql

unit-testing - 如何编写When a function having the parameters of c *gin.Context 的测试用例

go - 运行 dep 时出错确保 : Grouped write of manifest, 锁和 vendor :无法统计 VerifyVendor 声称存在的文件

go - Revel 应用程序必须有一个 app 文件夹来组织它的代码吗?

sql - 从不同表的列更新表

c# - 带有 Entity Framework 的复合键表的 SqlException 'invalid column name'

postgresql - 使用 Postgres 创建 B+ 树并在 B+ 树的节点中添加附加字段

Python - 输入末尾的语法错误