Search code examples
t-sqlbatch-filecmderror-handlingsqlcmd

How to conditionally exit .BAT file from SQL code run through SQLCMD


I have a .bat (Windows command) file that includes invocations of SQLCMD and other commands. (Of course SQLCMD is sending my T-SQL code to SQL Server.) I want to detect certain conditions in the SQL code, and conditionally exit the entire batch file. I've tried various combinations of RAISERROR, THROW, and deliberate division by 0 (I'm not proud) along with various command line switches on SQLCMD and handling of errorlevel in the .bat file.

I tried the answer to 5789568 but could not get it to work in my case. Here are two files which show one failed attempt. It tries to abort if there are more than 3 tables. But it doesn't abort the bat file, as you can see when the final command (echo) executes. It doesn't even abort the run of SQLCMD, as you can see when it tells you how many tables there are.

example.bat

set ERRORLEVEL=0
sqlcmd -b -S dbread.vistaprint.net -E -d columbus -e -i example.sql
if %ERRORLEVEL% neq 0 exit /b %ERRORLEVEL%
echo we got to the end of the BAT file

example.sql

SET XACT_ABORT ON
if ((SELECT COUNT(*) FROM sys.tables) > 3)
    begin
    RAISERROR ('There are more than 3 tables.  We will try to stop', 18, -1)
    end
SELECT COUNT(*) FROM sys.tables

Solution

  • @dbenson's answer solves the problem with the .bat file. But there is also a problem with the .sql file, whose symptom is that the last line executes despite the error. Here is a complete solution. That is, these two files work correctly.

    The "error" for which the code is checking is that a database named 'master' exists. If you replace 'master' with something that is not the name of a database, it runs without error.

    example.bat

    REM Replace the server name with any SQL Server server to which you
    REM have at least read access.  The contents of the server don't matter.
    sqlcmd -b -S dbread.vistaprint.net -E -i example.sql
    if %errorlevel% neq 0 exit /b %errorlevel%
    echo 'In the .bat file, we got past the error check, so run was successful.'
    

    example.sql

    if exists (select * from master.sys.databases where name = 'master')
        begin
        RAISERROR ('Found an error condition', 18, 10)
        return
        end
    print 'In the SQL file, we got past the error check, so run was successful.'