Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/joomla/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Postgresql 如何使用lib/pq驱动程序插入数字字段类型?_Postgresql_Go_Pq - Fatal编程技术网

Postgresql 如何使用lib/pq驱动程序插入数字字段类型?

Postgresql 如何使用lib/pq驱动程序插入数字字段类型?,postgresql,go,pq,Postgresql,Go,Pq,我有一个表,其中有一个字段存储了一个非常大的数字(math.big,比uint64大)。我将其存储为十进制类型: difficulty NUMERIC NOT NULL, 那么,如何使用PQ库(github.com/lib/PQ)从Go代码插入此字段 此代码不起作用: me@desk:~/src/github.com/myapp/misc$ cat insertbig.go package main import ( "database/sql" _

我有一个表,其中有一个字段存储了一个非常大的数字(math.big,比uint64大)。我将其存储为十进制类型:

difficulty          NUMERIC     NOT NULL,
那么,如何使用
PQ
库(
github.com/lib/PQ
)从
Go
代码插入此字段

此代码不起作用:

me@desk:~/src/github.com/myapp/misc$ cat insertbig.go
package main

import (
    "database/sql"
    _ "github.com/lib/pq"
    "os"
    "log"
    "math/big"
)
func main() {
    var err error
    var db *sql.DB
    std_out:=log.New(os.Stdout,"",0)

    conn_str:="user='testuser' dbname='testdb' password='testpasswd'";
    db,err=sql.Open("postgres",conn_str);
    if (err!=nil) {
        log.Fatal(err);
    }
    _,err=db.Exec("CREATE TABLE bigtable(difficulty NUMERIC)");

    difficulty:=big.NewInt(0);
    difficulty.SetString("1111111111111111111111111111111111111111111111111111111111111111111111",10);
    _,err=db.Exec("INSERT INTO bigtable(difficulty) VALUES(?)",difficulty);
    if (err!=nil) {
        log.Fatal(err);
    } else {
        std_out.Println("record was inserted");
    }
}

me@desk:~/src/github.com/myapp/misc$ 
它给了我这个错误:

2018/02/05 17:00:25 sql: converting argument $1 type: unsupported type big.Int, a struct

首先,您应该在PostgreSQL中使用数字占位符(
$1
$2
,…),因为这是它本机使用的。至于将bignum放入数据库中的
numeric
列,快速浏览文档和源代码表明,最好使用字符串(PostgreSQL将其视为“未知”类型的值),并让PostgreSQL根据列的(已知)类型对其进行解析和强制转换

比如说:

difficulty := "1111111111111111111111111111111111111111111111111111111111111111111111"
_, err = db.Exec("INSERT INTO bigtable (difficulty) VALUES ($1)", difficulty)
类似的方法也适用于驱动程序本机无法理解的任何其他PostgreSQL类型;始终会有一个字符串表示,您可以使用它来启动


您还可以
键入SQLBigInt big.Int
并从
数据库/sql/driver
实现
驱动程序.Valuer
接口:

type SQLBigInt big.Int
func (i *SQLBigInt) Value() (driver.Value, error) {
    return (*big.Int)(i).String(), nil
}

// Or
type SQLBigInt struct {
    big.Int
}
func (i *SQLBigInt) Value() (driver.Value, error) {
    return i.String(), nil
}

然后可能从
“数据库/sql”
读取
sql.Scanner
,但这可能会变得难看,可能不值得付出努力,因为您一直都在包装和解包。

您可以实现valuer和Scanner接口

//BigInt big.Int alias
   type BigInt struct {
      big.Int
   }

// Value implements the Valuer interface for BigInt
func (b *BigInt) Value() (driver.Value, error) {
   if b != nil {
      return b.String(), nil
   }
   return nil, nil
}

// Scan implements the Scanner interface for BigInt
func (b *BigInt) Scan(value interface{}) error {
    var i sql.NullString
    if err := i.Scan(value); err != nil {
        return err
    }
    if _, ok := b.SetString(i.String, 10); ok {
       return nil
    }
    return fmt.Errorf("Could not scan type %T into BigInt", value)
}