2009-12-22 2 views
33

Я пытаюсь напечатать выбранное значение, возможно ли это?SQL Server PRINT SELECT (печать результата запроса)?

Пример:

PRINT 
    SELECT SUM(Amount) FROM Expense 
+0

Shimmy - спасибо за выбор моего ответа, как "" ответ. –

+0

Вопрос о печати значения не о печати таблицы или результирующего набора. В любом случае язык не разрешает суб-запрос в качестве аргумента для команды PRINT. [Вот еще один вопрос и ответ SO]] (https://stackoverflow.com/a/5193984/3368958), который показывает пример, очень похожий на этот, со ссылкой на документацию PRINT. –

ответ

55

Вы знаете, что может быть проще, но первое, что приходит на ум:

Declare @SumVal int; 
Select @SumVal=Sum(Amount) From Expense; 
Print @SumVal; 

Вы можете, конечно, напечатать любой количество полей из таблицы таким образом. Конечно, если вы хотите распечатать все результаты запроса, который возвращает несколько строк, вы просто направите свой вывод соответствующим образом (например, в текст).

+0

Это, как правило, лучший способ, но для приятного решения, когда у вас много строк и столбцов, которые вы хотите выгрузить с помощью 'print', см. Ниже @DanFields - http://stackoverflow.com/a/36729681/8479 – Rory

20

Если вы хотите напечатать несколько строк, вы можете выполнить итерацию результата с помощью курсора. , например. печатать все имена из sys.database_principals

DECLARE @name nvarchar(128) 

DECLARE cur CURSOR FOR 
SELECT name FROM sys.database_principals 

OPEN cur 

FETCH NEXT FROM cur INTO @name; 
WHILE @@FETCH_STATUS = 0 
BEGIN 
PRINT @name 
FETCH NEXT FROM cur INTO @name; 
END 

CLOSE cur; 
DEALLOCATE cur; 
2

Я написал это SP делать только то, что вы хотите, однако, вы должны использовать динамический SQL.

Это работает для меня на SQL Server 2008 R2

ALTER procedure [dbo].[PrintSQLResults] 
    @query nvarchar(MAX), 
    @numberToDisplay int = 10, 
    @padding int = 20 
as 

SET NOCOUNT ON; 
SET ANSI_WARNINGS ON; 

declare @cols nvarchar(MAX), 
     @displayCols nvarchar(MAX), 
     @sql nvarchar(MAX), 
     @printableResults nvarchar(MAX), 
     @NewLineChar AS char(2) = char(13) + char(10), 
     @Tab AS char(9) = char(9); 

if exists (select * from tempdb.sys.tables where name = '##PrintSQLResultsTempTable') drop table ##PrintSQLResultsTempTable 

set @query = REPLACE(@query, 'from', ' into ##PrintSQLResultsTempTable from'); 
--print @query 
exec(@query); 
select ROW_NUMBER() OVER (ORDER BY (select Null)) AS ID12345XYZ, * into #PrintSQLResultsTempTable 
from ##PrintSQLResultsTempTable 
drop table ##PrintSQLResultsTempTable 

select name 
into #PrintSQLResultsTempTableColumns 
from tempdb.sys.columns where object_id = 
object_id('tempdb..#PrintSQLResultsTempTable'); 

select @cols = 
stuff((
    (select ' + space(1) + (LEFT((CAST([' + name + '] as nvarchar(max)) + space('+ CAST(@padding as nvarchar(4)) +')), '+CAST(@padding as nvarchar(4))+')) ' as [text()] 
    FROM #PrintSQLResultsTempTableColumns 
    where name != 'ID12345XYZ' 
    FOR XML PATH(''), root('str'), type).value('/str[1]','nvarchar(max)')) 
,1,0,''''''); 

select @displayCols = 
stuff((
    (select space(1) + LEFT(name + space(@padding), @padding) as [text()] 
    FROM #PrintSQLResultsTempTableColumns 
    where name != 'ID12345XYZ' 
    FOR XML PATH(''), root('str'), type).value('/str[1]','nvarchar(max)')) 
,1,0,''); 

DECLARE 
    @tableCount int = (select count(*) from #PrintSQLResultsTempTable); 
DECLARE 
    @i int = 1, 
    @ii int = case when @tableCount < @numberToDisplay then @tableCount else @numberToDisplay end; 

print @displayCols -- header 
While @i <= @ii 
BEGIN 
    set @sql = N'select @printableResults = ' + @cols + ' + @NewLineChar from #PrintSQLResultsTempTable where ID12345XYZ = ' + CAST(@i as varchar(3)) + '; print @printableResults;' 
    --print @sql 
    execute sp_executesql @sql, N'@NewLineChar char(2), @printableResults nvarchar(max) output', @NewLineChar = @NewLineChar, @printableResults = @printableResults output 
    print @printableResults 
    SET @i += 1; 
END 

Это работает для меня на SQL Server 2012

ALTER procedure [dbo].[PrintSQLResults] 
    @query nvarchar(MAX), 
    @numberToDisplay int = 10, 
    @padding int = 20 
as 

SET NOCOUNT ON; 
SET ANSI_WARNINGS ON; 

declare @cols nvarchar(MAX), 
     @displayCols nvarchar(MAX), 
     @sql nvarchar(MAX), 
     @printableResults nvarchar(MAX), 
     @NewLineChar AS char(2) = char(13) + char(10), 
     @Tab AS char(9) = char(9); 

if exists (select * from tempdb.sys.tables where name = '##PrintSQLResultsTempTable') drop table ##PrintSQLResultsTempTable 

set @query = REPLACE(@query, 'from', ' into ##PrintSQLResultsTempTable from'); 
--print @query 
exec(@query); 
select ROW_NUMBER() OVER (ORDER BY (select Null)) AS ID12345XYZ, * into #PrintSQLResultsTempTable 
from ##PrintSQLResultsTempTable 
drop table ##PrintSQLResultsTempTable 

select name 
into #PrintSQLResultsTempTableColumns 
from tempdb.sys.columns where object_id = 
object_id('tempdb..#PrintSQLResultsTempTable'); 

select @cols = 
stuff((
    (select ' + space(1) + LEFT(CAST([' + name + '] as nvarchar('+CAST(@padding as nvarchar(4))+')) + space('+ CAST(@padding as nvarchar(4)) +'), '+CAST(@padding as nvarchar(4))+') ' as [text()] 
    FROM #PrintSQLResultsTempTableColumns 
    where name != 'ID12345XYZ' 
    FOR XML PATH(''), root('str'), type).value('/str[1]','nvarchar(max)')) 
,1,0,''''''); 

select @displayCols = 
stuff((
    (select space(1) + LEFT(name + space(@padding), @padding) as [text()] 
    FROM #PrintSQLResultsTempTableColumns 
    where name != 'ID12345XYZ' 
    FOR XML PATH(''), root('str'), type).value('/str[1]','nvarchar(max)')) 
,1,0,''); 

DECLARE 
    @tableCount int = (select count(*) from #PrintSQLResultsTempTable); 
DECLARE 
    @i int = 1, 
    @ii int = case when @tableCount < @numberToDisplay then @tableCount else @numberToDisplay end; 

print @displayCols -- header 
While @i <= @ii 
BEGIN 
    set @sql = N'select @printableResults = ' + @cols + ' + @NewLineChar from #PrintSQLResultsTempTable where ID12345XYZ = ' + CAST(@i as varchar(3)) + ' ' 
    --print @sql 
    execute sp_executesql @sql, N'@NewLineChar char(2), @printableResults nvarchar(max) output', @NewLineChar = @NewLineChar, @printableResults = @printableResults output 
    print @printableResults 
    SET @i += 1; 
END 

Это работает для меня на SQL Server 2014

ALTER procedure [dbo].[PrintSQLResults] 
    @query nvarchar(MAX), 
    @numberToDisplay int = 10, 
    @padding int = 20 
as 

SET NOCOUNT ON; 
SET ANSI_WARNINGS ON; 

declare @cols nvarchar(MAX), 
     @displayCols nvarchar(MAX), 
     @sql nvarchar(MAX), 
     @printableResults nvarchar(MAX), 
     @NewLineChar AS char(2) = char(13) + char(10), 
     @Tab AS char(9) = char(9); 

if exists (select * from tempdb.sys.tables where name = '##PrintSQLResultsTempTable') drop table ##PrintSQLResultsTempTable 

set @query = REPLACE(@query, 'from', ' into ##PrintSQLResultsTempTable from'); 
--print @query 
exec(@query); 
select ROW_NUMBER() OVER (ORDER BY (select Null)) AS ID12345XYZ, * into #PrintSQLResultsTempTable 
from ##PrintSQLResultsTempTable 
drop table ##PrintSQLResultsTempTable 

select name 
into #PrintSQLResultsTempTableColumns 
from tempdb.sys.columns where object_id = 
object_id('tempdb..#PrintSQLResultsTempTable'); 

select @cols = 
stuff((
    (select ' , space(1) + LEFT(CAST([' + name + '] as nvarchar('+CAST(@padding as nvarchar(4))+')) + space('+ CAST(@padding as nvarchar(4)) +'), '+CAST(@padding as nvarchar(4))+') ' as [text()] 
    FROM #PrintSQLResultsTempTableColumns 
    where name != 'ID12345XYZ' 
    FOR XML PATH(''), root('str'), type).value('/str[1]','nvarchar(max)')) 
,1,0,''''''); 

select @displayCols = 
stuff((
    (select space(1) + LEFT(name + space(@padding), @padding) as [text()] 
    FROM #PrintSQLResultsTempTableColumns 
    where name != 'ID12345XYZ' 
    FOR XML PATH(''), root('str'), type).value('/str[1]','nvarchar(max)')) 
,1,0,''); 

DECLARE 
    @tableCount int = (select count(*) from #PrintSQLResultsTempTable); 
DECLARE 
    @i int = 1, 
    @ii int = case when @tableCount < @numberToDisplay then @tableCount else @numberToDisplay end; 

print @displayCols -- header 
While @i <= @ii 
BEGIN 
    set @sql = N'select @printableResults = concat(@printableResults, ' + @cols + ', @NewLineChar) from #PrintSQLResultsTempTable where ID12345XYZ = ' + CAST(@i as varchar(3)) 
    --print @sql 
    execute sp_executesql @sql, N'@NewLineChar char(2), @printableResults nvarchar(max) output', @NewLineChar = @NewLineChar, @printableResults = @printableResults output 
    print @printableResults 
    SET @printableResults = null; 
    SET @i += 1; 
END 

Пример:

exec [dbo].[PrintSQLResults] n'select * from MyTable' 
+0

Этот SP не работает, независимо от того, что я задал, он говорит «неправильный синтаксис рядом с« моим запросом ». –

+0

Это работает для меня на SQL-сервере 2014. Тестирование других версий сейчас. –

+0

Обновлено сообщение, чтобы включить рабочие версии на 2008 R2, 2012 и 2014. –

25

Если вы в порядке с его просмотра в формате XML:

DECLARE @xmltmp xml = (SELECT * FROM table FOR XML AUTO) 
PRINT CONVERT(NVARCHAR(MAX), @xmltmp) 

Хотя вопрос в OP как спросил, не обязательно требуют этого, это полезно, если вы получили здесь хотите напечатать несколько строк/столбцов (в пределах причина).

+1

Это _amazing_!Существует так много случаев, когда вы хотите использовать 'PRINT' для выгрузки результатов и добавления настраиваемого proc для него - это слишком тяжелая работа. Отличное решение. – Rory

+0

Да, я использовал это в SSMS, где добавление SELECT * FROM вызовет проблемы для других приложений/пользователей. –

1

Попробуйте этот запрос

DECLARE @PrintVarchar nvarchar(max) = (Select Sum(Amount) From Expense) 
PRINT 'Varchar format =' + @PrintVarchar 

DECLARE @PrintInt int = (Select Sum(Amount) From Expense) 
PRINT @PrintInt 
Смежные вопросы