2017-02-25 59 views
0

我有2層結構一個公司的其他服務。他們有一個has-many關係公司來服務。我正在嘗試編寫一個SQL查詢,它將在一個查詢中插入連接到該公司的公司和多個服務。PostgreSQL的插入多個表和行

RAW SQL:

WITH company AS (INSERT INTO companies(id, name) VALUES('1', 'acme') RETURNING id) 
INSERT INTO services(id, company_id, name) VALUES 
('1', (select company.id from company), 'cool service'), 
('2', (select company.id from company), 'cooler service'); 

我試圖模仿這種使用Go的SQL包。這是我嘗試迄今:我已經添加在頂部的結構只是爲了清楚起見

c := &Company{ 
    ID: uuid.NewV4().String(), 
    Name: "test comp", 
} 

s := []*Service{ 
    &Service{ 
     ID: uuid.NewV4().String(), 
     CompanyID: c.ID, 
     Name: "test svc", 
    }, 
} 

c.Service = s 

values := []interface{}{ 
    c.ID, 
    c.Name, 
} 

q := ` 
    WITH company as (INSERT INTO companies(id, name) VALUES ($1, $2)) INSERT INTO services(id, company_id, name) VALUES 
` 

for _, row := range c.Services { 
    q += "($1, $2, $3)," 
    values = append(values, row.ID, row.CompanyID) 
} 

q = strings.TrimSuffix(q, ",") 

stmt, err := s.DB.Prepare(q) 
if err != nil { 
    return err 
} 

if _, err := stmt.Exec(values...); err != nil { 
    return err 
} 

我不知道怎麼回事,去了解這一點,但用這種方法我得到這個錯誤:

ERROR #08P01 bind message supplies 5 parameters, but prepared statement "1" requires 3 

這是有道理的,我傳遞5個參數準備語句時,「1」,我猜是第二個只需要3。但我怎麼能不必它分成超過1執行我的查詢給exec查詢?

回答

0

正如你的錯誤消息指出,SQL語句只使用3個綁定變量:

WITH company as (INSERT INTO companies(id, name) VALUES ($1, $2)) INSERT INTO services(id, company_id, name) VALUES 

和:

q += "($1, $2, $3)," 

你簡單地重複$1$2,並且$3爲每你的行。因此,您構建的查詢將如下所示:

WITH company as (INSERT INTO companies(id, name) VALUES ($1, $2)) INSERT INTO services(id, company_id, name) VALUES 
($1, $2, $3),($1, $2, $3),($1, $2, $3),($1, $2, $3), 

顯然,這不是您想要的。您需要通過循環每次迭代增加綁定變量編號。

我的做法可能會是這樣的:

var i int = 3 
for _, row := range c.Services { 
    q += fmt.Sprintf("($%d, $%d, $%d),", i, i+1, i+2) 
    values = append(values, row.ID, row.CompanyID) 
    i += 3 
} 
+0

我不會每一次迭代來遞增的循環便對所使用的每個結合可變。 – Rodrigo

+0

@Rodrigo:嗯,我的方法是通過3每次通過循環遞增的變量。如果你喜歡三個單獨的迭代,那也可以。拿你的選擇。 – Flimzy

+0

我會標記你的答案是正確的,因爲你回答我的問題。這整個方法雖然感覺很臭。有沒有更好的方法來解決這個問題?像整體不只是試圖修復我的哈克方法? – Rodrigo