2017-04-12 264 views
1

我正在编写一个函数来执行对数据库的select查询。函数Go执行数据库选择查询并返回json输出

输入:字符串例如“Select some id,name,age from sometable” 此查询每次更改。

输出:以json格式输出选择查询。

示例预期输出: {“Data”:[{“id”:1,“name”:“abc”,“age”:40},{“id”:2,“name” XYZ”, “年龄”:45}]}

样品的实际输出: { “数据”:[[1, “ABC”,40],[2, “XYZ”,45]]}

而不是ie列名:值,我只得到值。 如何获得预期的输出?

func executeSQL(queryStr string) []byte { 
connString := createConnectString() 
conn, err := sql.Open("mssql", connString) 
if err != nil { 
    log.Fatal("Error while opening database connection:", err.Error()) 
} 
defer conn.Close() 

rows, err := conn.Query(queryStr) 
if err != nil { 
    log.Fatal("Query failed:", err.Error()) 
} 
defer rows.Close() 

columns, _ := rows.Columns() 
count := len(columns) 

var v struct { 
    Data []interface{} // `json:"data"` 
} 

for rows.Next() { 
    values := make([]interface{}, count) 
    valuePtrs := make([]interface{}, count) 
    for i, _ := range columns { 
     valuePtrs[i] = &values[i] 
    } 
    if err := rows.Scan(valuePtrs...); err != nil { 
     log.Fatal(err) 
    } 
    v.Data = append(v.Data, values) 
} 
jsonMsg, err := json.Marshal(v) 
return jsonMsg 
} 

回答

0

得到了解决方案。这是我做的。

func executeSQL(queryStr string) []byte { 
connString := createConnectString() 
conn, err := sql.Open("mssql", connString) 
if err != nil { 
    log.Fatal("Error while opening database connection:", err.Error()) 
} 
defer conn.Close() 

rows, err := conn.Query(queryStr) 
if err != nil { 
    log.Fatal("Query failed:", err.Error()) 
} 
defer rows.Close() 

columns, _ := rows.Columns() 
count := len(columns) 

var v struct { 
    Data []interface{} // `json:"data"` 
} 

for rows.Next() { 
    values := make([]interface{}, count) 
    valuePtrs := make([]interface{}, count) 
    for i, _ := range columns { 
     valuePtrs[i] = &values[i] 
    } 
    if err := rows.Scan(valuePtrs...); err != nil { 
     log.Fatal(err) 
    } 

//Created a map to handle the issue 
    var m map[string]interface{} 
    m = make(map[string]interface{}) 
    for i := range columns { 
     m[columns[i]] = values[i] 
    } 
    v.Data = append(v.Data, m) 
} 
jsonMsg, err := json.Marshal(v) 
return jsonMsg 
} 

让我知道是否存在更好的解决方案。

0

这段代码是直接从我的“沙箱”为MSSQL(使用denisenkom /复mssqldb和jmoiron/SQLX) - 我认为它有助于展示不同的方法和可能QueryIntoMap就是你要找的人:

package main 

import (
    "log" 
    "fmt" 
    _ "github.com/denisenkom/go-mssqldb" 
    "time" 
    "github.com/jmoiron/sqlx" 
    "encoding/json" 
) 

type Customer struct { 
    CustomerId string `db:"customerID" json:"customer_id"` 
    Company interface{} `db:"companyName" json:"company_name"` 
    Contact interface{} `db:"contactName" json:"contact_name"` 
} 

func main() { 
    connection := "server=192.168.55.3\\SqlExpress2012;database=Northwind;user id=me;Password=secret" 

    //QueryIntoMap(connection) 
    ScanIntoSlice(connection) 
} 

func QueryIntoMap(connection string) { 

    fmt.Println("QueryIntoMap sample") 
    fmt.Println("--------------------") 

    sel := `select customerId, companyName, contactName 
    from customers 
    where customerId = :id` 

    values := make(map[string]interface{}) 


    db, err := sqlx.Open("mssql", connection) 
    //db.MapperFunc(strings.ToUpper) 
    e(err) 
    defer db.Close() 
    tx := db.MustBegin() 
    stmt, err := tx.PrepareNamed(sel) 
    e(err) 

    stmt.QueryRowx(map[string]interface{}{"id": "BONAP"}).MapScan(values) 
    tx.Commit() 

    for k, v := range values { 
     fmt.Printf("%s %v\n", k, v) 
    } 

    js, err := json.Marshal(values) 
    if err != nil { 
     fmt.Println(err) 
    } 
    fmt.Println(string(js)) 
    fmt.Println("--------------------") 
} 

func ScanIntoStruct(connection string) { 
    fmt.Println("Scan into struct sample") 
    fmt.Println("--------------------") 

    db, err := sqlx.Open("mssql", connection) 
    e(err) 
    defer db.Close() 

    customer := Customer{} 

    rows, err := db.Queryx(`select customerID, companyName, contactName 
    from Customers`) 

    for rows.Next() { 
     err = rows.StructScan(&customer) 
     if err != nil { 
      log.Fatalln(err) 
     } 
     //fmt.Printf("%#v\n", user) 
     fmt.Printf("%-10s %-50v %-50v\n", 
      customer.CustomerId, 
      customer.Company, 
      customer.Contact) 
     js, err := json.Marshal(customer) 
     e(err) 
     fmt.Println(string(js)) 
    } 
    fmt.Println("--------------------") 

} 

func ScanIntoSlice(connection string) { 
    fmt.Println("Scan into slice sample") 
    fmt.Println("--------------------") 
    start := time.Now() 
    db, err := sqlx.Open("mssql", connection) 
    e(err) 
    defer db.Close() 

    customers := []Customer{} 

    err = db.Select(&customers, `select customerID, companyName, contactName from customers`) 
    e(err) 

    for i, customer := range customers { 
     fmt.Printf("%3d. %-10s %-50v %-50v\n", 
      i, 
      customer.CustomerId, 
      customer.Company, 
      customer.Contact) 
    } 
    js, err := json.Marshal(customers) 
    e(err) 

    fmt.Println(string(js)) 

    fmt.Printf("%s", time.Since(start)) 
    fmt.Println("--------------------") 

} 

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