Описание типа database/sql ColumnType

ColumnType тип для управлени структурой базы данных
type ColumnType struct {
// содержит отфильтрованные или неэкспортированные поля
}

ColumnType содержит имя и тип колонки.

func (*ColumnType) DatabaseTypeName

func (ci *ColumnType) DatabaseTypeName() string

DatabaseTypeName возвращает системное имя базы данных типа столбца. Если возвращается пустая строка, значит, имя типа драйвером не поддерживается. Список типов данных драйвера см. в документации к драйверу.

Спецификаторы ColumnType.Length не учитываются. Общие имена типов включают “VARCHAR”, “TEXT”, “NVARCHAR”, “DECIMAL”, “BOOL”, “INT” и “BIGINT”.

func (*ColumnType) DecimalSize

func (ci *ColumnType) DecimalSize() (precision, scale int64, ok bool)

DecimalSize возвращает масштаб и точность десятичного типа. Если они не применяются или не поддерживаются, ok равно false.

func (*ColumnType) Length

func (ci *ColumnType) Length() (length int64, ok bool)

Length возвращает длину типа столбца для типов столбцов переменной длины, таких как текстовые и бинарные типы полей. Если длина типа не ограничена, то значение будет math.MaxInt64 (все ограничения базы данных будут действовать). Если тип столбца не переменной длины, например int, или если он не поддерживается драйвером, ok будет false.

func (*ColumnType) Name

func (ci *ColumnType) Name() string

Name возвращает имя или псевдоним колонки.

func (*ColumnType) Nullable

func (ci *ColumnType) Nullable() (nullable, ok bool)

Nullable сообщает, может ли столбец быть нулевым. Если драйвер не поддерживает это свойство, ok будет равно false.

func (*ColumnType) ScanType

func (ci *ColumnType) ScanType() reflect.Type

ScanType возвращает тип Go, подходящий для сканирования с помощью Rows.Scan. Если драйвер не поддерживает это свойство, ScanType вернет тип пустого интерфейса.

package main

import (
	"context"
	"database/sql"
	"fmt"
	"log"
	"time"

	_ "github.com/go-sql-driver/mysql"
)

func main() {
	// Подключение к базе данных
	db, err := sql.Open("mysql", "user:password@tcp(localhost:3306)/testdb")
	if err != nil {
		log.Fatal(err)
	}
	defer db.Close()

	// Проверка соединения
	if err := db.Ping(); err != nil {
		log.Fatal(err)
	}

	// Выполнение запроса
	rows, err := db.QueryContext(context.Background(), 
		"SELECT id, username, created_at, balance, is_active FROM users LIMIT 1")
	if err != nil {
		log.Fatal(err)
	}
	defer rows.Close()

	// Получение информации о столбцах
	columnTypes, err := rows.ColumnTypes()
	if err != nil {
		log.Fatal(err)
	}

	// Анализ метаданных каждого столбца
	for i, ct := range columnTypes {
		fmt.Printf("\n--- Столбец %d: %s ---\n", i+1, ct.Name())

		// Тип данных в БД
		databaseType := ct.DatabaseTypeName()
		fmt.Printf("Тип в БД: %s\n", databaseType)

		// Nullable
		nullable, ok := ct.Nullable()
		if ok {
			fmt.Printf("Может быть NULL: %v\n", nullable)
		} else {
			fmt.Println("Информация о NULL недоступна")
		}

		// Длина/размер
		length, ok := ct.Length()
		if ok {
			fmt.Printf("Длина: %d\n", length)
		}

		// Точность и масштаб (для чисел)
		precision, scale, ok := ct.DecimalSize()
		if ok {
			fmt.Printf("Точность: %d, Масштаб: %d\n", precision, scale)
		}

		// Тип сканирования в Go
		scanType := ct.ScanType()
		fmt.Printf("Тип в Go: %v\n", scanType)
	}

	// Пример использования информации о типах для динамического сканирования
	var (
		id        int64
		username  string
		createdAt time.Time
		balance   float64
		isActive  bool
	)

	if rows.Next() {
		err = rows.Scan(&id, &username, &createdAt, &balance, &isActive)
		if err != nil {
			log.Fatal(err)
		}
		fmt.Printf("\nРеальные значения: %d, %s, %v, %.2f, %t\n", 
			id, username, createdAt, balance, isActive)
	}
}