2013-12-08 22 views
5

Tôi đang cố gắng tìm ra mẫu là gì để sử dụng các tham số có tên trong gói cơ sở dữ liệu/sql được tích hợp sẵn. Tôi nhìn vào trình điều khiển oracle, nhưng nó có vẻ giống như một wrapper cho thư viện C. Có người giải quyết điều này một cách thanh lịch? Cho đến nay tôi đã chỉ giải quyết vấn đề bằng cách đặt {0}, {1} làm tham số trong các bài kiểm tra đơn vị, nhưng chắc chắn sẽ rất tuyệt khi có thể sử dụng chúng như là map[string]interface{} hoặc một cái gì đó. Có ai có một ý tưởng hoặc một thực hiện có vẻ thành ngữ?các tham số có tên trong cơ sở dữ liệu/sql và cơ sở dữ liệu/sql/driver

Để tham khảo, đây là một thử nghiệm:

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

Và những gì tôi đang làm trong Query là:

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

Các câu trả lời hiện có dường như giả định rằng bạn đang viết một ứng dụng khách, nhưng có vẻ như tôi đang viết một trình điều khiển. Có đúng không? – andybalholm

+0

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

+0

Gói cơ sở dữ liệu/sql được xây dựng xung quanh các tham số vị trí, không được đặt tên tham số. Vì vậy, bất kỳ workaround để làm cho nó sử dụng các thông số được đặt tên sẽ được unidiomatic gần như theo định nghĩa. – andybalholm

Trả lời

1

Nó sẽ có thể để tạo ra một loại map[string]interface{} mà thực hiện driver.Valuer{} serialize nó như là một []byte, và sau đó chuyển đổi nó trở lại trong trình điều khiển.

Nhưng điều đó sẽ không hiệu quả và không đơn giản. Kể từ khi trình điều khiển của bạn sau đó sẽ được sử dụng trong một cách không chuẩn, dù sao, nó có lẽ sẽ là tốt hơn để chỉ cần quên về cơ sở dữ liệu/sql và viết một gói với một giao diện hoàn toàn tùy chỉnh.

8

Tôi đang sử dụng wrapper trên cơ sở dữ liệu/sql gọi sqlx https://github.com/jmoiron/sqlx Bạn có thể kiểm tra tại đây cách anh ấy đã thực hiện.

Ví dụ về cách chọn vào một tuple

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]"} 

Ví dụ về cách chèn một tuple

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

Câu hỏi của tôi là loại ngược lại - cách đặt thông số vào làm bản đồ. –

+0

Tôi đã chỉnh sửa một câu hỏi với một chi tiết về cách chèn một tuple – Goranek

+0

Cool - Tôi vẫn hy vọng một người nào đó sẽ hiển thị một cách với gói cơ sở dữ liệu/sql gốc. –

4

Theo như tôi biết, không có tài xế natively cung cấp cho các thông số được đặt tên. Cá nhân tôi sử dụng gorp cho phép bạn để ràng buộc các truy vấn từ cấu trúc hoặc bản đồ:

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

hoặc

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

Cảm ơn bạn đã đề cập - điều đó khá mượt mà. Tôi hy vọng cho một cách với gói cơ sở dữ liệu/sql bản địa. –

+3

Bạn không thể làm điều đó với cơ sở dữ liệu gốc/sql – Goranek

Các vấn đề liên quan