♠️

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

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 基本的な内容は上記のコードと同じように対応が可能かと思います。
  • 痒いとこに手が届く小技でした

https://twitter.com/MarcyWorkOut

Discussion