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

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

Scanning results from DB query that contain a % character

问题

我正在从我的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) {
    // 设置响应头的内容类型为json
    w.Header().Set("Content-Type", "application/json")
    
    // 调用另一个从postgres获取项目并将其作为[]struct返回的函数
    items := pg.SelectItems(Database)

    // 将[]struct编组为json字节数组
    jsonItems, err := json.Marshal(items)
    
    // 返回格式化的响应
    // 我认为问题就发生在这里
    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`

    // 执行数据库查询
    rows, err := database.Query(queryStatement)

    // 遍历行
    for rows.Next() {
        item := new(Item)
        // 将值扫描到item的字段中
        err = rows.Scan(&item.ItemID, &item.ItemValue)

        if err != nil {
            // 将项目附加到要返回的数组中
            result = append(result, item)
        }
    }
    return result
}

其中Items定义如下:

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

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

英文:

I'm reading data from a postgreSQL DB in my GO code, which works smoothly until I try to scan column values of type string containing the character %. The resulting scanned string will contain %!(MISSING) instead of the %.

For example, the string value this is a % test becomes this is a %!t(MISSING)est after being scanned.

I'm using the regular lib/pq driver for go, using database.Query(...).Scan(...) methods.

EDIT: To clarify exactly what I'm doing and how I'm doing it.

I have a function that accepts an HTTP GET request:

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))
}

... and a function that does the querying and scans the results into GO structs:

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
}

... where Items is defined as such:

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

Note: I know that it's best practice to always handle all the errors, and to be sure to call defer rows.Close() after the DB query.. and I do in my production code, but i omitted them from the question just for the sake of clarity and readability.

答案1

得分: 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 函数的问题,而是你选择如何显示扫描到的数据的问题。

英文:

You are probably parsing the string using some kind of formatting and therefore the % is being considered as a special character:

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

This outputs hi %!\n(MISSING)

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

This on the other hand outputs hi % 123 as expected.

In the first case we are using a function that formats the string, and therefore considers the % a special character, if you want to format a string that contains this character, just escape it:

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

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

Since we escaped the % this outputs hi % 123

This is probably not a problem with the Scan function, it's a problem of how you are choosing to display the scanned data.

答案2

得分: 1

使用fmt.Fprint而不是fmt.Fprintf

英文:

use fmt.Fprint instead of fmt.Fprintf

huangapple
  • 本文由 发表于 2017年2月3日 00:09:09
  • 转载请务必保留本文链接:https://go.coder-hub.com/42006995.html
匿名

发表评论

匿名网友

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

确定