2013-12-08 59 views
5

我想知道在go的內置數據庫/ sql包中使用命名參數的模式。我查看了oracle驅動程序,但它看起來只是C庫的一個包裝。有人以優雅的方式解決了這個問題嗎?到目前爲止,我剛剛通過在單元測試中將{0},{1}作爲參數解決了這個問題,但它肯定能很好地將它們用作map[string]interface{}或其他東西。有沒有人有一個想法或實施似乎慣用?在數據庫中的命名參數/ sql和數據庫/ sql /驅動程序

供參考,在這裏是一個測試:

db := testConn() 
stmt, err := db.Prepare("return {0} as int1, {1} as int2") 
if err != nil { 
    t.Fatal(err) 
} 
rows, err := stmt.Query(123, 456) 
if err != nil { 
    t.Fatal(err) 
} 
rows.Next() 

var test int 
var test2 int 
err = rows.Scan(&test, &test2) 
if err != nil { 
    t.Fatal(err) 
} 
if test != 123 { 
    t.Fatal("test != 123;", test) 
} 
if test2 != 456 { 
    t.Fatal("test2 != 456;", test2) 
} 

而且我在做什麼在Query是:

func (stmt *cypherStmt) Query(args []driver.Value) (driver.Rows, error) { 
    cyphReq := cypherRequest{ 
     Query: stmt.query, 
    } 
    if len(args) > 0 { 
     cyphReq.Params = make(map[string]interface{}) 
    } 
    for idx, e := range args { 
     cyphReq.Params[strconv.Itoa(idx)] = e 
    } 
... 
+0

現有的答案似乎假設你正在寫一個客戶端,但它看起來像我正在寫一個驅動程序。是對的嗎? – andybalholm

+0

Yep:https://github.com/wfreeman/cq –

+0

數據庫/ sql包是圍繞位置參數構建的,而不是命名參數。因此,任何使其使用命名參數的解決方法幾乎都是單一的。 – andybalholm

回答

1

這將有可能創建一個map[string]interface{}類型實現driver.Valuer{}序列化它作爲一個[]byte,和然後在驅動程序中將其轉換回來。

但是,這將是低效率和unidiomatic。由於您的驅動程序會以非標準方式使用,因此最好忘記數據庫/ sql並使用完全自定義的界面編寫程序包。

8

我使用的數據庫/ SQL的頂部封裝稱爲SQLX https://github.com/jmoiron/sqlx 你可以在這裏檢查他是如何做到的。

如何選擇到一個元組如何插入一個元組

dude := Person{ 
    FirstName:"Jason", 
    LastName:"Moiron", 
    Email:"[email protected]" 
} 
_, err = db.NamedExec(`INSERT INTO person (first_name,last_name,email) VALUES (:first,:last,:email)`, dude) 
+0

我的問題是相反的 - 如何將參數放入地圖中。 –

+0

我已經編輯了一個關於如何插入元組的詳細問題 – Goranek

+0

酷 - 我仍然希望有人用本地數據庫/ sql包顯示出一種方式。 –

4

據我所知,沒有驅動程序本身提供了命名參數

type Person struct { 
    FirstName string `db:"first_name"` 
    LastName string `db:"last_name"` 
    Email  string 
} 
jason = Person{} 
err = db.Get(&jason, "SELECT * FROM person WHERE first_name=$1", "Jason") 
fmt.Printf("%#v\n", jason) 
// Person{FirstName:"Jason", LastName:"Moiron", Email:"[email protected]"} 

示例例。我個人使用gorp它允許你綁定從結構或地圖查詢:

_, err = dbm.Select(&users, 
    "select * from PersistentUser where mykey = :Key", 
    map[string]interface{}{ 
     "Key": 43, 
    } 
) 

_, err = dbm.Select(&users, 
    "select * from PersistentUser where mykey = :Key", 
    User{Key: 43}, 
) 
+0

感謝提及 - 這非常漂亮。我希望與本地數據庫/ SQL包的方式。 –

+3

你不能用本地數據庫/ sql來完成它 – Goranek