2009-12-22 28 views
33

Tôi đang cố gắng in một giá trị đã chọn, điều này có khả thi không?CHỌN LỆNH MÁY CHỦ SQL (In kết quả truy vấn chọn)?

Ví dụ:

PRINT 
    SELECT SUM(Amount) FROM Expense 
+0

Shimmy - nhờ lựa chọn câu trả lời của tôi là "câu trả lời". –

+0

Câu hỏi được hỏi về việc in một giá trị không phải là in bảng hoặc tập hợp kết quả. Trong cả hai trường hợp, ngôn ngữ không cho phép truy vấn phụ làm đối số cho lệnh IN. [Đây là một câu hỏi và câu trả lời SO] (https://stackoverflow.com/a/5193984/3368958) cho thấy một ví dụ rất giống với ví dụ này có liên quan đến tài liệu PRINT. –

Trả lời

55

Bạn biết đấy, có thể có một cách dễ dàng hơn nhưng điều đầu tiên mà bật đến cái tâm là:

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

Bạn có thể, tất nhiên, in bất kỳ số trường từ bảng theo cách này. Tất nhiên, nếu bạn muốn in tất cả các kết quả từ truy vấn trả về nhiều hàng, bạn chỉ cần chuyển trực tiếp đầu ra của mình một cách thích hợp (ví dụ: Văn bản).

+0

Đây thường là cách tốt nhất, nhưng để có giải pháp tốt đẹp khi bạn có nhiều hàng và cột mà bạn muốn kết xuất bằng 'print', hãy xem @DanFields trả lời dưới đây - http://stackoverflow.com/a/36729681/8479 – Rory

6
set @n = (select sum(Amount) from Expense) 
print 'n=' + @n 
20

Nếu bạn muốn in nhiều hàng, bạn có thể lặp qua kết quả bằng cách sử dụng con trỏ. ví dụ: in tất cả các tên từ 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

Tôi đã viết SP này để làm những gì bạn muốn, tuy nhiên, bạn cần sử dụng sql động.

này làm việc cho tôi trên 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 

này làm việc cho tôi trên 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 

này làm việc cho tôi trên 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 

Ví dụ:

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

SP này không hoạt động, bất kỳ truy vấn nào tôi cung cấp cho nó nói 'sai cú pháp gần gần' truy vấn của tôi'' –

+0

Điều này làm việc cho tôi trên máy chủ SQL 2014. Kiểm tra các phiên bản khác ngay bây giờ. –

+0

Đã cập nhật bài đăng để bao gồm các phiên bản hoạt động trên 2008 R2, 2012 và 2014. –

25

Nếu bạn OK với xem nó như là XML:

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

Trong khi câu hỏi của OP như hỏi không nhất thiết đòi hỏi này, nó rất hữu ích nếu bạn đã ở đây tìm cách để in nhiều hàng/cột (trong vòng lý do).

+1

Đây là _amazing_!Có rất nhiều trường hợp mà bạn muốn sử dụng 'PRINT' để loại bỏ các kết quả và thêm một proc tùy chỉnh cho nó là quá nhiều công việc khó khăn. Giải pháp tuyệt vời. – Rory

+0

Vâng, tôi đã sử dụng điều này trong SSMS khi thêm SELECT * FROM sẽ gây ra sự cố cho các ứng dụng/người dùng khác. –

1

Hãy thử truy vấn này

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

DECLARE @PrintInt int = (Select Sum(Amount) From Expense) 
PRINT @PrintInt 
Các vấn đề liên quan