扫描包含%字符的数据库查询的结果

时间:2017-02-02 16:09:09

标签: sql postgresql go

我正在GO代码中从postgreSQL数据库中读取数据,该数据运行顺利,直到我尝试scan包含字符%的字符串类型的列值。生成的扫描字符串将包含%!(MISSING)而不是%。

例如,扫描后字符串值this is a % test变为this is a %!t(MISSING)est

我使用常规的lib / pq驱动程序,使用database.Query(...).Scan(...)方法。

编辑:准确说明我在做什么,以及我是如何做的。

我有一个接受HTTP GET请求的函数:

func GetItems(w http.ResponseWriter, r *http.Request) {
    // Setting header content type to json
    w.Header().Set("Content-Type", "application/json")

    // Calling another function that gets the items from postgres
    // and returns them as []structs
    items := pg.SelectItems(Database)

    // Marshall the []struct into a json byte array
    jsonItems, err := json.Marshal(items)

    // return the formatted response
    // I think that's where the problem is happening
    w.WriteHeader(200)
    fmt.Fprintf(w, string(response))
}

...和一个执行查询并将结果扫描到GO结构的函数:

func SelectItems (database *sql.DB) []Items {
    var result []Items
    queryStatement := `SELECT item_id,item_value FROM items`

    // Execute the DB Query
    rows, err := database.Query(queryStatement)

    // Loop over rows
    for rows.Next() {
        item := new(Item)
        // Scan values into item's fields
        err = rows.Scan(&item.ItemID, &item.ItemValue)

        if err != nil {
            // append the item to the array to be returned
            result = append(result, item)
        }
    }
    return result
}

...其中Items定义如下:

type Item struct {
    ItemID    string    `json:"item_id"`
    ItemValue string    `json:"item_value"`
}

注意:我知道始终处理所有错误的最佳做法,并确保在数据库查询后调用defer rows.Close() ..我在我的生产代码,但为了清晰和可读性,我在问题中省略了它们。

2 个答案:

答案 0 :(得分:3)

您可能正在使用某种格式解析字符串,因此%被视为特殊字符:

a := "hi % 123\n"
fmt.Printf(a)

这会输出hi %!\n(MISSING)

a := "hi % 123\n"
fmt.Println(a)

另一方面,这会按预期输出hi % 123

在第一种情况下,我们使用格式化字符串的函数,因此将%视为特殊字符,如果要格式化包含此字符的字符串,只需将其转义:

strings.Replace(str, "%", "%%", -1)

str := "hi % 123\n"
str2 := strings.Replace(str, "%", "%%", -1)
fmt.Printf(str2)

由于我们转发%此输出hi % 123

这可能不是Scan功能的问题,这是您选择显示扫描数据的问题。

答案 1 :(得分:1)

使用fmt.Fprint代替fmt.Fprintf