The New Go-Based sqlcmd: What Changed

You type sqlcmd and expect the old utility, but another executable answers. The Go-based sqlcmd adds commands and contexts while keeping only tested compatibility with old scripts.

Two identical white eggs spinning on a kitchen counter, one smooth and one wobbling, a hand hovering above

Two Programs Share One Name

Microsoft has an ODBC based sqlcmd and a Go based sqlcmd. Both can run T-SQL, but they are separate implementations. The Go program is distributed independently and includes modern subcommands. The ODBC program comes with SQL Server command line utilities.

I check which executable Windows finds before debugging a script. PATH order can switch the program without changing the command typed in a job. Use where.exe and the variant’s version help. Record the full path in important automation.

Which sqlcmd did the job run yesterday? If the answer is “whichever was first on PATH,” the script has a hidden dependency. Pin the intended executable or control PATH.

REM Command line
where.exe sqlcmd.exe

Go-Based sqlcmd Commands Have Their Own Help

The Go variant has subcommands for configuration, querying a selected context, and other tasks. Its double dash help describes the modern command surface. Its question mark help describes compatibility flags familiar from the older utility. Read both before translating a script.

A context can simplify repeated local commands, but it also changes where a query goes. Inspect the selected context before a destructive operation. Keep production scripts explicit about the server and authentication path. Convenience should not hide the target.

I use the modern commands for a new workflow only after a small test. A job built around old flags should not be rewritten just because the new help screen looks pleasant.

REM Command line
sqlcmd --version
sqlcmd --help
sqlcmd -?

Legacy Flags Are Not Identical in Go-Based sqlcmd

The Go utility supports many familiar flags, but some flags and behaviors differ from ODBC sqlcmd. Microsoft documents changed and missing compatibility options. For example, the error stream flag has had different argument handling, and some older switches are absent. Check the release you install rather than trusting a note about an earlier Go build.

Search your scripts for every sqlcmd option. Mark each one as tested, changed, or unsupported on the selected Go version. Do not assume an unrecognized option fails in the way your scheduler expects. Capture stderr, stdout, and exit code from a real test.

A short script inventory beats discovering the difference during a restore window.

Compare Script Output Exactly

A command can succeed while output formatting changes. Check headers, whitespace, encoding, NULL display, and error text if another program parses stdout. Run the same read only query through both variants and compare the files. Avoid parsing a human formatted grid when a machine readable export is required.

I watch scripts that use sqlcmd variables, GO batch separators, included files, and SQLCMD mode commands. Test each feature the job actually uses. A simple SELECT from a command prompt is not a complete migration test for a deployment script.

Keep a known small input script in the test kit. The same script should run under both versions and produce an expected result or a documented difference.

SELECT
    @@SERVERNAME AS ConnectedInstance,
    SERVERPROPERTY('ProductVersion') AS ProductVersion;
Two programs, one name: a diagram about the Go-based sqlcmd

Test Errors and Exit Codes

Automation needs to stop when SQL fails. Test a deliberate SQL error on a disposable database and inspect the process exit code for the flags your job uses. Do not infer failure handling from a successful query. A scheduler only sees the process result and whatever log you keep.

Use a safe read only error test rather than a destructive command. Document the exact invocation and expected exit behavior for the variant you deploy. Check whether messages go to stdout or stderr. A monitoring rule that watches one stream can miss the other.

I make this test before moving a backup or deployment job. The boring error path is the one that saves you when the real operation fails.

Check Authentication and Encryption

The two implementations use different underlying client stacks. Test Windows authentication, SQL authentication, certificate trust, and encryption options through the real target. A connection that works in the ODBC variant does not certify the Go variant.

Do not put passwords in command line arguments or shared script files. Use an approved secret mechanism and review the utility’s supported options. Keep the server name aligned with its certificate when validation is required.

A failed connection is not proof that the SQL Server engine is down. Capture the exact client error and confirm which utility produced it. The fix can belong in the client configuration.

Keep bcp Separate

The Go-based sqlcmd does not replace bcp. bcp is a separate bulk copy utility distributed with the Microsoft command line utilities. A workstation can therefore have Go sqlcmd first on PATH while bcp comes from the ODBC utilities package.

Check versions separately. A server CU does not update every client executable. Record which versions your automation uses, especially on build agents and scheduled task hosts.

I have seen a tool change described as “we updated SQL Server” when only the PATH changed on a job machine. Clear names and paths keep the investigation short.

Migrate One Job at a Time to Go-Based sqlcmd

Start with a low risk read only script. Compare output and exit behavior. Then test a representative deployment or maintenance script in a lab. Keep the old executable available under its full path until the new path has passed the relevant job cycle.

Update the runbook with the variant, version, full executable path, flags, authentication method, and expected output. Review PATH after any tool installation. A future utility update should not silently change the script contract.

The Go variant can be a useful tool. Treat its adoption as a client migration, with evidence for each script that matters.

Related reading on this blog: SQL SERVER Management Studio and SQLCMD Mode and Performance Test: sqlcmd vs SSMS.

Moving one job at a time: a checklist on the Go-based sqlcmd

A shared command name is not shared behavior, it is a reason to test the script that calls it.

Published by Pinal Dave on SQLAuthority. More of my work at pinaldave.com.

Command Line, SQL Server, SQL Utility, sqlcmd
Previous Post
SQL SERVER – Simple Explanation of Data Type Precedence
Next Post
SQL SERVER – Encrypted Stored Procedure and Activity Monitor

Related Posts

1 Comment. Leave new

Leave a Reply

Your email address will not be published. Required fields are marked *

Fill out this field
Fill out this field
Please enter a valid email address.