事务中的游标在 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")
我有问题。出于某种原因,这完全超出了我的范围,当我 运行 它在 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")