godbc

package module
v0.0.4 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 9, 2026 License: MIT Imports: 16 Imported by: 0

README

godbc

Pure Go ODBC driver for database/sql using purego for FFI. No CGO required. Developed by SlingData.IO.

Features

  • Pure Go implementation - no CGO required
  • Cross-platform: Windows, macOS, Linux
  • Standard database/sql interface
  • Supports prepared statements with parameters
  • Transaction support with isolation levels
  • Multiple result sets
  • Column type information

Installation

go get github.com/slingdata-io/godbc

Requirements

You need an ODBC driver manager installed on your system:

  • Windows: Built-in (odbc32.dll)
  • macOS: Install unixODBC via Homebrew: brew install unixodbc
  • Linux: Install unixODBC: apt install unixodbc or yum install unixODBC

You also need ODBC drivers for the databases you want to connect to.

Usage

package main

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

    _ "github.com/slingdata-io/godbc"
)

func main() {
    // Connect using a DSN
    db, err := sql.Open("odbc", "DSN=mydsn;UID=user;PWD=password")
    if err != nil {
        log.Fatal(err)
    }
    defer db.Close()

    // Or use a DSN-less connection string
    // db, err := sql.Open("odbc", "Driver={SQL Server};Server=localhost;Database=mydb;UID=user;PWD=password")

    // Query
    rows, err := db.Query("SELECT id, name FROM users WHERE active = ?", true)
    if err != nil {
        log.Fatal(err)
    }
    defer rows.Close()

    for rows.Next() {
        var id int
        var name string
        if err := rows.Scan(&id, &name); err != nil {
            log.Fatal(err)
        }
        fmt.Printf("ID: %d, Name: %s\n", id, name)
    }
}

Connection String Examples

// DSN-based connection
"DSN=mydsn;UID=user;PWD=password"

// SQL Server (DSN-less)
"Driver={ODBC Driver 17 for SQL Server};Server=localhost;Database=mydb;UID=user;PWD=password"

// PostgreSQL (DSN-less)
"Driver={PostgreSQL Unicode};Server=localhost;Port=5432;Database=mydb;UID=user;PWD=password"

// MySQL (DSN-less)
"Driver={MySQL ODBC 8.0 Unicode Driver};Server=localhost;Database=mydb;UID=user;PWD=password"

// SQLite (DSN-less)
"Driver={SQLite3 ODBC Driver};Database=/path/to/database.db"

Supported Data Types

Go Type ODBC SQL Type
bool BIT
int8, int16, int32, int64 TINYINT, SMALLINT, INTEGER, BIGINT
float32, float64 REAL, DOUBLE
string CHAR, VARCHAR, TEXT, DECIMAL, NUMERIC
[]byte BINARY, VARBINARY, BLOB
time.Time DATE, TIME, TIMESTAMP

Decimal Precision

DECIMAL and NUMERIC columns are returned as string to preserve full precision (avoiding float64 rounding errors). Use the DecimalSize() method on column types to get precision and scale metadata:

rows, _ := db.Query("SELECT price FROM products")
defer rows.Close()

cols, _ := rows.ColumnTypes()
for _, col := range cols {
    if prec, scale, ok := col.DecimalSize(); ok {
        fmt.Printf("Column %s: DECIMAL(%d,%d)\n", col.Name(), prec, scale)
    }
}

For arbitrary-precision arithmetic, use a decimal library like shopspring/decimal:

import "github.com/shopspring/decimal"

var priceStr string
rows.Scan(&priceStr)
price, _ := decimal.NewFromString(priceStr)

Transactions

tx, err := db.Begin()
if err != nil {
    log.Fatal(err)
}

_, err = tx.Exec("INSERT INTO users (name) VALUES (?)", "John")
if err != nil {
    tx.Rollback()
    log.Fatal(err)
}

err = tx.Commit()
if err != nil {
    log.Fatal(err)
}

Named Parameters

The driver supports named parameters in addition to positional ? placeholders. Named parameters are automatically converted to positional placeholders before execution.

Supported styles:

  • :name - Oracle/PostgreSQL style
  • @name - SQL Server style
  • $name - PostgreSQL style (not $1 which is positional)
// Using named parameters
rows, err := db.Query(
    "SELECT * FROM users WHERE name = :name AND status = :status",
    sql.Named("name", "John"),
    sql.Named("status", "active"),
)

// SQL Server style
rows, err := db.Query(
    "SELECT * FROM users WHERE name = @name AND status = @status",
    sql.Named("name", "John"),
    sql.Named("status", "active"),
)

Named parameters can appear multiple times in a query:

rows, err := db.Query(
    "SELECT * FROM users WHERE first_name = :name OR last_name = :name",
    sql.Named("name", "Smith"),
)

Connection Options

Use OpenConnectorWithOptions for advanced configuration:

import "github.com/slingdata-io/godbc"

// Create connector with options
connector, err := godbc.OpenConnectorWithOptions(
    "Driver={PostgreSQL Unicode};Server=localhost;Database=mydb",
    godbc.WithTimezone(time.UTC),
    godbc.WithTimestampPrecision(godbc.Microseconds),
    godbc.WithQueryTimeout(30 * time.Second),
    godbc.WithLastInsertIdBehavior(godbc.LastInsertIdAuto),
)
if err != nil {
    log.Fatal(err)
}

db := sql.OpenDB(connector)
defer db.Close()
Available Options
Option Description
WithTimezone(tz) Set timezone for timestamp handling (default: UTC)
WithTimestampPrecision(p) Set precision: Seconds, Milliseconds, Microseconds, Nanoseconds
WithQueryTimeout(d) Set default query timeout (default: no timeout)
WithLastInsertIdBehavior(b) Set LastInsertId handling: LastInsertIdAuto, LastInsertIdDisabled

Query Timeout

Set a timeout for query execution:

connector, _ := godbc.OpenConnectorWithOptions(
    connString,
    godbc.WithQueryTimeout(30 * time.Second),
)
db := sql.OpenDB(connector)

// All queries will timeout after 30 seconds
rows, err := db.Query("SELECT * FROM large_table")

You can also use context-based timeouts:

ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second)
defer cancel()

rows, err := db.QueryContext(ctx, "SELECT * FROM large_table")

Output Parameters

When calling stored procedures, retrieve output parameter values from the result:

// Execute stored procedure with output parameter
result, err := db.Exec("CALL get_user_count(?)", sql.Out{Dest: new(int64)})
if err != nil {
    log.Fatal(err)
}

// Get output parameters (requires type assertion to *godbc.Result)
if odbcResult, ok := result.(*godbc.Result); ok {
    params := odbcResult.OutputParams()
    count := params[0].(int64)
    fmt.Printf("User count: %d\n", count)
}

Unit Tests

Run the unit tests (no database connection required):

go test -v

The test suite covers:

  • Type conversions (Go ↔ ODBC)
  • GUID parsing and formatting
  • UTF-16 to UTF-8 string conversion
  • Error handling utilities
  • SQL type name helpers

Integration Testing with the Basic Example

The examples/basic directory contains a test program that validates the driver against any ODBC-compatible database. It creates a test table, inserts rows, validates the data, tests transactions, and cleans up.

Build
go build ./examples/basic/
Usage
./basic -conn-string <connection-string> [-schema <schema-name>]
Examples
# SQL Server
./basic -conn-string "Driver={ODBC Driver 18 for SQL Server};Server=localhost;Database=master;UID=sa;PWD=password;Encrypt=no" -schema dbo

# PostgreSQL
./basic -conn-string "Driver={PostgreSQL Unicode};Server=localhost;Port=5432;Database=postgres;UID=postgres;PWD=password" -schema public

# MySQL
./basic -conn-string "Driver={MySQL ODBC 8.0 Unicode Driver};Server=localhost;Database=test;UID=root;PWD=password"

# SQLite
./basic -conn-string "Driver={SQLite3 ODBC Driver};Database=/tmp/test.db"
What It Tests
  • Connection and ping
  • Table creation with various data types (INTEGER, VARCHAR, FLOAT, BOOLEAN/BIT, TIMESTAMP, BINARY, DECIMAL)
  • Prepared statement parameter binding
  • Data insertion and retrieval
  • Value equality validation (verifies inserted values match retrieved values)
  • Decimal precision/scale metadata (validates ColumnTypePrecisionScale returns correct values)
  • Transaction rollback (inserts row, rolls back, verifies not persisted)
  • Transaction commit (inserts row, commits, verifies persisted)
  • Table cleanup

The example auto-detects the database type from the DSN and uses appropriate DDL syntax for SQL Server, PostgreSQL, MySQL, SQLite, and Oracle.

Troubleshooting

ODBC Library Not Found

If you get an error about the ODBC library not being found, set GODBC_LIBRARY_PATH to specify a custom library location:

# macOS
export GODBC_LIBRARY_PATH=/opt/homebrew/lib/libodbc.2.dylib

# Linux
export GODBC_LIBRARY_PATH=/usr/lib/x86_64-linux-gnu/libodbc.so.2
Known Limitations
  • LastInsertId(): Always returns 0. ODBC does not have a standard way to retrieve the last inserted ID. Use database-specific queries like SELECT @@IDENTITY (SQL Server), SELECT lastval() (PostgreSQL), or SELECT LAST_INSERT_ID() (MySQL).

  • Timestamp precision: Timestamps are truncated to millisecond precision for database compatibility. Nanosecond precision is not preserved.

  • DECIMAL/NUMERIC: Returned as strings to preserve full precision. Use a decimal library like shopspring/decimal for arithmetic.

Error Handling

The driver provides helper functions for error classification:

import "github.com/slingdata-io/godbc"

if err := db.Ping(); err != nil {
    if godbc.IsConnectionError(err) {
        // Handle connection failure
    }
    if godbc.IsRetryable(err) {
        // Retry the operation
    }
}

License

MIT License - see LICENSE file

Documentation

Index

Constants

View Source
const (
	// Connection errors (08xxx)
	SQLStateConnectionFailure  = "08001" // Unable to connect
	SQLStateConnectionNotOpen  = "08003" // Connection not open
	SQLStateConnectionRejected = "08004" // Connection rejected by server
	SQLStateConnectionError    = "08S01" // Communication link failure

	// Warning states (01xxx)
	SQLStateDataTruncation = "01004" // Data truncated
	SQLStateOptionChanged  = "01S02" // Option value changed

	// No data (02xxx)
	SQLStateNoData = "02000" // No data found

	// Data errors (22xxx)
	SQLStateStringTruncation = "22001" // String data right truncation
	SQLStateNumericOverflow  = "22003" // Numeric value out of range
	SQLStateInvalidDatetime  = "22007" // Invalid datetime format
	SQLStateDivisionByZero   = "22012" // Division by zero

	// Constraint violations (23xxx)
	SQLStateDuplicateKey        = "23000" // Integrity constraint violation
	SQLStateConstraintViolation = "23000" // Integrity constraint violation (alias)

	// Cursor/Transaction states (24xxx, 25xxx)
	SQLStateInvalidCursorState = "24000" // Invalid cursor state
	SQLStateInvalidTransState  = "25000" // Invalid transaction state

	// Transaction errors (40xxx)
	SQLStateDeadlock          = "40001" // Serialization failure (deadlock)
	SQLStateTransactionFailed = "40003" // Statement completion unknown

	// Syntax/access errors (42xxx)
	SQLStateSyntaxError    = "42000" // Syntax error or access violation
	SQLStateTableNotFound  = "42S02" // Table not found
	SQLStateColumnNotFound = "42S22" // Column not found

	// General errors (HYxxx)
	SQLStateGeneralError          = "HY000" // General error
	SQLStateMemoryAllocationError = "HY001" // Memory allocation error
	SQLStateFunctionSequenceError = "HY010" // Function sequence error
	SQLStateInvalidAttrValue      = "HY024" // Invalid attribute value
	SQLStateInvalidStringLength   = "HY090" // Invalid string or buffer length
	SQLStateInvalidDescIndex      = "HY091" // Invalid descriptor field identifier
	SQLStateTimeout               = "HYT00" // Timeout expired
	SQLStateConnectionTimeout     = "HYT01" // Connection timeout expired
)

SQLState constants for common errors. These follow the ODBC specification and can be used with errors.Is.

View Source
const (
	SQL_OV_ODBC2 = 2
	SQL_OV_ODBC3 = 3
)

ODBC version constants

View Source
const (
	SQL_AUTOCOMMIT_OFF = 0
	SQL_AUTOCOMMIT_ON  = 1
)

Autocommit values

View Source
const (
	SQL_MODE_READ_WRITE = 0
	SQL_MODE_READ_ONLY  = 1
)

Access mode values

View Source
const (
	SQL_TXN_READ_UNCOMMITTED = 1
	SQL_TXN_READ_COMMITTED   = 2
	SQL_TXN_REPEATABLE_READ  = 4
	SQL_TXN_SERIALIZABLE     = 8
)

Transaction isolation levels

View Source
const (
	SQL_CURSOR_FORWARD_ONLY  = 0
	SQL_CURSOR_KEYSET_DRIVEN = 1
	SQL_CURSOR_DYNAMIC       = 2
	SQL_CURSOR_STATIC        = 3
)

Cursor types

View Source
const (
	SQL_C_CHAR      = SQL_CHAR
	SQL_C_LONG      = SQL_INTEGER
	SQL_C_SHORT     = SQL_SMALLINT
	SQL_C_FLOAT     = SQL_REAL
	SQL_C_DOUBLE    = SQL_DOUBLE
	SQL_C_NUMERIC   = SQL_NUMERIC
	SQL_C_DEFAULT   = 99
	SQL_C_DATE      = SQL_TYPE_DATE
	SQL_C_TIME      = SQL_TYPE_TIME
	SQL_C_TIMESTAMP = SQL_TYPE_TIMESTAMP
	SQL_C_BINARY    = SQL_BINARY
	SQL_C_BIT       = SQL_BIT
	SQL_C_WCHAR     = SQL_WCHAR
	SQL_C_SBIGINT   = SQL_BIGINT + SQL_SIGNED_OFFSET    // -25
	SQL_C_UBIGINT   = SQL_BIGINT + SQL_UNSIGNED_OFFSET  // -27
	SQL_C_SLONG     = SQL_C_LONG + SQL_SIGNED_OFFSET    // -16
	SQL_C_SSHORT    = SQL_C_SHORT + SQL_SIGNED_OFFSET   // -15
	SQL_C_STINYINT  = SQL_TINYINT + SQL_SIGNED_OFFSET   // -26
	SQL_C_ULONG     = SQL_C_LONG + SQL_UNSIGNED_OFFSET  // -18
	SQL_C_USHORT    = SQL_C_SHORT + SQL_UNSIGNED_OFFSET // -17
	SQL_C_UTINYINT  = SQL_TINYINT + SQL_UNSIGNED_OFFSET // -28
	SQL_C_GUID      = SQL_GUID
)
View Source
const (
	SQL_C_INTERVAL_YEAR             = SQL_INTERVAL_YEAR
	SQL_C_INTERVAL_MONTH            = SQL_INTERVAL_MONTH
	SQL_C_INTERVAL_DAY              = SQL_INTERVAL_DAY
	SQL_C_INTERVAL_HOUR             = SQL_INTERVAL_HOUR
	SQL_C_INTERVAL_MINUTE           = SQL_INTERVAL_MINUTE
	SQL_C_INTERVAL_SECOND           = SQL_INTERVAL_SECOND
	SQL_C_INTERVAL_YEAR_TO_MONTH    = SQL_INTERVAL_YEAR_TO_MONTH
	SQL_C_INTERVAL_DAY_TO_HOUR      = SQL_INTERVAL_DAY_TO_HOUR
	SQL_C_INTERVAL_DAY_TO_MINUTE    = SQL_INTERVAL_DAY_TO_MINUTE
	SQL_C_INTERVAL_DAY_TO_SECOND    = SQL_INTERVAL_DAY_TO_SECOND
	SQL_C_INTERVAL_HOUR_TO_MINUTE   = SQL_INTERVAL_HOUR_TO_MINUTE
	SQL_C_INTERVAL_HOUR_TO_SECOND   = SQL_INTERVAL_HOUR_TO_SECOND
	SQL_C_INTERVAL_MINUTE_TO_SECOND = SQL_INTERVAL_MINUTE_TO_SECOND
)

C Interval type identifiers (same as SQL types for intervals)

View Source
const (
	SQL_PARAM_SUCCESS           = 0
	SQL_PARAM_SUCCESS_WITH_INFO = 1
	SQL_PARAM_ERROR             = 5
	SQL_PARAM_UNUSED            = 7
	SQL_PARAM_DIAG_UNAVAILABLE  = 8
)

Param status values

View Source
const (
	SQL_NONSCROLLABLE = 0
	SQL_SCROLLABLE    = 1
)

Cursor scrollability

View Source
const (
	SQL_PARAM_BIND_BY_COLUMN = 0
)

Param binding types

Variables

This section is empty.

Functions

func ColAttribute

func ColAttribute(stmt SQLHSTMT, colNum SQLUSMALLINT, fieldId SQLUSMALLINT, charAttr []byte) (strLen SQLSMALLINT, numAttr SQLLEN, ret SQLRETURN)

ColAttribute returns a column attribute

func DescribeCol

func DescribeCol(stmt SQLHSTMT, colNum SQLUSMALLINT, colName []byte) (nameLen SQLSMALLINT, dataType SQLSMALLINT, colSize SQLULEN, decDigits SQLSMALLINT, nullable SQLSMALLINT, ret SQLRETURN)

DescribeCol describes a column in a result set

func DriverConnect

func DriverConnect(dbc SQLHDBC, hwnd uintptr, inConnStr string, outConnStr []byte, driverCompletion SQLUSMALLINT) (outLen SQLSMALLINT, ret SQLRETURN)

DriverConnect connects to a data source using a connection string

func FormatReturnCode

func FormatReturnCode(ret SQLRETURN) string

FormatReturnCode returns a string representation of an ODBC return code

func GetDiagRec

func GetDiagRec(handleType SQLSMALLINT, handle SQLHANDLE, recNum SQLSMALLINT, sqlState []byte, message []byte) (nativeError SQLINTEGER, msgLen SQLSMALLINT, ret SQLRETURN)

GetDiagRec retrieves diagnostic records

func GetInfo

func GetInfo(dbc SQLHDBC, infoType SQLUSMALLINT, infoValue []byte) (stringLength SQLSMALLINT, ret SQLRETURN)

GetInfo retrieves driver/data source information

func IsConnectionError

func IsConnectionError(err error) bool

IsConnectionError reports whether err indicates a connection problem. Connection errors have SQLState codes starting with "08".

func IsDataTruncation

func IsDataTruncation(err error) bool

IsDataTruncation reports whether err indicates data truncation.

func IsRetryable

func IsRetryable(err error) bool

IsRetryable reports whether err represents a transient error that may succeed if retried. Transient errors include connection failures, timeouts, and deadlocks.

func IsSuccess

func IsSuccess(ret SQLRETURN) bool

IsSuccess checks if the return code indicates success

func NewError

func NewError(handleType SQLSMALLINT, handle SQLHANDLE) error

NewError creates an Error from diagnostic records

func SQLTypeName

func SQLTypeName(sqlType SQLSMALLINT) string

SQLTypeName returns a human-readable name for an SQL type

Types

type BatchResult

type BatchResult struct {
	// TotalRowsAffected is the sum of all rows affected across all parameter sets
	TotalRowsAffected int64

	// RowCounts contains the number of rows affected for each parameter set
	RowCounts []int64

	// Errors contains any error that occurred for each parameter set (nil if success)
	Errors []error
}

BatchResult holds the result of a batch execution

func (*BatchResult) HasErrors

func (r *BatchResult) HasErrors() bool

HasErrors returns true if any parameter set resulted in an error

type ColumnBuffer

type ColumnBuffer struct {
	Data      interface{} // The actual buffer (slice of values)
	CType     SQLSMALLINT // ODBC C type
	SQLType   SQLSMALLINT // ODBC SQL type
	ColSize   SQLULEN     // Column size
	DecDigits SQLSMALLINT // Decimal digits
	Lengths   []SQLLEN    // Length/indicator array (one per row)
	ElemSize  int         // Size of each element in bytes
}

ColumnBuffer holds the buffer data for array parameter binding

func AllocateColumnArray

func AllocateColumnArray(values []interface{}, numRows int) (*ColumnBuffer, error)

AllocateColumnArray allocates a column buffer for array parameter binding based on the type of the first non-nil value in the column

func (*ColumnBuffer) GetColumnBufferPtr

func (cb *ColumnBuffer) GetColumnBufferPtr() uintptr

GetColumnBufferPtr returns a pointer to the start of the column buffer data

type Conn

type Conn struct {
	// contains filtered or unexported fields
}

Conn implements driver.Conn and represents a connection to a database

func (*Conn) Begin

func (c *Conn) Begin() (driver.Tx, error)

Begin starts a new transaction with default options. Deprecated: Use BeginTx with context and options instead.

func (*Conn) BeginTx

func (c *Conn) BeginTx(ctx context.Context, opts driver.TxOptions) (driver.Tx, error)

BeginTx starts a new transaction with the given context and options. It supports setting isolation levels and read-only mode via driver.TxOptions. Returns an error if the connection is already in a transaction.

func (*Conn) CheckNamedValue

func (c *Conn) CheckNamedValue(nv *driver.NamedValue) error

CheckNamedValue validates and converts named values

func (*Conn) Close

func (c *Conn) Close() error

Close closes the database connection, releasing all associated ODBC handles. It is safe to call Close multiple times; subsequent calls are no-ops.

func (*Conn) ExecContext

func (c *Conn) ExecContext(ctx context.Context, query string, args []driver.NamedValue) (driver.Result, error)

ExecContext executes a query that doesn't return rows (INSERT, UPDATE, DELETE). It supports context cancellation and query timeout. If args is empty, the query is executed directly; otherwise a prepared statement is used.

func (*Conn) IsValid

func (c *Conn) IsValid() bool

IsValid implements driver.Validator and returns true if the connection is usable. Used by database/sql to check if a connection should be discarded.

func (*Conn) Ping

func (c *Conn) Ping(ctx context.Context) error

Ping verifies the database connection is still alive. It executes a simple query (SELECT 1) to check connectivity. Returns driver.ErrBadConn if the connection is no longer valid.

func (*Conn) Prepare

func (c *Conn) Prepare(query string) (driver.Stmt, error)

Prepare prepares a statement for execution

func (*Conn) PrepareContext

func (c *Conn) PrepareContext(ctx context.Context, query string) (driver.Stmt, error)

PrepareContext prepares a statement with context support

func (*Conn) PrepareWithCursor

func (c *Conn) PrepareWithCursor(ctx context.Context, query string, cursorType CursorType) (driver.Stmt, error)

PrepareWithCursor prepares a statement with a specific cursor type. Use this when you need scrollable cursors for random-access navigation.

func (*Conn) QueryContext

func (c *Conn) QueryContext(ctx context.Context, query string, args []driver.NamedValue) (driver.Rows, error)

QueryContext executes a query that returns rows (SELECT). It supports context cancellation and query timeout. If args is empty, the query is executed directly; otherwise a prepared statement is used.

func (*Conn) ResetSession

func (c *Conn) ResetSession(ctx context.Context) error

ResetSession is called by database/sql before a connection is returned to the pool. It verifies the connection is in a valid state (not closed, not in a transaction).

type Connector

type Connector struct {

	// Enhanced Type Handling options
	DefaultTimezone           *time.Location       // Default timezone for timestamp retrieval (defaults to UTC)
	DefaultTimestampPrecision TimestampPrecision   // Default precision for Timestamp type (defaults to Milliseconds)
	LastInsertIdBehavior      LastInsertIdBehavior // How to handle LastInsertId() (defaults to Auto)

	// Query execution options
	QueryTimeout time.Duration // Default query timeout (0 = no timeout)
	// contains filtered or unexported fields
}

Connector implements driver.Connector for efficient connection pooling

func (*Connector) Connect

func (c *Connector) Connect(ctx context.Context) (driver.Conn, error)

Connect establishes a new connection to the database

func (*Connector) Driver

func (c *Connector) Driver() driver.Driver

Driver returns the underlying Driver

type ConnectorOption

type ConnectorOption func(*Connector)

ConnectorOption configures a Connector

func WithLastInsertIdBehavior

func WithLastInsertIdBehavior(behavior LastInsertIdBehavior) ConnectorOption

WithLastInsertIdBehavior sets the behavior for LastInsertId()

func WithQueryTimeout

func WithQueryTimeout(d time.Duration) ConnectorOption

WithQueryTimeout sets the default query timeout for all statements. The timeout is applied using SQL_ATTR_QUERY_TIMEOUT and context cancellation. A value of 0 means no timeout (the default).

func WithTimestampPrecision

func WithTimestampPrecision(precision TimestampPrecision) ConnectorOption

WithTimestampPrecision sets the default timestamp precision

func WithTimezone

func WithTimezone(tz *time.Location) ConnectorOption

WithTimezone sets the default timezone for timestamp handling

type CursorType

type CursorType int

CursorType specifies the type of cursor to use for a query

const (
	// CursorForwardOnly is the default cursor type (forward-only, read-only)
	CursorForwardOnly CursorType = iota
	// CursorStatic creates a static snapshot of the result set
	CursorStatic
	// CursorKeyset uses a keyset-driven cursor
	CursorKeyset
	// CursorDynamic creates a fully dynamic cursor
	CursorDynamic
)

type Decimal

type Decimal struct {
	Value     string // String representation for precision preservation
	Precision int    // Total digits (1-38)
	Scale     int    // Digits after decimal point (0-Precision)
}

Decimal represents a decimal value with explicit precision and scale. Use this for precise numeric values where floating-point approximation is unacceptable.

func NewDecimal

func NewDecimal(value string, precision, scale int) (Decimal, error)

NewDecimal creates a Decimal from a string with validation

func ParseDecimal

func ParseDecimal(s string) (Decimal, error)

ParseDecimal parses a decimal string with automatic precision/scale detection

type DecimalError

type DecimalError struct {
	Message string
}

DecimalError represents a decimal validation error

func (*DecimalError) Error

func (e *DecimalError) Error() string

type DiagRecord

type DiagRecord struct {
	SQLState    string
	NativeError int32
	Message     string
}

DiagRecord represents a single diagnostic record from ODBC

func GetDiagRecords

func GetDiagRecords(handleType SQLSMALLINT, handle SQLHANDLE) []DiagRecord

GetDiagRecords retrieves all diagnostic records for a handle

type Driver

type Driver struct{}

Driver implements the database/sql/driver.Driver interface

func (*Driver) Open

func (d *Driver) Open(name string) (driver.Conn, error)

Open opens a new connection to the database The name is an ODBC connection string, e.g.:

  • "DSN=mydsn;UID=user;PWD=password"
  • "Driver={SQL Server};Server=localhost;Database=mydb;UID=user;PWD=password"

func (*Driver) OpenConnector

func (d *Driver) OpenConnector(name string) (driver.Connector, error)

OpenConnector returns a new Connector for the given connection string This implements driver.DriverContext for connection pooling efficiency

func (*Driver) OpenConnectorWithOptions

func (d *Driver) OpenConnectorWithOptions(name string, opts ...ConnectorOption) (*Connector, error)

OpenConnectorWithOptions returns a Connector with custom options for enhanced type handling. Use this when you need to configure timezone, timestamp precision, or other options.

Example:

driver := &odbc.Driver{}
connector, err := driver.OpenConnectorWithOptions(
    "Driver={SQL Server};Server=localhost;Database=test",
    odbc.WithTimezone(time.Local),
    odbc.WithTimestampPrecision(odbc.TimestampPrecisionMicroseconds),
)

type Error

type Error struct {
	SQLState    string
	NativeError int32
	Message     string
}

Error represents an ODBC error with diagnostic information from the driver. It implements the error interface and provides SQLState, native error code, and a human-readable message.

func (*Error) Error

func (e *Error) Error() string

Error implements the error interface

func (*Error) Is

func (e *Error) Is(target error) bool

Is reports whether target matches this error's SQLState. This allows using errors.Is to check for specific ODBC errors.

func (*Error) Unwrap

func (e *Error) Unwrap() error

Unwrap returns nil as Error is a terminal error type. This method supports Go 1.13+ error handling with errors.Is and errors.As.

type Errors

type Errors []Error

Errors represents multiple ODBC errors

func (Errors) Error

func (e Errors) Error() string

Error implements the error interface for multiple errors

type GUID

type GUID [16]byte

GUID represents a UUID/GUID value for use as a parameter

func ParseGUID

func ParseGUID(s string) (GUID, error)

ParseGUID parses a GUID string in the format xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx

type IntervalDaySecond

type IntervalDaySecond struct {
	Days        int
	Hours       int
	Minutes     int
	Seconds     int
	Nanoseconds int
	Negative    bool
}

IntervalDaySecond represents a day-time interval

func (IntervalDaySecond) ToDuration

func (i IntervalDaySecond) ToDuration() time.Duration

ToDuration converts IntervalDaySecond to time.Duration

type IntervalYearMonth

type IntervalYearMonth struct {
	Years    int
	Months   int
	Negative bool
}

IntervalYearMonth represents a year-month interval

type LastInsertIdBehavior

type LastInsertIdBehavior int

LastInsertIdBehavior specifies how LastInsertId() should behave

const (
	// LastInsertIdAuto automatically detects the database type and executes
	// the appropriate identity query after INSERT statements
	LastInsertIdAuto LastInsertIdBehavior = iota

	// LastInsertIdDisabled returns 0 for LastInsertId() (original behavior)
	LastInsertIdDisabled

	// LastInsertIdReturning expects the query to use a RETURNING clause (PostgreSQL style)
	LastInsertIdReturning
)

type NamedParams

type NamedParams struct {
	// Query is the converted query with positional ? placeholders
	Query string

	// Names contains the parameter names in order of their first appearance
	Names []string

	// Positions maps parameter names to their positions (1-based, matching ODBC binding)
	// A single named parameter may appear multiple times in the query
	Positions map[string][]int
}

NamedParams holds parsed named parameter information

func ParseNamedParams

func ParseNamedParams(query string) *NamedParams

ParseNamedParams parses a query with named parameters and converts to positional placeholders. Supports the following named parameter styles:

  • :name (Oracle/PostgreSQL style)
  • @name (SQL Server style)
  • $name (PostgreSQL style - not $1 which is positional)

Returns nil if no named parameters are found (query uses positional ? only). The original query is preserved if it contains only ? placeholders.

type OutputParam

type OutputParam struct {
	// Value holds the initial value (for InputOutput) or a type hint (for Output).
	// For output-only parameters, the type of Value determines the buffer size and type.
	// Supported types: int, int32, int64, float32, float64, string, []byte, bool, time.Time
	Value interface{}

	// Direction specifies whether this is an output or input/output parameter
	Direction ParamDirection

	// Size specifies the buffer size for variable-length types (string, []byte).
	// If 0, a default size will be used (4000 for strings, 8000 for bytes).
	Size int
}

OutputParam wraps a value for output or input/output parameter binding. Use this type when calling stored procedures that return values through parameters.

func NewInputOutputParam

func NewInputOutputParam(value interface{}) OutputParam

NewInputOutputParam creates a bidirectional parameter with an initial value.

func NewInputOutputParamWithSize

func NewInputOutputParamWithSize(value interface{}, size int) OutputParam

NewInputOutputParamWithSize creates a bidirectional parameter with a specific buffer size.

func NewOutputParam

func NewOutputParam(typeHint interface{}) OutputParam

NewOutputParam creates an output-only parameter with the given type hint. The type of value determines the expected output type.

func NewOutputParamWithSize

func NewOutputParamWithSize(typeHint interface{}, size int) OutputParam

NewOutputParamWithSize creates an output-only parameter with a specific buffer size. Use this for variable-length types (string, []byte) when you know the maximum size.

type ParamDirection

type ParamDirection int

ParamDirection specifies the direction of a parameter (input, output, or both)

const (
	// ParamInput is for input-only parameters (default)
	ParamInput ParamDirection = iota
	// ParamOutput is for output-only parameters
	ParamOutput
	// ParamInputOutput is for bidirectional parameters
	ParamInputOutput
)

type ParameterError

type ParameterError struct {
	Name    string
	Message string
}

ParameterError represents an error with parameter binding

func (*ParameterError) Error

func (e *ParameterError) Error() string

type Result

type Result struct {
	// contains filtered or unexported fields
}

Result implements driver.Result for INSERT, UPDATE, DELETE operations

func (*Result) LastInsertId

func (r *Result) LastInsertId() (int64, error)

LastInsertId returns the ID of the last inserted row. When LastInsertIdAuto behavior is configured (default), this automatically executes the appropriate identity query for the connected database type.

func (*Result) OutputParam

func (r *Result) OutputParam(index int) interface{}

OutputParam returns a single output parameter value by index (0-based). Returns nil if the index is out of range or if the parameter was input-only.

func (*Result) OutputParams

func (r *Result) OutputParams() []interface{}

OutputParams returns the values of output parameters after executing a stored procedure. The values are returned in the same order as the parameters were bound. Only parameters marked as ParamOutput or ParamInputOutput will have values. Input-only parameters will have nil values in the corresponding positions.

func (*Result) RowsAffected

func (r *Result) RowsAffected() (int64, error)

RowsAffected returns the number of rows affected by the query

type Rows

type Rows struct {
	// contains filtered or unexported fields
}

Rows implements driver.Rows for result set iteration

func (*Rows) Absolute

func (r *Rows) Absolute(row int64) error

Absolute moves the cursor to the specified row number (1-based) Positive values count from the beginning, negative values count from the end.

func (*Rows) Close

func (r *Rows) Close() error

Close closes the result set and releases associated resources. It is safe to call Close multiple times; subsequent calls are no-ops.

func (*Rows) ColumnTypeDatabaseTypeName

func (r *Rows) ColumnTypeDatabaseTypeName(index int) string

ColumnTypeDatabaseTypeName returns the native database-specific type name for a column. This returns the actual type name from the database driver (e.g., "datetime2", "varchar", "int") rather than a generic ODBC type mapping.

func (*Rows) ColumnTypeLength

func (r *Rows) ColumnTypeLength(index int) (length int64, ok bool)

ColumnTypeLength returns the maximum length for variable-length column types. Returns ok=true for VARCHAR, VARBINARY, and similar types; ok=false for fixed types.

func (*Rows) ColumnTypeNullable

func (r *Rows) ColumnTypeNullable(index int) (nullable, ok bool)

ColumnTypeNullable reports whether a column may be null. Returns ok=false if nullability cannot be determined.

func (*Rows) ColumnTypePrecisionScale

func (r *Rows) ColumnTypePrecisionScale(index int) (precision, scale int64, ok bool)

ColumnTypePrecisionScale returns precision and scale for NUMERIC/DECIMAL columns. Precision is the total number of digits; scale is digits after the decimal point. Returns ok=false for non-numeric types.

func (*Rows) ColumnTypeScanType

func (r *Rows) ColumnTypeScanType(index int) reflect.Type

ColumnTypeScanType returns the Go type suitable for scanning column values. For example, SQL_INTEGER returns int64, SQL_VARCHAR returns string.

func (*Rows) Columns

func (r *Rows) Columns() []string

Columns returns the names of all columns in the result set.

func (*Rows) First

func (r *Rows) First() error

First moves the cursor to the first row

func (*Rows) GetRowData

func (r *Rows) GetRowData(dest []driver.Value) error

GetRowData retrieves the current row's data after a scroll operation

func (*Rows) HasNextResultSet

func (r *Rows) HasNextResultSet() bool

HasNextResultSet reports whether there are additional result sets available. Use NextResultSet to advance to the next result set.

func (*Rows) Last

func (r *Rows) Last() error

Last moves the cursor to the last row

func (*Rows) Next

func (r *Rows) Next(dest []driver.Value) error

Next advances to the next row and populates dest with column values. Returns io.EOF when no more rows are available.

func (*Rows) NextResultSet

func (r *Rows) NextResultSet() error

NextResultSet advances to the next result set from a multi-result query. Returns io.EOF if there are no more result sets.

func (*Rows) Prior

func (r *Rows) Prior() error

Prior moves the cursor to the previous row

func (*Rows) Relative

func (r *Rows) Relative(offset int64) error

Relative moves the cursor by the specified offset from the current position

type SQLCHAR

type SQLCHAR byte

ODBC Character types

type SQLHANDLE

type SQLHANDLE uintptr

ODBC Handle types (opaque pointers)

const SQL_NULL_HANDLE SQLHANDLE = 0

Null handle constant

type SQLHDBC

type SQLHDBC SQLHANDLE

type SQLHDESC

type SQLHDESC SQLHANDLE

type SQLHENV

type SQLHENV SQLHANDLE

type SQLHSTMT

type SQLHSTMT SQLHANDLE

type SQLINTEGER

type SQLINTEGER int32
const (
	SQL_ATTR_ODBC_VERSION       SQLINTEGER = 200
	SQL_ATTR_CONNECTION_POOLING SQLINTEGER = 201
	SQL_ATTR_CP_MATCH           SQLINTEGER = 202
	SQL_ATTR_OUTPUT_NTS         SQLINTEGER = 10001
)

Environment attributes

const (
	SQL_ATTR_AUTOCOMMIT      SQLINTEGER = 102
	SQL_ATTR_CONNECTION_DEAD SQLINTEGER = 1209
	SQL_ATTR_LOGIN_TIMEOUT   SQLINTEGER = 103
	SQL_ATTR_ACCESS_MODE     SQLINTEGER = 101
	SQL_ATTR_TXN_ISOLATION   SQLINTEGER = 108
)

Connection attributes

const (
	SQL_ATTR_CURSOR_TYPE        SQLINTEGER = 6
	SQL_ATTR_CONCURRENCY        SQLINTEGER = 7
	SQL_ATTR_ROW_ARRAY_SIZE     SQLINTEGER = 27
	SQL_ATTR_ROW_STATUS_PTR     SQLINTEGER = 25
	SQL_ATTR_ROWS_FETCHED       SQLINTEGER = 26
	SQL_ATTR_QUERY_TIMEOUT      SQLINTEGER = 0
	SQL_ATTR_MAX_ROWS           SQLINTEGER = 1
	SQL_ATTR_CURSOR_SCROLLABLE  SQLINTEGER = -1
	SQL_ATTR_CURSOR_SENSITIVITY SQLINTEGER = -2
)

Statement attributes

const (
	SQL_ATTR_PARAM_BIND_TYPE      SQLINTEGER = 18
	SQL_ATTR_PARAM_STATUS_PTR     SQLINTEGER = 20
	SQL_ATTR_PARAMS_PROCESSED_PTR SQLINTEGER = 21
	SQL_ATTR_PARAMSET_SIZE        SQLINTEGER = 22
)

Statement attributes for batch operations

const SQL_NTS SQLINTEGER = -3

String terminator

type SQLLEN

type SQLLEN int64 // 64-bit for portability across platforms
const (
	SQL_NULL_DATA    SQLLEN = -1
	SQL_DATA_AT_EXEC SQLLEN = -2
)

Null data indicators

type SQLRETURN

type SQLRETURN SQLSMALLINT
const (
	SQL_SUCCESS           SQLRETURN = 0
	SQL_SUCCESS_WITH_INFO SQLRETURN = 1
	SQL_ERROR             SQLRETURN = -1
	SQL_INVALID_HANDLE    SQLRETURN = -2
	SQL_NO_DATA           SQLRETURN = 100
	SQL_NEED_DATA         SQLRETURN = 99
	SQL_STILL_EXECUTING   SQLRETURN = 2
)

Return codes

func AllocHandle

func AllocHandle(handleType SQLSMALLINT, inputHandle SQLHANDLE, outputHandle *SQLHANDLE) SQLRETURN

AllocHandle allocates an ODBC handle

func BindParameter

func BindParameter(stmt SQLHSTMT, paramNum SQLUSMALLINT, ioType SQLSMALLINT, valueType SQLSMALLINT, paramType SQLSMALLINT, colSize SQLULEN, decDigits SQLSMALLINT, paramValue uintptr, bufferLen SQLLEN, strLenOrInd *SQLLEN) SQLRETURN

BindParameter binds a parameter to a statement

func Cancel

func Cancel(stmt SQLHSTMT) SQLRETURN

Cancel cancels a statement execution

func CloseCursor

func CloseCursor(stmt SQLHSTMT) SQLRETURN

CloseCursor closes an open cursor

func Disconnect

func Disconnect(dbc SQLHDBC) SQLRETURN

Disconnect disconnects from a data source

func EndTran

func EndTran(handleType SQLSMALLINT, handle SQLHANDLE, completionType SQLSMALLINT) SQLRETURN

EndTran commits or rolls back a transaction

func ExecDirect

func ExecDirect(stmt SQLHSTMT, query string) SQLRETURN

ExecDirect executes an SQL statement directly

func Execute

func Execute(stmt SQLHSTMT) SQLRETURN

Execute executes a prepared statement

func Fetch

func Fetch(stmt SQLHSTMT) SQLRETURN

Fetch fetches the next row from the result set

func FetchScroll

func FetchScroll(stmt SQLHSTMT, fetchOrientation SQLSMALLINT, fetchOffset SQLLEN) SQLRETURN

FetchScroll fetches a row from the result set using scroll operations

func FreeHandle

func FreeHandle(handleType SQLSMALLINT, handle SQLHANDLE) SQLRETURN

FreeHandle frees an ODBC handle

func FreeStmt

func FreeStmt(stmt SQLHSTMT, option SQLUSMALLINT) SQLRETURN

FreeStmt frees resources associated with a statement

func GetData

func GetData(stmt SQLHSTMT, colNum SQLUSMALLINT, targetType SQLSMALLINT, targetValue uintptr, bufferLen SQLLEN, strLenOrInd *SQLLEN) SQLRETURN

GetData retrieves data for a single column

func MoreResults

func MoreResults(stmt SQLHSTMT) SQLRETURN

MoreResults checks for more result sets

func NumParams

func NumParams(stmt SQLHSTMT, paramCount *SQLSMALLINT) SQLRETURN

NumParams returns the number of parameters in a prepared statement

func NumResultCols

func NumResultCols(stmt SQLHSTMT, columnCount *SQLSMALLINT) SQLRETURN

NumResultCols returns the number of columns in a result set

func Prepare

func Prepare(stmt SQLHSTMT, query string) SQLRETURN

Prepare prepares an SQL statement for execution

func RowCount

func RowCount(stmt SQLHSTMT, rowCount *SQLLEN) SQLRETURN

RowCount returns the number of rows affected by an UPDATE, INSERT, or DELETE

func SetConnectAttr

func SetConnectAttr(dbc SQLHDBC, attribute SQLINTEGER, value uintptr, stringLength SQLINTEGER) SQLRETURN

SetConnectAttr sets a connection attribute

func SetEnvAttr

func SetEnvAttr(env SQLHENV, attribute SQLINTEGER, value uintptr, stringLength SQLINTEGER) SQLRETURN

SetEnvAttr sets an environment attribute

func SetStmtAttr

func SetStmtAttr(stmt SQLHSTMT, attribute SQLINTEGER, value uintptr, stringLength SQLINTEGER) SQLRETURN

SetStmtAttr sets a statement attribute

type SQLSCHAR

type SQLSCHAR int8

type SQLSMALLINT

type SQLSMALLINT int16

ODBC Integer types

const (
	SQL_HANDLE_ENV  SQLSMALLINT = 1
	SQL_HANDLE_DBC  SQLSMALLINT = 2
	SQL_HANDLE_STMT SQLSMALLINT = 3
	SQL_HANDLE_DESC SQLSMALLINT = 4
)

Handle type identifiers

const (
	SQL_UNKNOWN_TYPE   SQLSMALLINT = 0
	SQL_CHAR           SQLSMALLINT = 1
	SQL_NUMERIC        SQLSMALLINT = 2
	SQL_DECIMAL        SQLSMALLINT = 3
	SQL_INTEGER        SQLSMALLINT = 4
	SQL_SMALLINT       SQLSMALLINT = 5
	SQL_FLOAT          SQLSMALLINT = 6
	SQL_REAL           SQLSMALLINT = 7
	SQL_DOUBLE         SQLSMALLINT = 8
	SQL_DATETIME       SQLSMALLINT = 9
	SQL_VARCHAR        SQLSMALLINT = 12
	SQL_TYPE_DATE      SQLSMALLINT = 91
	SQL_TYPE_TIME      SQLSMALLINT = 92
	SQL_TYPE_TIMESTAMP SQLSMALLINT = 93
	SQL_LONGVARCHAR    SQLSMALLINT = -1
	SQL_BINARY         SQLSMALLINT = -2
	SQL_VARBINARY      SQLSMALLINT = -3
	SQL_LONGVARBINARY  SQLSMALLINT = -4
	SQL_BIGINT         SQLSMALLINT = -5
	SQL_TINYINT        SQLSMALLINT = -6
	SQL_BIT            SQLSMALLINT = -7
	SQL_BOOLEAN        SQLSMALLINT = 16 // DB2 BOOLEAN type
	SQL_WCHAR          SQLSMALLINT = -8
	SQL_WVARCHAR       SQLSMALLINT = -9
	SQL_WLONGVARCHAR   SQLSMALLINT = -10
	SQL_GUID           SQLSMALLINT = -11
)

SQL data types

const (
	SQL_SIGNED_OFFSET   SQLSMALLINT = -20
	SQL_UNSIGNED_OFFSET SQLSMALLINT = -22
)

C data type identifiers for binding

const (
	SQL_PARAM_INPUT        SQLSMALLINT = 1
	SQL_PARAM_INPUT_OUTPUT SQLSMALLINT = 2
	SQL_PARAM_OUTPUT       SQLSMALLINT = 4
)

Parameter input/output type

const (
	SQL_FETCH_NEXT     SQLSMALLINT = 1
	SQL_FETCH_FIRST    SQLSMALLINT = 2
	SQL_FETCH_LAST     SQLSMALLINT = 3
	SQL_FETCH_PRIOR    SQLSMALLINT = 4
	SQL_FETCH_ABSOLUTE SQLSMALLINT = 5
	SQL_FETCH_RELATIVE SQLSMALLINT = 6
)

Fetch direction

const (
	SQL_COMMIT   SQLSMALLINT = 0
	SQL_ROLLBACK SQLSMALLINT = 1
)

Transaction completion types

const (
	SQL_NO_NULLS         SQLSMALLINT = 0
	SQL_NULLABLE         SQLSMALLINT = 1
	SQL_NULLABLE_UNKNOWN SQLSMALLINT = 2
)

Nullable field values

const (
	SQL_INTERVAL_YEAR             SQLSMALLINT = 101
	SQL_INTERVAL_MONTH            SQLSMALLINT = 102
	SQL_INTERVAL_DAY              SQLSMALLINT = 103
	SQL_INTERVAL_HOUR             SQLSMALLINT = 104
	SQL_INTERVAL_MINUTE           SQLSMALLINT = 105
	SQL_INTERVAL_SECOND           SQLSMALLINT = 106
	SQL_INTERVAL_YEAR_TO_MONTH    SQLSMALLINT = 107
	SQL_INTERVAL_DAY_TO_HOUR      SQLSMALLINT = 108
	SQL_INTERVAL_DAY_TO_MINUTE    SQLSMALLINT = 109
	SQL_INTERVAL_DAY_TO_SECOND    SQLSMALLINT = 110
	SQL_INTERVAL_HOUR_TO_MINUTE   SQLSMALLINT = 111
	SQL_INTERVAL_HOUR_TO_SECOND   SQLSMALLINT = 112
	SQL_INTERVAL_MINUTE_TO_SECOND SQLSMALLINT = 113
)

SQL Interval type constants

type SQLUINTEGER

type SQLUINTEGER uint32

type SQLULEN

type SQLULEN uint64 // 64-bit for portability across platforms

type SQLUSMALLINT

type SQLUSMALLINT uint16
const (
	SQL_DRIVER_NOPROMPT          SQLUSMALLINT = 0
	SQL_DRIVER_COMPLETE          SQLUSMALLINT = 1
	SQL_DRIVER_PROMPT            SQLUSMALLINT = 2
	SQL_DRIVER_COMPLETE_REQUIRED SQLUSMALLINT = 3
)

SQLDriverConnect options

const (
	SQL_CLOSE        SQLUSMALLINT = 0
	SQL_DROP         SQLUSMALLINT = 1
	SQL_UNBIND       SQLUSMALLINT = 2
	SQL_RESET_PARAMS SQLUSMALLINT = 3
)

Free statement options

const (
	SQL_DESC_COUNT                  SQLUSMALLINT = 1001
	SQL_DESC_TYPE                   SQLUSMALLINT = 1002
	SQL_DESC_LENGTH                 SQLUSMALLINT = 1003
	SQL_DESC_OCTET_LENGTH_PTR       SQLUSMALLINT = 1004
	SQL_DESC_PRECISION              SQLUSMALLINT = 1005
	SQL_DESC_SCALE                  SQLUSMALLINT = 1006
	SQL_DESC_DATETIME_INTERVAL_CODE SQLUSMALLINT = 1007
	SQL_DESC_NULLABLE               SQLUSMALLINT = 1008
	SQL_DESC_INDICATOR_PTR          SQLUSMALLINT = 1009
	SQL_DESC_DATA_PTR               SQLUSMALLINT = 1010
	SQL_DESC_NAME                   SQLUSMALLINT = 1011
	SQL_DESC_UNNAMED                SQLUSMALLINT = 1012
	SQL_DESC_OCTET_LENGTH           SQLUSMALLINT = 1013
	SQL_DESC_ALLOC_TYPE             SQLUSMALLINT = 1099
	SQL_DESC_CONCISE_TYPE           SQLUSMALLINT = SQL_DESC_TYPE
	SQL_DESC_DISPLAY_SIZE           SQLUSMALLINT = 6
	SQL_DESC_UNSIGNED               SQLUSMALLINT = 8
	SQL_DESC_UPDATABLE              SQLUSMALLINT = 10
	SQL_DESC_AUTO_UNIQUE_VALUE      SQLUSMALLINT = 11
	SQL_DESC_TYPE_NAME              SQLUSMALLINT = 14
	SQL_DESC_TABLE_NAME             SQLUSMALLINT = 15
	SQL_DESC_SCHEMA_NAME            SQLUSMALLINT = 16
	SQL_DESC_CATALOG_NAME           SQLUSMALLINT = 17
	SQL_DESC_BASE_COLUMN_NAME       SQLUSMALLINT = 22
	SQL_DESC_BASE_TABLE_NAME        SQLUSMALLINT = 23
	SQL_DESC_LABEL                  SQLUSMALLINT = 18
	SQL_COLUMN_LENGTH               SQLUSMALLINT = 3
	SQL_COLUMN_PRECISION            SQLUSMALLINT = 4
	SQL_COLUMN_SCALE                SQLUSMALLINT = 5
)

Column attribute identifiers

const (
	SQL_DRIVER_NAME           SQLUSMALLINT = 6
	SQL_DRIVER_VER            SQLUSMALLINT = 7
	SQL_DBMS_NAME             SQLUSMALLINT = 17
	SQL_DBMS_VER              SQLUSMALLINT = 18
	SQL_DATABASE_NAME         SQLUSMALLINT = 16
	SQL_SERVER_NAME           SQLUSMALLINT = 13
	SQL_USER_NAME             SQLUSMALLINT = 47
	SQL_IDENTIFIER_QUOTE_CHAR SQLUSMALLINT = 29
	SQL_MAX_IDENTIFIER_LEN    SQLUSMALLINT = 10005
)

SQLGetInfo information types

type SQLWCHAR

type SQLWCHAR uint16 // UTF-16 on Windows

type SQL_DATE_STRUCT

type SQL_DATE_STRUCT struct {
	Year  SQLSMALLINT
	Month SQLUSMALLINT
	Day   SQLUSMALLINT
}

Date struct

type SQL_DAY_SECOND_STRUCT

type SQL_DAY_SECOND_STRUCT struct {
	Day      SQLUINTEGER
	Hour     SQLUINTEGER
	Minute   SQLUINTEGER
	Second   SQLUINTEGER
	Fraction SQLUINTEGER // billionths of a second
}

SQL_DAY_SECOND_STRUCT for day-time intervals

type SQL_GUID_STRUCT

type SQL_GUID_STRUCT struct {
	Data1 uint32
	Data2 uint16
	Data3 uint16
	Data4 [8]byte
}

GUID struct for uniqueidentifier types

func (SQL_GUID_STRUCT) String

func (g SQL_GUID_STRUCT) String() string

String returns the GUID as a formatted string (xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx)

type SQL_INTERVAL_STRUCT

type SQL_INTERVAL_STRUCT struct {
	IntervalType SQLSMALLINT
	IntervalSign SQLSMALLINT // 0 = positive, 1 = negative

	YearMonth SQL_YEAR_MONTH_STRUCT
	DaySecond SQL_DAY_SECOND_STRUCT
	// contains filtered or unexported fields
}

SQL_INTERVAL_STRUCT is the ODBC interval structure

type SQL_NUMERIC_STRUCT

type SQL_NUMERIC_STRUCT struct {
	Precision SQLCHAR
	Scale     SQLSCHAR
	Sign      SQLCHAR // 1 = positive, 0 = negative
	Val       [16]SQLCHAR
}

Numeric struct for decimal/numeric types

type SQL_TIMESTAMP_STRUCT

type SQL_TIMESTAMP_STRUCT struct {
	Year     SQLSMALLINT
	Month    SQLUSMALLINT
	Day      SQLUSMALLINT
	Hour     SQLUSMALLINT
	Minute   SQLUSMALLINT
	Second   SQLUSMALLINT
	Fraction SQLUINTEGER // billionths of a second
}

Timestamp struct for date/time binding

type SQL_TIME_STRUCT

type SQL_TIME_STRUCT struct {
	Hour   SQLUSMALLINT
	Minute SQLUSMALLINT
	Second SQLUSMALLINT
}

Time struct

type SQL_YEAR_MONTH_STRUCT

type SQL_YEAR_MONTH_STRUCT struct {
	Year  SQLUINTEGER
	Month SQLUINTEGER
}

SQL_YEAR_MONTH_STRUCT for year-month intervals

type ScrollableRows

type ScrollableRows interface {
	driver.Rows
	First() error
	Last() error
	Prior() error
	Absolute(row int64) error
	Relative(offset int64) error
}

ScrollableRows provides methods for scrollable cursor navigation. These methods are only available when the statement was prepared with PrepareWithCursor using a scrollable cursor type (CursorStatic, CursorKeyset, or CursorDynamic).

type Stmt

type Stmt struct {
	// contains filtered or unexported fields
}

Stmt implements driver.Stmt for prepared statements

func (*Stmt) Close

func (s *Stmt) Close() error

Close releases all resources associated with the prepared statement. It is safe to call Close multiple times; subsequent calls are no-ops.

func (*Stmt) Exec

func (s *Stmt) Exec(args []driver.Value) (driver.Result, error)

Exec executes a prepared statement without returning rows. Deprecated: Use ExecContext with context support instead.

func (*Stmt) ExecBatch

func (s *Stmt) ExecBatch(ctx context.Context, paramSets [][]driver.NamedValue) (*BatchResult, error)

ExecBatch executes a prepared statement with multiple parameter sets in a single batch. This uses ODBC array binding (SQL_ATTR_PARAMSET_SIZE) for efficient bulk operations. Returns a BatchResult with per-row status information.

func (*Stmt) ExecContext

func (s *Stmt) ExecContext(ctx context.Context, args []driver.NamedValue) (driver.Result, error)

ExecContext executes a prepared statement that doesn't return rows. It supports context cancellation and named/positional parameters. Returns a Result with rows affected and output parameter values.

func (*Stmt) NumInput

func (s *Stmt) NumInput() int

NumInput returns the number of placeholder parameters in the prepared statement. Returns -1 if the driver cannot determine the count.

func (*Stmt) Query

func (s *Stmt) Query(args []driver.Value) (driver.Rows, error)

Query executes a prepared statement that returns rows. Deprecated: Use QueryContext with context support instead.

func (*Stmt) QueryContext

func (s *Stmt) QueryContext(ctx context.Context, args []driver.NamedValue) (driver.Rows, error)

QueryContext executes a prepared statement that returns rows. It supports context cancellation and named/positional parameters.

type Timestamp

type Timestamp struct {
	Time      time.Time
	Precision TimestampPrecision
}

Timestamp wraps time.Time with explicit precision control

func NewTimestamp

func NewTimestamp(t time.Time, precision TimestampPrecision) Timestamp

NewTimestamp creates a Timestamp with the specified precision

type TimestampPrecision

type TimestampPrecision int

TimestampPrecision specifies the fractional seconds precision for timestamps

const (
	// TimestampPrecisionSeconds provides no fractional seconds (datetime)
	TimestampPrecisionSeconds TimestampPrecision = 0
	// TimestampPrecisionMilliseconds provides 3 digits (default, datetime2(3))
	TimestampPrecisionMilliseconds TimestampPrecision = 3
	// TimestampPrecisionMicroseconds provides 6 digits (datetime2(6))
	TimestampPrecisionMicroseconds TimestampPrecision = 6
	// TimestampPrecisionNanoseconds provides 9 digits (max ODBC precision)
	TimestampPrecisionNanoseconds TimestampPrecision = 9
)

type TimestampTZ

type TimestampTZ struct {
	Time      time.Time
	Precision TimestampPrecision
	TZ        *time.Location // nil means use connection default (UTC)
}

TimestampTZ represents a timestamp with timezone awareness

func NewTimestampTZ

func NewTimestampTZ(t time.Time, precision TimestampPrecision, tz *time.Location) TimestampTZ

NewTimestampTZ creates a timezone-aware timestamp

type Tx

type Tx struct {
	// contains filtered or unexported fields
}

Tx implements driver.Tx for transaction support

func (*Tx) Commit

func (t *Tx) Commit() error

Commit commits the transaction. If the commit succeeds, autocommit is re-enabled for subsequent operations.

func (*Tx) Rollback

func (t *Tx) Rollback() error

Rollback rolls back the transaction. If the rollback succeeds, autocommit is re-enabled for subsequent operations.

type WideString

type WideString string

WideString wraps a Go string for explicit UTF-16 (NVARCHAR/NCHAR) binding. Use this when inserting into Unicode columns that require wide character encoding.

Directories

Path Synopsis
examples
basic command
Package main provides a basic example of using the godbc ODBC driver.
Package main provides a basic example of using the godbc ODBC driver.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL