【问题标题】:Does the error returned by db.Exec(...) have a code?db.Exec(...) 返回的错误是否有代码?
【发布时间】:2016-09-30 08:12:11
【问题描述】:

我正在尝试使用 postgres 驱动程序 (lib/pq) 删除数据库,方法是:

db.Exec("DROP DATABASE dbName;")

但我想根据收到的错误是奇怪的东西还是“数据库不存在”错误来做一个不同的条件。

是否有一个常量变量或可以用来检查返回的错误是否是“数据库不存在”错误消息,或者我必须自己手动解析错误字符串?

我试图查看文档,但找不到“数据库不存在”的任何内容。但是我确实找到了this list

也许它适合其他一些错误代码?此外,我不太确定通过 Postgres 驱动程序获取和比较错误代码的语义正确方法。我想我应该这样做:

if err.ErrorCode != "xxx"

【问题讨论】:

  • 有什么理由不想在尝试删除数据库之前检查它是否存在?
  • 这也是一个可以接受的解决方案,我不知道我能做到这一点 :-) 有相关查询吗?
  • 当然可以。查看 pg_database 对象。 SELECT TRUE AS result FROM pg_database WHERE datname='abc';
  • 另外,如果你想避免整个问题,只需:DROP DATABASE IF EXISTS dbName;
  • 太棒了,谢谢,太完美了。

标签: database postgresql go


【解决方案1】:

lib/pq 包可能返回 *pq.Error 类型的错误,这是一个结构。如果是这样,您可以使用它的所有字段来检查错误的详细信息。

可以这样做:

if err, ok := err.(*pq.Error); ok {
    // Here err is of type *pq.Error, you may inspect all its fields, e.g.:
    fmt.Println("pq error:", err.Code.Name())
}

pq.Error 有以下字段:

type Error struct {
    Severity         string
    Code             ErrorCode
    Message          string
    Detail           string
    Hint             string
    Position         string
    InternalPosition string
    InternalQuery    string
    Where            string
    Schema           string
    Table            string
    Column           string
    DataTypeName     string
    Constraint       string
    File             string
    Line             string
    Routine          string
}

这些字段的含义和可能的值是 Postres 特定的,完整列表可以在这里找到:Error and Notice Message Fields

【讨论】:

  • 谢谢,这很有帮助,但是我将使用上面提到的 Nicarus(删除数据库,如果存在 dbName;)。如果有人好奇返回的错误消息是什么,那就是:pq.Error{Severity:"ERROR", Code:"3D000", Message:"database \"dbname\" doesn't exist", Detail:"" , Hint:"", Position:"", InternalPosition:"", InternalQuery:"", Where:"", Schema:"", Table:"", Column:"", DataTypeName:"", Constraint:"" ,文件:“dbcommands.c”,行:“799”,例程:“dropdb”} 无法执行设置:pq:数据库“dbname”不存在
  • 这里是所有错误代码/名称的列表postgresql.org/docs/9.3/errcodes-appendix.html
  • 使用错误。作为play.golang.org/p/_SDyuC3ERAX
【解决方案2】:

你可以使用这个:https://github.com/omeid/pgerror

它有很多针对各种 postgres 错误的映射。

使用该软件包,您可以执行以下操作(摘自自述文件):

// example use:
_, err = stmt.Exec(SomeInsertStateMent, params...)
if err != nil {
  if e := pgerror.UniqueViolation(err); e != nil {
  // you can use e here to check the fields et al
    return SomeThingAlreadyExists
  }

  return err // other cases.
}

【讨论】:

    【解决方案3】:

    这个包有所有的 PG 错误常量: https://github.com/jackc/pgerrcode

    只需导入即可:

    import "github.com/jackc/pgerrcode"
    
    // ...
    
    if err, ok := err.(*pq.Error); ok {
      if err.Code == pgerrcode.UniqueViolation {
        return fmt.Errorf("unique field violation on column %s", err.Column)
      }
    }
    

    该软件包也属于 2 或 3 个最流行的 Go PostgreSQL 驱动程序之一,称为“pgx”,因此它应该足够可靠。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-03-24
      • 2012-06-28
      • 2023-03-25
      • 1970-01-01
      • 2020-09-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多