共享数据库全局处理程序的问题

huangapple go评论81阅读模式
英文:

Troubles sharing the db global handler

问题

我的代码如下:

package main

import (
	"database/sql"
	"fmt"
	_ "github.com/mattn/go-sqlite3"
	"log"
)

var db *sql.DB

func main() {
	fmt.Println("Starting test ...")

	db, err := sql.Open("sqlite3", "./data.db")
	checkErr(err)

	err = db.Ping()
	checkErr(err)

	fmt.Println(getNames())
}

func checkErr(err error) {
	if err != nil {
		log.Fatal(err)
	}
}

func getNames() []string {
	query := `select name from places`
	rows, err := db.Query(query)
	checkErr(err)
	defer rows.Close()

	var names []string
	for rows.Next() {
		var name string
		rows.Scan(&name)
		names = append(names, name)
	}

	return names
}

我遇到了这个问题,但是这种方法对我不起作用。我正在使用sqlite3进行存储。
我的目标很简单,就是在所有函数之间共享数据库处理程序。
当我构建和运行时,我得到以下错误。

Starting test ...
panic: runtime error: invalid memory address or nil pointer dereference
[signal 0xb code=0x1 addr=0x0 pc=0x411fc6e]

goroutine 1 [running]:
database/sql.(*DB).conn(0x0, 0x0, 0x0, 0x0)
    /usr/local/Cellar/go/1.4.2/libexec/src/database/sql/sql.go:634   +0x7ae
database/sql.(*DB).query(0x0, 0x421cb10, 0x17, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0)
    /usr/local/Cellar/go/1.4.2/libexec/src/database/sql/sql.go:933 +0x43
database/sql.(*DB).Query(0x0, 0x421cb10, 0x17, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0)
    /usr/local/Cellar/go/1.4.2/libexec/src/database/sql/sql.go:924 +0xa6
main.getNames(0x0, 0x0, 0x0)
    /Users/kdys/Code/go/src/test/main.go:32 +0x94
main.main()
    /Users/kdys/Code/go/src/test/main.go:21 +0x188

goroutine 5 [chan receive]:
database/sql.(*DB).connectionOpener(0xc20802e000)
    /usr/local/Cellar/go/1.4.2/libexec/src/database/sql/sql.go:589 +0x4c
created by database/sql.Open
    /usr/local/Cellar/go/1.4.2/libexec/src/database/sql/sql.go:452 +0x31c

goroutine 17 [syscall, locked to thread]:
runtime.goexit()
    /usr/local/Cellar/go/1.4.2/libexec/src/runtime/asm_amd64.s:2232 +0x1

我在这里做错了什么?

英文:

My code is the following:

package main

import (
  "database/sql"
  "fmt"
  _ "github.com/mattn/go-sqlite3"
  "log"
)

var db *sql.DB

func main() {
  fmt.Println("Starting test ...")

  db, err := sql.Open("sqlite3", "./data.db")
  checkErr(err)

  err = db.Ping()
  checkErr(err)

  fmt.Println(getNames())
}

func checkErr(err error) {
  if err != nil {
	log.Fatal(err)
  }
}

func getNames() []string {
  query := `select name from places`
  rows, err := db.Query(query)
  checkErr(err)
  defer rows.Close()

  var names []string
  for rows.Next() {
	var name string
	rows.Scan(&name)
	names = append(names, name)
  }

  return names
}

I came across this question but the approach don't work for me. I'm using sqlite3 for storage.
My goal is simple. Share the db handler across all the functions.
I'm getting the following error when build and run.

Starting test ...
panic: runtime error: invalid memory address or nil pointer dereference
[signal 0xb code=0x1 addr=0x0 pc=0x411fc6e]

goroutine 1 [running]:
database/sql.(*DB).conn(0x0, 0x0, 0x0, 0x0)
    /usr/local/Cellar/go/1.4.2/libexec/src/database/sql/sql.go:634   +0x7ae
database/sql.(*DB).query(0x0, 0x421cb10, 0x17, 0x0, 0x0, 0x0, 0x1, 0x0, 0x0)
    /usr/local/Cellar/go/1.4.2/libexec/src/database/sql/sql.go:933 +0x43
database/sql.(*DB).Query(0x0, 0x421cb10, 0x17, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0)
    /usr/local/Cellar/go/1.4.2/libexec/src/database/sql/sql.go:924 +0xa6
main.getNames(0x0, 0x0, 0x0)
    /Users/kdys/Code/go/src/test/main.go:32 +0x94
main.main()
    /Users/kdys/Code/go/src/test/main.go:21 +0x188

goroutine 5 [chan receive]:
database/sql.(*DB).connectionOpener(0xc20802e000)
    /usr/local/Cellar/go/1.4.2/libexec/src/database/sql/sql.go:589 +0x4c
created by database/sql.Open
    /usr/local/Cellar/go/1.4.2/libexec/src/database/sql/sql.go:452 +0x31c

goroutine 17 [syscall, locked to thread]:
runtime.goexit()
    /usr/local/Cellar/go/1.4.2/libexec/src/runtime/asm_amd64.s:2232 +0x1

What i'm doing wrong here ?

答案1

得分: 1

你在main函数中创建了一个名为db的局部变量。当你调用getNames函数时,它使用的是全局变量db,而该变量仍然是空值。

请使用以下代码:

var err error
db, err = sql.Open("sqlite3", "./data.db")
英文:

You're creatng a local db variable within main. When you call getNames, it is using the global db, which is still nil.

use

var err error
db, err = sql.Open("sqlite3", "./data.db")

huangapple
  • 本文由 发表于 2015年3月31日 03:20:55
  • 转载请务必保留本文链接:https://go.coder-hub.com/29354470.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定