HiveBrain v1.2.0
Get Started
← Back to all entries
debugsqlMinor

sqlcmd :out not working as expected?

Submitted by: @import:stackexchange-dba··
0
Viewed 0 times
workingexpectedsqlcmdnotout

Problem

Consider the following code:

DECLARE @db sysname;
DECLARE @filename varchar(260);
DECLARE cur CURSOR LOCAL FORWARD_ONLY STATIC READ_ONLY
FOR
SELECT d.name
FROM sys.databases d;
OPEN cur;
FETCH NEXT FROM cur INTO @db
WHILE @@FETCH_STATUS = 0
BEGIN
    SET @filename = 'C:\temp\create_database_' + @db + '.txt';
    :setvar c @filename
    :out $(c)
    PRINT $(c);
    FETCH NEXT FROM cur INTO @db
END
CLOSE cur;
DEALLOCATE cur;


I'm expecting to get multiple files created in C:\temp, one for each database, but nothing is created, and no errors are reported by SQL Server.

I've tried running this in SSMS using SQLCMD mode, and I've also tried running it from sqlcmd.exe

Solution

The way to do this with sqlcmd mode is to script a script which scripts a script, then execute those scripts, so it's a slightly different way of thinking about things, a bit like Inception or Borges, the dream within the dream:

-- Script a script which scripts a script
SET NOCOUNT ON
GO

:out d:\temp\temp.sql
GO

SELECT REPLACE( ':out d:\temp\@database.sql
-- Do some work here
PRINT ''select ''''@database''''''
GO

-- Return stdout to normal
:out STDOUT
GO
', '@database', name ) AS [--sql]
--C:\temp\create_database_' + name + '.txt'
FROM sys.databases 
GO

-- Return stdout to normal
:out STDOUT
GO

-- Now execute your scripted file
:r d:\temp\temp.sql
GO

-- Create another script which executes all thoses scripts ...
:out d:\temp\temp2.sql
GO

SELECT REPLACE( ':r d:\temp\@database.sql
GO
', '@database', name ) AS [--sql]
FROM sys.databases 
GO

-- Return stdout to normal
:out STDOUT
GO

-- Execute your script of scripts?
:r d:\temp\temp2.sql
GO

Code Snippets

-- Script a script which scripts a script
SET NOCOUNT ON
GO

:out d:\temp\temp.sql
GO

SELECT REPLACE( ':out d:\temp\@database.sql
-- Do some work here
PRINT ''select ''''@database''''''
GO

-- Return stdout to normal
:out STDOUT
GO
', '@database', name ) AS [--sql]
--C:\temp\create_database_' + name + '.txt'
FROM sys.databases 
GO


-- Return stdout to normal
:out STDOUT
GO

-- Now execute your scripted file
:r d:\temp\temp.sql
GO


-- Create another script which executes all thoses scripts ...
:out d:\temp\temp2.sql
GO

SELECT REPLACE( ':r d:\temp\@database.sql
GO
', '@database', name ) AS [--sql]
FROM sys.databases 
GO

-- Return stdout to normal
:out STDOUT
GO

-- Execute your script of scripts?
:r d:\temp\temp2.sql
GO

Context

StackExchange Database Administrators Q#211804, answer score: 4

Revisions (0)

No revisions yet.