我非常喜欢Go,我正在尝试使用Ben Johnson的网页创建一个结构化的应用程序。不幸的是,他的例子不是一个完整的工作应用程序。
他的网页是https://medium.com/@benbjohnson/standard-package-layout-7cdbc8391fc1
我试图使用他的方法,我不断收到“Undefined:db”错误。它没有告诉我导致错误的行,只是文件“MSSQL.go”
有人可以帮助我帮忙修复此错误吗?
使用已接受的解决方案编辑代码。
package statementprinter
type Statement struct {
CustomerId string
CustomerName string
}
type StatementService interface {
Statement(id string) (*Statement, error)
}
package main
import (
"fmt"
"log"
"github.com/ybenjolin/StatementPrinter"
"github.com/ybenjolin/StatementPrinter/mssql"
"database/sql"
_ "github.com/alexbrainman/odbc"
)
const DB_INFO = "Driver={SQL Server};Server=cdc-edb2;Database=CostarReports;Trusted_Connection=yes;"
var db *sql.DB
func init() {
var err error
db, err = sql.Open("odbc", DB_INFO)
if err != nil {
log.Fatal("Error opening database connection.\n", err.Error())
}
err = db.Ping()
if err != nil {
log.Fatal("Error pinging database server.\n", err.Error())
}
fmt.Println("Database connection established.")
}
func main () {
var err error
defer db.Close()
// Create services
// Changes required here. Was ss := &statementprinter.Stat..
ss := &mssql.StatementService{DB: db}
// Use service
var s *statementprinter.Statement
s, err = ss.Statement("101583")
if err != nil {
log.Fatal("Query failed:", err.Error())
}
fmt.Printf("Statement: %+v\n", s)
}
package mssql
import (
_ "github.com/alexbrainman/odbc"
"database/sql"
"github.com/ybenjolin/StatementPrinter"
)
// StatementService represents a MSSQL implementation of statemenetprinter.StatementService.
type StatementService struct {
DB *sql.DB
}
// Statement returns a statement for a given customer.
func (s *StatementService) Statement(customer string) (*statementprinter.Statement, error) {
var err error
var t statementprinter.Statement
// Changes required here. Was row := db.Query......
row := s.DB.QueryRow(`Select Customer, CustomerName From AccountsReceivable.rptfARStatementHeader(?)`, customer)
if row.Scan(&t.CustomerId, &t.CustomerName); err != nil {
return nil, err
}
return &t, nil
答案 0 :(得分:1)
这似乎只是一个错字。似乎有问题的一行是在方法
中 func (s *StatementService) Statement(customer string)
在mssql.go中,
row := db.QueryRow(`Select Customer, CustomerName From AccountsReceivable.rptfARStatementHeader(?)`, customer)
QueryRow
应该是db
的方法,但db
未定义。但是,在struct
type StatementService struct {
DB *sql.DB
}
有*sql.DB
个实例。您使用的方法有一个*StatementService
参数s
。所以,我的猜测是打算访问sql.DB
中的s
字段,如此
func (s *StatementService) Statement(customer string) (*statementprinter.Statement, error) {
var err error
var t statementprinter.Statement
//CHANGED LINE:
row := s.DB.QueryRow(`Select Customer, CustomerName From AccountsReceivable.rptfARStatementHeader(?)`, customer)
if row.Scan(&t.CustomerId, &t.CustomerName); err != nil {
return nil, err
}
return &t, nil
然后,在main.go中调用该方法,并传递包含数据库的StatementService
实例:
ss := &statementprinter.StatementService{DB: db}
我相信您需要将此行更改为
ss := &mssql.StatementService{DB: db}
因为实际的接口实现。您现在拥有的行将StatementService接口视为不能编译的结构。
main.go中的全局db
在应用程序的生命周期内存在。它只是一个被复制的指针供使用。