I have a code which does unit testing, where I prepare a database for the tests (I do not use sql-go-mock), so I want to insert returning id with a simple sql INSERT INTO, but for some reason pgx errors with panic: ERROR: syntax error at or near ")" (SQLSTATE 42601)
, but the query does execute in a goland console.
What is wrong here? By the way, the code does not even work without RETURNING id.
Query built by the builder: INSERT INTO collections (name) VALUES (?),(?) RETURNING id
Simplified example below
package main
import (
"context"
"fmt"
sq "github.com/Masterminds/squirrel"
"github.com/jackc/pgx/v5/pgxpool"
)
func main() {
dsn := "postgresql://user:password@localhost:5432/merge?sslmode=disable"
ctx := context.Background()
pool, err := pgxpool.New(ctx, dsn)
if err != nil {
panic(err)
}
type a struct {
ID uint
Name string
}
as := []a{{
Name: "asd",
}, {
Name: "zxc",
}}
stmt := sq.Insert("collections").Columns("name").
Values(as[0].Name).Values(as[1].Name).
Suffix("RETURNING id")
query, args, err := stmt.ToSql()
if err != nil {
panic(err)
}
err = pool.QueryRow(ctx, query, args).Scan(&as)
if err != nil {
panic(err)
}
fmt.Printf("%v", as)
}
The ?
is not a valid parameter placeholder in PostgreSQL, instead PostgreSQL uses $N
where N
is the position of the argument, e.g. $1
for the first argument, $2
for the second, etc.
psql := sq.StatementBuilder.PlaceholderFormat(sq.Dollar)
, and then you should be able use the returned psql
builder to build your queries with the correct placeholder format..PlaceholderFormat(sq.Dollar)
method call to your sq.Insert("collections")...
statement.psql := sq.StatementBuilder.PlaceholderFormat(sq.Dollar)
// You use question marks for placeholders...
sql, _, _ := psql.Select("*").From("elephants").Where("name IN (?,?)", "Dumbo", "Verna").ToSql()
/// ...squirrel replaces them using PlaceholderFormat.
sql == "SELECT * FROM elephants WHERE name IN ($1,$2)"
/// You can retrieve id ...
query := sq.Insert("nodes").
Columns("uuid", "type", "data").
Values(node.Uuid, node.Type, node.Data).
Suffix("RETURNING \"id\"").
RunWith(m.db).
PlaceholderFormat(sq.Dollar)
query.QueryRow().Scan(&node.id)
Example taken from squirrel
's README.