OriginChainDB docs
examples · tds · 2 / 5

2. Connect with microsoft/go-mssqldb

← SQL Server wire examples
what this does

The same session as the JDBC example, over Microsoft's Go driver, with the DSN built through net/url so a password containing a reserved character cannot quietly corrupt it. Measured against microsoft/go-mssqldb 1.11.0, 21 of 21 checks, on 2026-09-07.

the code
package main

import (
	"database/sql"
	"fmt"
	"net/url"
	"os"

	_ "github.com/microsoft/go-mssqldb"
)

func dsn() string {
	q := url.Values{}
	q.Set("database", os.Getenv("OC_DATABASE"))
	q.Set("encrypt", "true")                 // mandatory - the only way in
	q.Set("TrustServerCertificate", "false") // validate the chain
	q.Set("dial timeout", "30")

	u := url.URL{
		Scheme: "sqlserver",
		// url.UserPassword escapes for you. Never build this by hand.
		User:     url.UserPassword(os.Getenv("OC_DB_USER"), os.Getenv("OC_DB_PASSWORD")),
		Host:     os.Getenv("OC_SQL_HOST") + ":1433",
		RawQuery: q.Encode(),
	}
	return u.String()
}

func main() {
	db, err := sql.Open("sqlserver", dsn())
	if err != nil {
		panic(err)
	}
	defer db.Close()

	// sql.Open is lazy. Ping is the first thing that actually connects.
	if err := db.Ping(); err != nil {
		panic(err)
	}

	rows, err := db.Query(
		"SELECT TOP 5 id, customer_ref, amount_cents"+
			"  FROM invoices WHERE status = @p1 ORDER BY amount_cents DESC",
		"open")
	if err != nil {
		panic(err)
	}
	defer rows.Close()

	for rows.Next() {
		var id, cents int
		var ref string
		if err := rows.Scan(&id, &ref, &cents); err != nil {
			panic(err)
		}
		fmt.Printf("%d  %-12s %d\n", id, ref, cents)
	}
	if err := rows.Err(); err != nil {
		panic(err)
	}
}
the result shape
4101  ACME-77       129900
4088  ACME-12        98450
4077  ORBIT-3        61000
4051  ACME-77        44900
4020  ORBIT-9        12750
notes
  • sql.Open does not connect. If a listener is missing or a certificate is unloadable you will not learn it until Ping or the first query, so call Ping at start-up rather than discovering it inside a request.
  • This driver names parameters @p1, @p2, and so on. That is the driver's placeholder syntax and it is fine — it is rewritten to a positional bind before the statement reaches the engine. It is not the same thing as a T-SQL @variable, which is refused.
  • Leave TrustServerCertificate at false. Turning it on does not make a broken listener work — there is no listener to reach when the certificate is the problem — it only stops you noticing who you are talking to.

Microsoft, SQL Server and T-SQL are trademarks of the Microsoft group of companies; go-mssqldb is Microsoft's own driver. Named here only to describe protocol compatibility and to identify the version it was measured against. OriginChainDB is not affiliated with, endorsed by, or sponsored by Microsoft, and does not distribute Microsoft software.