Search code examples
sqlsql-serversqlcmd

SQLCMD stops at first GO it reaches in script


Essentially i need to run a quite large SQL script that wont run in SSMS.

Using sqlcmd to input a .sql file however will simply seem to stop at first GO statement it reaches.

All it seems to run is:

USE [master]
GO

CMD writes: "Changed database context to 'master'"

And then its idle, no cpu usage and bare minimal ram usage.

Even with minimized script just to create a new, empty DB, the result is the same.

the string i used would be like this:

sqlcmd -S 127.0.0.1 -U x -P x -i D:\x\f.sql 

it connects to the db just fine, however the included .sql script still wont run.

Setting errorlevel to 1 wont help, it still stops/halts, simply no message then.


Solution

  • I think you've got GO in the wrong place.

    I use sqlcmd for a unattended installs and have reproduced the issue and see what you mean.

    This is how I call scripts passing parameters:

    sqlcmd -S . -E -b -v Database="Test" -i "C:\temp\CreateDatabase.sql"
    

    This is the CreateDatabase.sql script file:

    :On Error exit
    --:Out null
    --:SetVar SQLCMDERRORLEVEL 18
    
    -- USE [master] GO -- with this line it fails, but its in the Master context already    
    
    DECLARE @Database varchar(64);
    DECLARE @Error int;
    DECLARE @Path varchar(256);
    DECLARE @BackUpPath varchar(256);
    
    SET @Database = '$(Database)';
    SET @Path = '';
    SET @BackUpPath = '';   
    
    IF @Path IS NULL OR RTrim(@Path) = ''
        SET @Path = (SELECT SUBSTRING(physical_name, 1, CHARINDEX('master.mdf', LOWER(physical_name)) - 1)
                    FROM master.sys.master_files
                    WHERE database_id = 1 AND file_id = 1);
    ELSE IF Right(@Path, 1) != ''
        SET @Path = @Path + '';
    
    IF EXISTS(SELECT [name] as [Database]
            FROM master.sys.databases
            WHERE [name] = @Database)
        RAISERROR ('Database already exists.', 18, 10); --  :Exit(SELECT 10)
    
    EXECUTE('CREATE DATABASE ' + @Database + ' ON PRIMARY 
            (NAME = ' + @Database + ', FILENAME = ''' + @Path + @Database + '.mdf'', FILEGROWTH = 1024KB)
            LOG ON
            (NAME = ' + @Database + '_log, FILENAME = ''' + @Path + @Database + '_log.ldf'', SIZE = 5MB,
        MAXSIZE = 25MB,
        FILEGROWTH = 5MB )
            COLLATE SQL_Latin1_General_CP1_CI_AI');
    
    IF @@Error != 0
        RAISERROR ('Failed to create database.', 18, 12);   --  :Exit(SELECT 2)
    

    So you dont need to use GO when creating a database.

    When creating the schema and populating your database I would suggest using SQL tools to export the script so you end up with scripts that look like this:

    USE [SpecificDatabase]
    
    
    /****** Object:  ForeignKey [FK_tblAppCustomers_tblCustomers]    Script Date: 11/23/2008 12:44:26 ******/
    IF  EXISTS (SELECT * FROM sys.foreign_keys WHERE object_id = OBJECT_ID(N'[dbo].[FK_tblAppCustomers_tblCustomers]') AND parent_object_id = OBJECT_ID(N'[dbo].[tblAppCustomers]'))
    ALTER TABLE [dbo].[tblAppCustomers] DROP CONSTRAINT [FK_tblAppCustomers_tblCustomers]
    GO
    /****** Object:  ForeignKey [FK_tblAppSales_tblGS]    Script Date: 11/23/2008 12:44:26 ******/
    IF  EXISTS (SELECT * FROM sys.foreign_keys WHERE object_id = OBJECT_ID(N'[dbo].[FK_tblAppSales_tblGS]') AND parent_object_id = OBJECT_ID(N'[dbo].[tblAppSales]'))
    ALTER TABLE [dbo].[tblAppSales] DROP CONSTRAINT [FK_tblAppSales_tblGS]
    GO