事务中的游标在 go 和 psql 之间的行为不同

Cursor within transaction behaves differently between go and psql

我有问题。出于某种原因,这完全超出了我的范围,当我 运行 它在 psql (它工作的地方)时我创建的光标表现不同,而不是当我 运行 它通过我的 go 代码。

我接受了一部分名称并将它们作为 pq.Array 传递给事务执行函数调用。从我读过的内容来看,这应该可以解决将任意计数的多个值传递给查询的问题。但显然不是..我不知道这是否发生,因为它在事务中的游标内,这是我唯一能想到的了。

我们的想法是查询 tenants 的所有 id 的名字 NOT 出现在这个列表中,因此使用 <> 运算符。这些名称在数据库中是唯一的。

当我 运行 通过 go 代码时,我最终得到了所有 id,而不仅仅是那些没有出现在列表中的。

我在这里包含了这个函数,事务在一个调用函数中启动并传递给这个函数。请告知是否需要包含其他内容以进一步说明!

我是不是漏掉了什么?

func DeleteTenants(orphanTenants []string, tx *sql.Tx) error {
    query := `
    DECLARE tenants_cursor CURSOR FOR
    SELECT id FROM tenants
    WHERE name <> ALL(ARRAY[])
    FOR UPDATE
    `
    if _, err := tx.Exec(query, pq.Array(orphanTenants)); err != nil {
        log.Println("DeleteTenants: Error creating Tenant cursor")
        return err
    }
    defer tx.Exec("CLOSE tenants_cursor")
    for {
        id := -1
        if err := tx.QueryRow("FETCH NEXT FROM tenants_cursor").Scan(&id); err != nil {
            if err == sql.ErrNoRows {
                log.Println("No rows found in tenants_cursor")
                break
            }
            log.Println("DeleteTenants: Error when fetching next row from Tenant cursor")
            return err
        }
        log.Println("Tenant ID to be deleted:", id)
        if err := deleteTenant(id, tx); err != nil {
            log.Println("DeleteTenants: Error returned from deleteTenant")
        }
    }
    return nil
}

没关系..想通了。将 pq.Array 传递给查询时,我不需要在查询中包含 ARRAY 符号。

这很尴尬!在几分钟内回答我自己的问题。

所以查询应该是这样的:

query := `
DECLARE tenants_cursor CURSOR FOR
SELECT id FROM tenants
WHERE name <> ALL()
FOR UPDATE
`
if _, err := tx.Exec(query, pq.Array(orphanTenants)); err != nil {
    log.Println("DeleteTenants: Error creating Tenant cursor")
    return err
}
defer tx.Exec("CLOSE tenants_cursor")