• Home
  • History
  • Annotate
Name Date Size #Lines LOC

..24-Mar-2022-

internal/H24-Mar-2022-64,93664,821

msdsn/H24-Mar-2022-680526

.gitignoreH A D24-Mar-2022133 1513

.golangci.ymlH A D24-Mar-2022145 119

README.mdH A D24-Mar-202215.9 KiB349260

accesstokenconnector.goH A D24-Mar-2022820 3221

appveyor.ymlH A D24-Mar-20221.8 KiB7061

buf.goH A D24-Mar-20225.5 KiB272219

bulkcopy.goH A D24-Mar-202215 KiB599507

bulkcopy_sql.goH A D24-Mar-20221.7 KiB9472

convert.goH A D24-Mar-20227 KiB307268

doc.goH A D24-Mar-2022643 151

error.goH A D24-Mar-20222.6 KiB11872

fedauth.goH A D24-Mar-20223.1 KiB7938

log.goH A D24-Mar-20222.1 KiB7242

mssql.goH A D24-Mar-202233.3 KiB1,281982

mssql_go110.goH A D24-Mar-20221.1 KiB5339

mssql_go110pre.goH A D24-Mar-2022565 3227

mssql_go118.goH A D24-Mar-2022492 156

mssql_go118pre.goH A D24-Mar-2022525 187

mssql_go19.goH A D24-Mar-20225.5 KiB208172

mssql_go19pre.goH A D24-Mar-2022418 2114

net.goH A D24-Mar-20223.4 KiB169134

ntlm.goH A D24-Mar-202212.5 KiB394315

rpc.goH A D24-Mar-20221.8 KiB8475

sspi_windows.goH A D24-Mar-20226.8 KiB267241

tds.goH A D24-Mar-202232.7 KiB1,2911,068

token.goH A D24-Mar-202223.8 KiB955766

token_string.goH A D24-Mar-20221.2 KiB4841

tran.goH A D24-Mar-20222.5 KiB11199

tvp_go19.goH A D24-Mar-20227.6 KiB294260

types.goH A D24-Mar-202237.6 KiB1,5831,420

uniqueidentifier.goH A D24-Mar-20221.7 KiB8162

README.md

1# A pure Go MSSQL driver for Go's database/sql package
2
3[![Go Reference](https://pkg.go.dev/badge/github.com/denisenkom/go-mssqldb.svg)](https://pkg.go.dev/github.com/denisenkom/go-mssqldb)
4[![Build status](https://ci.appveyor.com/api/projects/status/jrln8cs62wj9i0a2?svg=true)](https://ci.appveyor.com/project/denisenkom/go-mssqldb)
5[![codecov](https://codecov.io/gh/denisenkom/go-mssqldb/branch/master/graph/badge.svg)](https://codecov.io/gh/denisenkom/go-mssqldb)
6
7## Install
8
9Requires Go 1.8 or above.
10
11Install with `go get github.com/denisenkom/go-mssqldb` .
12
13## Connection Parameters and DSN
14
15The recommended connection string uses a URL format:
16`sqlserver://username:password@host/instance?param1=value&param2=value`
17Other supported formats are listed below.
18
19### Common parameters
20
21* `user id` - enter the SQL Server Authentication user id or the Windows Authentication user id in the DOMAIN\User format. On Windows, if user id is empty or missing Single-Sign-On is used. The user domain sensitive to the case which is defined in the connection string.
22* `password`
23* `database`
24* `connection timeout` - in seconds (default is 0 for no timeout), set to 0 for no timeout. Recommended to set to 0 and use context to manage query and connection timeouts.
25* `dial timeout` - in seconds (default is 15), set to 0 for no timeout
26* `encrypt`
27  * `disable` - Data send between client and server is not encrypted.
28  * `false` - Data sent between client and server is not encrypted beyond the login packet. (Default)
29  * `true` - Data sent between client and server is encrypted.
30* `app name` - The application name (default is go-mssqldb)
31
32### Connection parameters for ODBC and ADO style connection strings
33
34* `server` - host or host\instance (default localhost)
35* `port` - used only when there is no instance in server (default 1433)
36
37### Less common parameters
38
39* `keepAlive` - in seconds; 0 to disable (default is 30)
40* `failoverpartner` - host or host\instance (default is no partner).
41* `failoverport` - used only when there is no instance in failoverpartner (default 1433)
42* `packet size` - in bytes; 512 to 32767 (default is 4096)
43  * Encrypted connections have a maximum packet size of 16383 bytes
44  * Further information on usage: <https://docs.microsoft.com/en-us/sql/database-engine/configure-windows/configure-the-network-packet-size-server-configuration-option>
45* `log` - logging flags (default 0/no logging, 63 for full logging)
46  * 1 log errors
47  * 2 log messages
48  * 4 log rows affected
49  * 8 trace sql statements
50  * 16 log statement parameters
51  * 32 log transaction begin/end
52* `TrustServerCertificate`
53  * false - Server certificate is checked. Default is false if encypt is specified.
54  * true - Server certificate is not checked. Default is true if encrypt is not specified. If trust server certificate is true, driver accepts any certificate presented by the server and any host name in that certificate. In this mode, TLS is susceptible to man-in-the-middle attacks. This should be used only for testing.
55* `certificate` - The file that contains the public key certificate of the CA that signed the SQL Server certificate. The specified certificate overrides the go platform specific CA certificates.
56* `hostNameInCertificate` - Specifies the Common Name (CN) in the server certificate. Default value is the server host.
57* `ServerSPN` - The kerberos SPN (Service Principal Name) for the server. Default is MSSQLSvc/host:port.
58* `Workstation ID` - The workstation name (default is the host name)
59* `ApplicationIntent` - Can be given the value `ReadOnly` to initiate a read-only connection to an Availability Group listener. The `database` must be specified when connecting with `Application Intent` set to `ReadOnly`.
60
61### The connection string can be specified in one of three formats
62
631. URL: with `sqlserver` scheme. username and password appears before the host. Any instance appears as
64    the first segment in the path. All other options are query parameters. Examples:
65
66    * `sqlserver://username:password@host/instance?param1=value&param2=value`
67    * `sqlserver://username:password@host:port?param1=value&param2=value`
68    * `sqlserver://sa@localhost/SQLExpress?database=master&connection+timeout=30` // `SQLExpress instance.
69    * `sqlserver://sa:mypass@localhost?database=master&connection+timeout=30`     // username=sa, password=mypass.
70    * `sqlserver://sa:mypass@localhost:1234?database=master&connection+timeout=30` // port 1234 on localhost.
71    * `sqlserver://sa:my%7Bpass@somehost?connection+timeout=30` // password is "my{pass"
72      A string of this format can be constructed using the `URL` type in the `net/url` package.
73
74    ```go
75
76    query := url.Values{}
77    query.Add("app name", "MyAppName")
78
79    u := &url.URL{
80    	Scheme:   "sqlserver",
81    	User:     url.UserPassword(username, password),
82    	Host:     fmt.Sprintf("%s:%d", hostname, port),
83    	// Path:  instance, // if connecting to an instance instead of a port
84    	RawQuery: query.Encode(),
85    }
86    db, err := sql.Open("sqlserver", u.String())
87
88    ```
89
902. ADO: `key=value` pairs separated by `;`. Values may not contain `;`, leading and trailing whitespace is ignored.
91     Examples:
92
93    * `server=localhost\\SQLExpress;user id=sa;database=master;app name=MyAppName`
94    * `server=localhost;user id=sa;database=master;app name=MyAppName`
95
96    ADO strings support synonyms for database, app name, user id, and server
97    * server <= addr, address, network address, data source
98    * user id <= user, uid
99    * database <= initial catalog
100    * app name <= application name
101
1023. ODBC: Prefix with `odbc`, `key=value` pairs separated by `;`. Allow `;` by wrapping
103    values in `{}`. Examples:
104
105    * `odbc:server=localhost\\SQLExpress;user id=sa;database=master;app name=MyAppName`
106    * `odbc:server=localhost;user id=sa;database=master;app name=MyAppName`
107    * `odbc:server=localhost;user id=sa;password={foo;bar}` // Value marked with `{}`, password is "foo;bar"
108    * `odbc:server=localhost;user id=sa;password={foo{bar}` // Value marked with `{}`, password is "foo{bar"
109    * `odbc:server=localhost;user id=sa;password={foobar }` // Value marked with `{}`, password is "foobar "
110    * `odbc:server=localhost;user id=sa;password=foo{bar`   // Literal `{`, password is "foo{bar"
111    * `odbc:server=localhost;user id=sa;password=foo}bar`   // Literal `}`, password is "foo}bar"
112    * `odbc:server=localhost;user id=sa;password={foo{bar}` // Literal `{`, password is "foo{bar"
113    * `odbc:server=localhost;user id=sa;password={foo}}bar}` // Escaped `} with`}}`, password is "foo}bar"
114
115### Azure Active Directory authentication
116
117Azure Active Directory authentication uses temporary authentication tokens to authenticate.
118The `mssql` package does not provide an implementation to obtain tokens: instead, import the `azuread` package and use driver name `azuresql`. This driver uses [azidentity](https://pkg.go.dev/github.com/Azure/azure-sdk-for-go/sdk/azidentity#section-readme) to acquire tokens using a variety of credential types.
119
120The credential type is determined by the new `fedauth` connection string parameter.
121
122* `fedauth=ActiveDirectoryServicePrincipal` or `fedauth=ActiveDirectoryApplication` - authenticates using an Azure Active Directory application client ID and client secret or certificate. Implemented using [ClientSecretCredential or CertificateCredential](https://github.com/Azure/azure-sdk-for-go/tree/main/sdk/azidentity#authenticating-service-principals)
123  * `clientcertpath=<path to certificate file>;password=<certificate password>` or
124  * `password=<client secret>`
125  * `user id=<application id>[@tenantid]` Note the `@tenantid` component can be omitted if the server's tenant is the same as the application's tenant.
126* `fedauth=ActiveDirectoryPassword` - authenticates using a user name and password.
127  * `user id=username@domain`
128  * `password=<password>`
129  * `applicationclientid=<application id>` - This guid identifies an Azure Active Directory enterprise application that the AAD admin has approved for accessing Azure SQL database resources in the tenant. This driver does not have an associated application id of its own.
130* `fedauth=ActiveDirectoryDefault` - authenticates using a chained set of credentials. The chain is built from EnvironmentCredential -> ManagedIdentityCredential->AzureCLICredential.  See [DefaultAzureCredential docs](https://github.com/Azure/azure-sdk-for-go/wiki/Set-up-Your-Environment-for-Authentication#configure-defaultazurecredential) for instructions on setting up your host environment to use it. Using this option allows you to have the same connection string in a service deployment as on your interactive development machine.
131* `fedauth=ActiveDirectoryManagedIdentity` or `fedauth=ActiveDirectoryMSI` - authenticates using a system-assigned or user-assigned Azure Managed Identity.
132  * `user id=<identity id>` - optional id of user-assigned managed identity. If empty, system-assigned managed identity is used.
133* `fedauth=ActiveDirectoryInteractive` - authenticates using credentials acquired from an external web browser. Only suitable for use with human interaction.
134  * `applicationclientid=<application id>` - This guid identifies an Azure Active Directory enterprise application that the AAD admin has approved for accessing Azure SQL database resources in the tenant. This driver does not have an associated application id of its own.
135
136```go
137
138import (
139  "database/sql"
140  "net/url"
141
142  // Import the Azure AD driver module (also imports the regular driver package)
143  "github.com/denisenkom/go-mssqldb/azuread"
144)
145
146func ConnectWithMSI() (*sql.DB, error) {
147  return sql.Open(azuread.DriverName, "sqlserver://azuresql.database.windows.net?database=yourdb&fedauth=ActiveDirectoryMSI")
148}
149
150```
151
152## Executing Stored Procedures
153
154To run a stored procedure, set the query text to the procedure name:
155
156```go
157
158var account = "abc"
159_, err := db.ExecContext(ctx, "sp_RunMe",
160	sql.Named("ID", 123),
161	sql.Named("Account", sql.Out{Dest: &account}),
162)
163
164```
165
166## Reading Output Parameters from a Stored Procedure with Resultset
167
168To read output parameters from a stored procedure with resultset, make sure you read all the rows before reading the output parameters:
169
170```go
171
172sqltextcreate := `
173CREATE PROCEDURE spwithoutputandrows
174	@bitparam BIT OUTPUT
175AS BEGIN
176	SET @bitparam = 1
177	SELECT 'Row 1'
178END
179`
180var bitout int64
181rows, err := db.QueryContext(ctx, "spwithoutputandrows", sql.Named("bitparam", sql.Out{Dest: &bitout}))
182var strrow string
183for rows.Next() {
184	err = rows.Scan(&strrow)
185}
186fmt.Printf("bitparam is %d", bitout)
187
188```
189
190## Caveat for local temporary tables
191
192Due to protocol limitations, temporary tables will only be allocated on the connection
193as a result of executing a query with zero parameters. The following query
194will, due to the use of a parameter, execute in its own session,
195and `#mytemp` will be de-allocated right away:
196
197```go
198conn, err := pool.Conn(ctx)
199defer conn.Close()
200_, err := conn.ExecContext(ctx, "select @p1 as x into #mytemp", 1)
201// at this point #mytemp is already dropped again as the session of the ExecContext is over
202```
203
204To work around this, always explicitly create the local temporary
205table in a query without any parameters. As a special case, the driver
206will then be able to execute the query directly on the
207connection-scoped session. The following example works:
208
209```go
210conn, err := pool.Conn(ctx)
211
212// Set us up so that temp table is always cleaned up, since conn.Close()
213// merely returns conn to pool, rather than actually closing the connection.
214defer func() {
215	_, _ = conn.ExecContext(ctx, "drop table #mytemp")  // always clean up
216	conn.Close() // merely returns conn to pool
217}()
218
219
220// Since we not pass any parameters below, the query will execute on the scope of
221// the connection and succeed in creating the table.
222_, err := conn.ExecContext(ctx, "create table #mytemp ( x int )")
223
224// #mytemp is now available even if you pass parameters
225_, err := conn.ExecContext(ctx, "insert into #mytemp (x) values (@p1)", 1)
226
227```
228
229## Return Status
230
231To get the procedure return status, pass into the parameters a
232`*mssql.ReturnStatus`. For example:
233
234```go
235
236var rs mssql.ReturnStatus
237_, err := db.ExecContext(ctx, "theproc", &rs)
238log.Printf("status=%d", rs)
239
240```
241
242or
243
244```go
245var rs mssql.ReturnStatus
246_, err := db.QueryContext(ctx, "theproc", &rs)
247for rows.Next() {
248	err = rows.Scan(&val)
249}
250log.Printf("status=%d", rs)
251
252```
253
254Limitation: ReturnStatus cannot be retrieved using `QueryRow`.
255
256## Parameters
257
258The `sqlserver` driver uses normal MS SQL Server syntax and expects parameters in
259the sql query to be in the form of either `@Name` or `@p1` to `@pN` (ordinal position).
260
261```go
262
263db.QueryContext(ctx, `select * from t where ID = @ID and Name = @p2;`, sql.Named("ID", 6), "Bob")
264
265```
266
267### Parameter Types
268
269To pass specific types to the query parameters, say `varchar` or `date` types,
270you must convert the types to the type before passing in. The following types
271are supported:
272
273* string -> nvarchar
274* mssql.VarChar -> varchar
275* time.Time -> datetimeoffset or datetime (TDS version dependent)
276* mssql.DateTime1 -> datetime
277* mssql.DateTimeOffset -> datetimeoffset
278* "github.com/golang-sql/civil".Date -> date
279* "github.com/golang-sql/civil".DateTime -> datetime2
280* "github.com/golang-sql/civil".Time -> time
281* mssql.TVP -> Table Value Parameter (TDS version dependent)
282
283## Important Notes
284
285* [LastInsertId](https://golang.org/pkg/database/sql/#Result.LastInsertId) should
286    not be used with this driver (or SQL Server) due to how the TDS protocol
287 works. Please use the [OUTPUT Clause](https://docs.microsoft.com/en-us/sql/t-sql/queries/output-clause-transact-sql)
288 or add a `select ID = convert(bigint, SCOPE_IDENTITY());` to the end of your
289 query (ref [SCOPE_IDENTITY](https://docs.microsoft.com/en-us/sql/t-sql/functions/scope-identity-transact-sql)).
290 This will ensure you are getting the correct ID and will prevent a network round trip.
291* [NewConnector](https://godoc.org/github.com/denisenkom/go-mssqldb#NewConnector)
292    may be used with [OpenDB](https://golang.org/pkg/database/sql/#OpenDB).
293* [Connector.SessionInitSQL](https://godoc.org/github.com/denisenkom/go-mssqldb#Connector.SessionInitSQL)
294 may be set to set any driver specific session settings after the session
295 has been reset. If empty the session will still be reset but use the database
296 defaults in Go1.10+.
297
298## Features
299
300* Can be used with SQL Server 2005 or newer
301* Can be used with Microsoft Azure SQL Database
302* Can be used on all go supported platforms (e.g. Linux, Mac OS X and Windows)
303* Supports new date/time types: date, time, datetime2, datetimeoffset
304* Supports string parameters longer than 8000 characters
305* Supports encryption using SSL/TLS
306* Supports SQL Server and Windows Authentication
307* Supports Single-Sign-On on Windows
308* Supports connections to AlwaysOn Availability Group listeners, including re-direction to read-only replicas.
309* Supports query notifications
310
311## Tests
312
313`go test` is used for testing. A running instance of MSSQL server is required.
314Environment variables are used to pass login information.
315
316Example:
317
318```bash
319    env SQLSERVER_DSN=sqlserver://user:pass@hostname/instance?database=test1 go test
320```
321
322`AZURESERVER_DSN` environment variable provides the connection string for Azure Active Directory-based authentication. If it's not set the AAD test will be skipped.
323
324## Deprecated
325
326These features still exist in the driver, but they are are deprecated.
327
328### Query Parameter Token Replace (driver "mssql")
329
330If you use the driver name "mssql" (rather then "sqlserver") the SQL text
331will be loosly parsed and an attempt to extract identifiers using one of
332
333* ?
334* ?nnn
335* :nnn
336* $nnn
337
338will be used. This is not recommended with SQL Server.
339There is at least one existing `won't fix` issue with the query parsing.
340
341Use the native "@Name" parameters instead with the "sqlserver" driver name.
342
343## Known Issues
344
345* SQL Server 2008 and 2008 R2 engine cannot handle login records when SSL encryption is not disabled.
346To fix SQL Server 2008 R2 issue, install SQL Server 2008 R2 Service Pack 2.
347To fix SQL Server 2008 issue, install Microsoft SQL Server 2008 Service Pack 3 and Cumulative update package 3 for SQL Server 2008 SP3.
348More information: <http://support.microsoft.com/kb/2653857>
349