Go 返回CockroachDB在事务后创建的行ID

Go 返回CockroachDB在事务后创建的行ID,go,cockroachdb,Go,Cockroachdb,在执行创建行的cockroachDB事务之后,我想将该id返回到我的应用程序 我目前正在使用数据库/sqlgolang包定义一个事务。然后,我使用crdb客户机对蟑螂数据库执行事务 除了与crdb事务本身相关的错误外,我无法从crdb事务返回任何内容。如果接口没有提供返回新行id的方法,人们如何检索最近创建的行 我有一个执行两个插入的事务。我得到这些插入的结果id,并返回带有这两个id值的响应 func myTransaction(ctx context.Context, tx *sql.Tx)

在执行创建行的cockroachDB事务之后,我想将该id返回到我的应用程序

我目前正在使用
数据库/sql
golang包定义一个事务。然后,我使用
crdb
客户机对蟑螂数据库执行事务

除了与
crdb
事务本身相关的错误外,我无法从
crdb
事务返回任何内容。如果接口没有提供返回新行id的方法,人们如何检索最近创建的行

我有一个执行两个插入的事务。我得到这些插入的结果id,并返回带有这两个id值的响应

func myTransaction(ctx context.Context, tx *sql.Tx) (MyTxnResponse, error) {
  var aResult string
  if err := tx.QueryRowContext(ctx, `INSERT INTO foo (a,b,c) VALUES (1,2,3) RETURNING foo_id`).Scan(&aResult); err != nil { ... }

  var bResult string
  if err := tx.QueryRowContext(ctx, `INSERT INTO bar (d,e,f) VALUES (4,5,6) RETURNING bar_id`).Scan(&bResult); err != nil { ... }

  return MyTxnResponse{A: aResult, B: bResult}
}
现在,我想对CRDB执行事务

var responseStruct MyTxnResponse
err := crdb.ExecuteTx(ctx.Background(), db, nil, func(tx *sql.Tx) error {
    res, err := myTransaction(ctx,tx)

    // This is what I am currently doing... it seems bad
    responseStruct.A = res.A
    responseStruct.B = res.B

    return err
}
... use responseStruct for something
我可以通过使用这个外部var解决方案并在闭包中改变它的状态来获得事务的结果,但这似乎是一个非常糟糕的模式。我肯定我错过了一些东西,如果我保持这种模式,这些东西会在我脸上爆炸


是否有一种标准的方法可以从事务中返回某些内容?

您的想法是正确的:在事务外部声明变量,并在事务闭包内部分配它们。这是从这样的闭包“返回”Go中内容的惯用方法,因为唯一的替代方法是让函数返回一个
接口{}
,这需要运行时强制转换才能有用

这里有两个快捷方式:由于
responseStruct
res
是同一类型,因此不需要列出所有字段。您可以简单地说
responseStruct=res

您甚至可以将
myTransaction
的结果直接分配给
responseStruct
,完全避免使用临时
res
。但是,在这里必须小心使用变量范围-不能使用
:=
,因为这样会在闭包内创建一个新的
responseStruct
。相反,您必须声明所有其他变量(此处,
err
),以便可以使用普通的
=
赋值:

var responseStruct MyTxnResponse
err := crdb.ExecuteTx(context.Background(), db, nil, func(tx *sql.Tx) error {
    var err error
    responseStruct, err = myTransaction(ctx, tx)
    return err
})
// use responseStruct (but only if err is nil)