首页 > 解决方案 > 当 args 数很大时,数据库/sql 无法选择查询

问题描述

你使用的是什么版本的 Go ( go version)?

$ go version
go version go1.14 linux/amd64

这个问题会在最新版本中重现吗?

是的

您使用的是什么操作系统和处理器架构(go env)?

$ go env
GO111MODULE="on"
GOARCH="amd64"
GOBIN="/home/zabludovsky/go/bin"
GOCACHE="/home/zabludovsky/.cache/go-build"
GOENV="/home/zabludovsky/.config/go/env"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOINSECURE=""
GONOPROXY="gl.rosst.ru/backend/*"
GONOSUMDB="gl.rosst.ru/backend/*"
GOOS="linux"
GOPATH="/home/zabludovsky/go"
GOPRIVATE="gl.rosst.ru/backend/*"
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/usr/local/go"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/usr/local/go/pkg/tool/linux_amd64"
GCCGO="gccgo"
AR="ar"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD="/home/zabludovsky/go/src/awesomeProject1/go.mod"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build174435943=/tmp/go-build -gno-record-gcc-switches"

你做了什么?

package main

import (
    "database/sql"
    "fmt"
    "strconv"

    _ "github.com/lib/pq"
)

func main()  {
    err := selectFromDb(65536)
    if err != nil{
        panic(err)
    }

    println("where was no errors!")
}

func selectFromDb(argsNumber int) (err error){
    //open connect to postgres database, put your database connection string below, instead of second argument
    db, err := sql.Open("postgres", "postgres://mayber:password@localhost:5432/test?sslmode=disable")
    if err != nil {
        return
    }

    //preparing query, you can call this func with argsNumber = 10(or some not huge number)
    //to check that it is working correct
    var args []interface{}
    query := "SELECT id FROM test_tbl WHERE id IN ("
    for i := 0; i < argsNumber; i++ {
        args = append(args, strconv.Itoa(i))
        query = fmt.Sprintf("%s $%d, ", query, i+1)
        fmt.Printf("preparing query, %d/%d \n", i, argsNumber)
    }
    query = fmt.Sprintf("%s);", query[:len(query)-2])
    fmt.Println("preparing finished:")

    //uncomment string bellow to see result query and check it
    //fmt.Println(query)


    //preparing query
    stmt, err := db.Prepare(query)
    if err != nil {
        return
    }

    //selecting
    rows, err := stmt.Query(args...)
    if err != nil{
        return
    }

    //closing db connection
    err = rows.Close()
    if err != nil{
        return
    }

    return
}

你期待看到什么?

preparing query, 0/65536
preparing query, 1/65536
...
preparing query, 60535/65536
preparing finished:
where was no errors!

你看到了什么?

preparing finished:
panic: sql: expected 0 arguments, got 65536

更多详情https://github.com/GlebZabl/golang_postgres_bug

标签: postgresqlgoojdbc

解决方案


推荐阅读