質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
Go

Go(golang)は、Googleで開発されたオープンソースのプログラミング言語です。

PostgreSQL

PostgreSQLはオープンソースのオブジェクトリレーショナルデータベース管理システムです。 Oracle Databaseで使われるPL/SQLを参考に実装されたビルトイン言語で、Windows、 Mac、Linux、UNIX、MSなどいくつものプラットフォームに対応しています。

Q&A

解決済

1回答

3180閲覧

go/squirrel で最後にinsertされたidを取得したい

hello_whats_up

総合スコア57

Go

Go(golang)は、Googleで開発されたオープンソースのプログラミング言語です。

PostgreSQL

PostgreSQLはオープンソースのオブジェクトリレーショナルデータベース管理システムです。 Oracle Databaseで使われるPL/SQLを参考に実装されたビルトイン言語で、Windows、 Mac、Linux、UNIX、MSなどいくつものプラットフォームに対応しています。

0グッド

0クリップ

投稿2020/06/04 12:16

編集2020/06/05 06:01

わからないこと

squirrelで、insertされたID(primary key、オートインクリメント値)を取得する方法を教えていただきたいです。

database/sqlではLastInsertIdというものがあるようでしたが、同様の機能のものをsquirrelで見つけることができませんでした。
なにかありましたら教えていただけると助かります。よろしくお願いいたします。

stmt, err := db.Prepare("INSERT table SET unique_id=? ON DUPLICATE KEY UPDATE id=LAST_INSERT_ID(id)") res, err := stmt.Exec(unique_id) lid, err := res.LastInsertId()

追記

現状下記のようなinsertメソッドにしていて、ここからinsertした場合のidを取得したいです。

func (p *Postgres) InsertHoge(tx *sqlx.Tx, hoge models.Hoge) (models.Hoge, error) { query, args, err := sq.StatementBuilder.PlaceholderFormat(sq.Dollar). Insert(`"hoge"`). Columns( `"title"`, ). Values( hoge.Title, ). ToSql() if err != nil { return hoge, err } if err := tx.Get(&hoge, query, args...); err != nil { return hoge, err } return hoge, nil

}

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

hello_whats_up

2020/06/04 12:56

はい、そうです! 不足があり申し訳ありません
guest

回答1

0

ベストアンサー

追記いただいたコード(InsertHoge メソッド)をベースに全体的に書き換えました。ローカルで試す際は Docker などを用いて PostgreSQL に接続できる環境でお試しください。

LastInsertId は PostgreSQL のドライバーでは使えない (参照: no LastInsertId available in Postgresql) ため RETURNING 句を用いるのはどうでしょうか?RETURNINGsquirrel のクエリビルダで付与するイメージです。

コード

go

1package main 2 3import ( 4 "database/sql" 5 "fmt" 6 7 "github.com/jmoiron/sqlx" 8 _ "github.com/lib/pq" 9 10 sq "github.com/Masterminds/squirrel" 11) 12 13func (p *Postgres) InsertHoge(hoge *Hoge) (*Hoge, error) { 14 query, args, err := sq.StatementBuilder.PlaceholderFormat(sq.Dollar). 15 Insert("hoge").Columns("title").Values(hoge.Title).Suffix("RETURNING *").ToSql() 16 17 if err != nil { 18 return nil, err 19 } 20 21 tx, err := p.Beginx() 22 if err != nil { 23 return nil, err 24 } 25 26 var h Hoge 27 if err := tx.QueryRowx(query, args[0]).StructScan(&h); err != nil { 28 return nil, err 29 } 30 31 tx.Commit() 32 33 // エラーのときのロールバックの処理は割愛 34 return &h, nil 35} 36 37// ------------------------------------------------------------------------------------------------ 38// ローカルの Docker の起動 39// $ docker run --name tmp-postgres -e POSTGRES_USER=postgres -e POSTGRES_PASSWORD=postgres -d -p 5432:5432 postgres 40// ------------------------------------------------------------------------------------------------ 41 42func main() { 43 // Docker上のデータベースへの接続 44 db, err := sql.Open("postgres", fmt.Sprintf( 45 "user=%s password=%s host=%s port=%s dbname=%s sslmode=%s", 46 "postgres", "postgres", "localhost", "5432", "postgres", "disable", 47 )) 48 if err != nil { 49 panic(err) 50 } 51 52 // sqlxライブラリの使用 53 x := sqlx.NewDb(db, "postgres") 54 55 // Postgres構造体の値生成 56 p := &Postgres{x} 57 58 // クエリの実行 59 m, err := p.InsertHoge(&Hoge{Title: "gopher"}) 60 if err != nil { 61 panic(err) 62 } 63 64 // 結果の表示 65 fmt.Printf("%+v\n", m) 66} 67 68/* 69-- DDLは以下のようなものを想定 70 71CREATE TABLE hoge ( 72 id SERIAL NOT NULL, 73 title VARCHAR(255) NOT NULL, 74 PRIMARY KEY (id) 75); 76*/ 77type Hoge struct { 78 Id int `db:"id"` 79 Title string `db:"title"` 80} 81 82type Postgres struct{ *sqlx.DB }

取得できる結果例

以下のように ID と Title の組み合わせでオートインクリメントされた ID の値も取得できます。

&{Id:3 Title:gopher}

投稿2020/06/04 13:13

編集2020/06/06 04:02
d_tutuz

総合スコア730

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

hello_whats_up

2020/06/05 06:03

回答ありがとうございます。 本文に追記したようなコード中で使用してみたのですが、`unreferenced` などのエラーが出てしまうので、上記のようなコード中での使用法を教えていただけないでしょうか?
d_tutuz

2020/06/06 03:29

追記いただいたコードで全面的に回答を書き換えました!お試しくださいっ
hello_whats_up

2020/06/06 13:35

ありがとうございます! 試してみてまた連絡させていただきます!
hello_whats_up

2020/06/07 04:31

ありがとうございます! 教えて頂いたコードで取得することができました! あと一つ教えていただきたいのですが、取得したIDの値をInsertHogeメソッド内で取得することも可能なのでしょうか??
d_tutuz

2020/06/07 05:48

tx.QueryRowx(query, args[0]).StructScan(&h) で変数 h の中に Id と Title がセットされるので、変数 h を用いれば InsertHoge メソッド内で Id を使うことができます。
hello_whats_up

2020/06/07 10:14

おかげさまで解決することができました。 ご丁寧にありがとうございました!
d_tutuz

2020/06/07 12:26

良かったです!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問