sqlcmd: Run SQL Against SQL Server in CI
sqlcmd -S host -U user -P pass -Q "SQL" runs a batch against SQL Server and exits.
sqlcmd is the command-line client for Microsoft SQL Server. In CI you point -S at the server, authenticate with -U/-P, and run a batch with -Q or a script with -i, adding -b so a SQL error fails the job.
What it does
sqlcmd connects to a SQL Server instance and executes T-SQL. -Q runs a query and then exits, -q runs a query and stays interactive, and -i reads a script file. By default sqlcmd returns 0 even after a SQL error; -b makes it return the error level so CI can detect failures.
Common usage
# run one batch and exit
sqlcmd -S db -U sa -P "$SA_PASSWORD" -Q "SELECT @@VERSION"
# run a script, fail the job on error
sqlcmd -S db -U sa -P "$SA_PASSWORD" -b -i migrate.sql
# target a database, trust the server cert (dev only)
sqlcmd -S db -U sa -P "$SA_PASSWORD" -d appdb -C -Q "SELECT 1"Options
| Flag | What it does |
|---|---|
| -S <server> | Server name (host or host,port) |
| -U <user> / -P <pass> | SQL login user and password |
| -Q "<sql>" | Run a batch and exit |
| -i <file> | Read T-SQL from a script file |
| -d <db> | Database to use |
| -b | Return an error level on SQL error (fail the job) |
| -C | Trust the server certificate (skip TLS validation) |
In CI
Always add -b so a failing batch returns non-zero; without it a broken migration still exits 0. Newer sqlcmd (v18+, ODBC 18) encrypts by default and validates the certificate, so a self-signed dev server needs -C (trust) or -N (encryption control). Wait for SQL Server to finish starting (it is slow) before the first connection.
Common errors in CI
"Login failed for user \"sa\"." means the wrong -P password or a disabled login. "A network-related or instance-specific error ... server was not found or was not accessible" means the server is not up yet or -S is wrong; wait and retry. "SSL Provider: ... certificate chain was issued by an authority that is not trusted" from sqlcmd 18+ means add -C for a self-signed dev cert. Use host,port (comma) in -S, not host:port.