0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

16rep - DBSQLでNull値をInsertしたりSelectで取得する方法

Last updated at Posted at 2021-02-16

どういうシチュエーション?

  • 特定のカラムに対してNULLで入れたい場合

実際のコード

  • exec を含めないコードサンプル
  • Insertでsample_tableテーブルnum_hogeにnullで入れたい場合そのままですとInsertできません
  • db driver側でnullに変えてくれる記述で定義してInsertする必要があります
package main

import (
	"database/sql"
	"fmt"
)

func main() {
	var sampleID int64
	sampleID = 0

	sid := sql.NullInt64{} // sql.NullInt64{}型

	/*
	    // ./src/database/sql/sql.goより
	    // Nullint64は,nullになる可能性のあるint64を表します
	    // NullStringと同様にスキャン先として使用することができます
	    // (今回はint64です)
		type NullInt64 struct {
			Int64 int64
			Valid bool // int64がNULLでない場合有効
		}
	*/

	if sampleID != 0 {
		// 0でない場合(整数など入っている場合)
		// そのまま値として使用します
		sid.Int64, sid.Valid = sampleID, true
	}

	q := `
		INSERT INTO sample_table (
			id,
			num_hoge,
			fuge
		) VALUES (?,?,?)`

	if _, err := Exec(q, 1, sid, "fugefuge"); err != nil {
		return err
	}

}
  • sql.NullInt64{}
    • NullInt64 -> Valuer Interfaceを実装している構造体
    • Valuer Interface -> DBドライバが参照するインターフェース型

Exec等のメソッド実行

  • database/sqlを通じて間接的にブランクインポートしたdb driverが実行される
  • db driverにて実行する際、渡された引数をdb driver読み取れるデータ型変更(convert value)
  • db driverにてbyte型等に変換してのSQL文に組み込んでSQL実行

ブランクインポート
間接的な参照 パッケージとして直接使用していないもの(アンダーバーで定義されているもの)

最後に

  • 今回 sql.NullInt64{}ですが sql.NullInt32{} sql.NullFloat64{} sql.NullString 基本的な内容は上記のコードと同じように対応が可能かと思います。
  • 痒いとこに手が届く小技でした
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?