Skip to content

Troubleshooting and supportability

David Shiflet edited this page Feb 14, 2023 · 2 revisions

Overview

Unlike most components delivered by the SQL Server team at Microsoft, go-sqlcmd is not a traditional application built in C++ or C#/.Net, nor does it use ODBC or client libraries that the support team has a lot of experience with.

When you run into unexpected errors with go-sqlcmd, try some of the following approaches to narrow down the source of the problem. Once you identify the source of the issue, open an issue or support case through the appropriate channel.

Enable tracing

Sqlcmd offers two options for enhanced tracing, one for "modern" CLI mode and one for the legacy ODBC-compatible mode.

Modern CLI

Use the -v flag with 3 or 4

 -v, --verbosity int              Log level, error=0, warn=1, info=2, debug=3, trace=4 (default 2)

These traces are generated directly by the sqlcmd application but do not include go-mssqldb driver traces. If you are having issues with sqlcmd query that look like TSQL problems, switch to legacy mode and enable driver traces.

Legacy mode

Use the --driver_logging_level=65 parameter to enable output of all driver-level traces.

 9:50:54.59 E:\git\go-sqlcmd>.\sqlcmd --driver-logging-level=65
DRIVER:Dialing with protocol np
DRIVER:Returning connection from protocol np
DRIVER:Starting SSPI login
DRIVER:got token tokenSSPI
DRIVER:got token tokenSSPI
DRIVER:got token tokenSSPI
DRIVER:got token tokenEnvChange
DRIVER:got token tokenInfo
DRIVER:got INFO 5701 Changed database context to 'master'.
DRIVER:got token tokenEnvChange
DRIVER:got token tokenEnvChange
DRIVER:got token tokenInfo
DRIVER:got INFO 5703 Changed language setting to us_english.
DRIVER:got token tokenLoginAck
DRIVER:got token tokenEnvChange
DRIVER:got token tokenDone
DRIVER:got DONE or DONEPROC status=0
1> select 1
2> go
DRIVER:got token tokenEnvChange
DRIVER:got token tokenColMetadata
DRIVER:got token tokenRow
DRIVER:got token tokenDone
DRIVER:got DONE or DONEPROC status=16
DRIVER:Columns() token type:[]mssql.columnStruct
DRIVER:Next() token type:[]interface {}

-----------
          1
DRIVER:Next() token type:mssql.doneStruct

(1 row affected)
1>

Consuming traces

Ideally, the trace messages themselves will provide sufficient insight into the problem that you can make appropriate changes to your environment to resolve the problem. In some instances, the message might be cryptic and you need further context to understand it. You can leverage the fact that sqlcmd is now open source and search github.com using the message to find its source.

Caveats

  • Because github.com/microsoft/go-mssqldb is a fork, the search UI on github.com will not scan it. You'll need to clone it locally to search it. Any trace prefixed with DRIVER: is coming from the go-mssqldb code.

  • Having some knowledge of the go language is required to understand the source of the traces.

Open issues on Github

Data to include in a new issue (with any private data obscured):

  • Verbose traces
  • Full command line showing where sqlcmd binary is installed and all flags
  • Values of SQLCMD environment variables
  • Edition of SQL Server being queried
  • Host operating system version and CPU architecture
  • How sqlcmd was installed (package manager/github download/etc)

Go-mssqldb

For issues specific to querying a SQL Server instance that appear to be TDS protocol or driver level, open an issue at https://github.com/microsoft/go-mssqldb/issues.

Go-sqlcmd

Non-TSQL specific issues should go to http://github.com/microsoft/go-sqlcmd/issues.

Debugging

Applications built with go require a different set of debugging tools than those built with C++ or C#. Our recommendations are VS Code with the Go extension provided by Google and Goland by Jetbrains.

Start by installing Go 1.19+.

Clone the go-mssqldb and go-sqlcmd repos locally.

Debug with VS Code

Once VS Code is installed, get the Go extension. Open the go-sqlcmd clone in VS Code and edit .vscode/launch.json to add entries that can reproduce the problem. This sample enables 3 scenarios.

  • attach to a running instance
  • run a query provided by the -Q flag
  • run a query using the named pipe protocol and importing the query text from a file
{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Attach to Process",
            "type": "go",
            "request": "attach",
            "mode": "local",
            "processId": 0
        },
        {
            "name" : "Run query and exit",
            "type" : "go",
            "request": "launch",
            "mode" : "auto",
            "program": "${workspaceFolder}/cmd/modern",
            "args" : ["-Q", "EXIT(select net_transport from sys.dm_exec_connections)"],
        },
        {
            "name" : "Run file query",
            "type" : "go",
            "request": "launch",
            "mode" : "auto",
            "program": "${workspaceFolder}/cmd/modern",
            "args" : ["-S", "np:.", "-i", "${workspaceFolder}/cmd/sqlcmd/testdata/select100.sql"],
        },
    ]
}

You can now pick the appropriate scenario to run from the RUN AND DEBUG tab in VS Code. You can set breakpoints on the code files etc.

Debug with Goland