OriginChainDB
Sqlserver

Connect Go to an existing TDS listener

← SQL Server wire examples

Use go-mssqldb over TLS. Build its URL safely so special characters in credentials are encoded.

Before you run it: Keep certificate validation on. The driver-bound @p1 parameter is not a general T-SQL variable.

Load the invoice sample first. Add the github.com/microsoft/go-mssqldb driver to your Go module. A DSN is the connection address plus settings; net/url encodes its credential fields safely. The four environment variables identify the existing host, database, user and password.

Build a safe Go connection and test itsql.Open creates a handle; Ping verifies that the connection works.
  1. Load the invoice sampleUse the existing preview listener and test database.
  2. Build the connection URLUse net/url to encode credentials and keep TLS verification.
  3. Open and pingCheck connectivity before issuing an application request.
  4. Run the bound queryPass the value through @p1 and inspect the invoices.

Follow the example

  1. Confirm the existing preview listener is available.
  2. Build the DSN with net/url.
  3. Open the handle and call Ping.
  4. Run the bound-parameter query.

Run the example

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)
	}
}

Check the result

Ping checks the connection because sql.Open alone may not connect.

4101  ACME-77       129900
4088  ACME-12        98450
4077  ORBIT-3        61000
4051  ACME-77        44900
4020  ORBIT-9        12750

Important details

  • 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.

Recorded driver check: microsoft/go-mssqldb 1.11.0, 21 of 21 checks, on 2026-09-07. This is a historical test record.

Continue

Continue to reuse a parameterized statement.

© 2026 Silicoyn Technologies Pvt Ltd

On this page