2017-02-02 52 views
3

我正在從我的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 
} 

...其中物品被定義爲這樣:

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

注:我知道最好的做法是始終處理所有錯誤,並確保在DB查詢後調用defer rows.Close() ..並且我在生產代碼中執行操作,但爲了清晰和易讀,我忽略了這些錯誤。

+2

要提高你的問題,請添加一些代碼的實際行代表的問題。我個人很難想象失蹤的細節。 – miltonb

+0

@miltonb你說得對。我在問題中加入了一些真正的代碼,使其更清晰。請注意,要測試該代碼,您需要運行一個sql db。在代碼中,'Database'對象是該數據庫的連接。 – Frax

回答

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

這可能不是一個與問題0功能,這是您如何選擇顯示掃描數據的問題。

+0

感謝您的回答。你說得對,這個問題不在'Scan'功能中。這是格式化。我已將代碼添加到顯示它發生的問題。每次處理程序被調用時(這是很多),都不會執行'strings.Replace',這會給我的服務器增加很多開銷? – Frax

+1

沒關係:D解決方案很簡單。 如果我們調用'fmt.Fprint'而不是'fmt.Fprintf',它會起作用 感謝您指出 – Frax

+0

除非您有很好的理由,否則不應該使用數據庫中的值作爲printf的第一個參數。相反,使用'%v'格式化字符串,或者只使用print或println。例如: fmt.Printf('%v',a) 有沒有必要訴諸逃脫。 – user1431317

1

使用fmt.Fprint代替fmt.Fprintf

+0

是的。就是這樣 – Frax