【问题标题】:SQL Server PRINT SELECT (Print a select query result)?SQL Server PRINT SELECT(打印选择查询结果)?
【发布时间】:2010-12-28 23:17:37
【问题描述】:

我正在尝试打印一个选定的值,这可能吗?

例子:

PRINT 
    SELECT SUM(Amount) FROM Expense

【问题讨论】:

  • Shimmy - 感谢您选择我的答案作为“最”答案。
  • 关于打印值而不是打印表或结果集的问题。在任何一种情况下,该语言都不允许将子查询作为 PRINT 命令的参数。 Here is another SO question and answer 显示了一个与此非常相似的示例,参考了 PRINT 文档。

标签: sql-server tsql select-query


【解决方案1】:
set @n = (select sum(Amount) from Expense)
print 'n=' + @n

【讨论】:

    【解决方案2】:

    您知道,可能有更简单的方法,但首先想到的是:

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

    当然,您可以通过这种方式从表格中打印任意数量的字段。当然,如果您想打印返回多行的查询的所有结果,您只需适当地引导您的输出(例如到文本)。

    【讨论】:

    • 这通常是最好的方法,但是当您有很多行和列要使用print 转储时,这是一个很好的解决方案,请参阅下面的@DanFields 答案 - stackoverflow.com/a/36729681/8479
    【解决方案3】:

    如果要打印多行,可以使用游标遍历结果。 例如打印来自 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;
    

    【讨论】:

      【解决方案4】:

      我写了这个 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'
      

      【讨论】:

      • 这个 SP 不工作,不管我给它的查询是 incorrect syntax near near 'my query'
      • 这适用于我在 SQL Server 2014 上。现在测试其他版本。
      • 更新了帖子以包含 2008 R2、2012 和 2014 的工作版本。
      • 感谢您的更新,现在工作正常。但是在一个表中我收到了这个错误Msg 529, Level 16, State 2, Line 1 Explicit conversion from data type timestamp to nvarchar is not allowed. 我会尝试解决这个转换问题
      【解决方案5】:

      如果您可以将其视为 XML:

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

      虽然所问的 OP 问题不一定需要这样做,但如果您到这里希望打印多行/列(在合理范围内),它会很有用。

      【讨论】:

      • 太棒了!在很多情况下,您想使用PRINT 来转储结果并为此添加自定义 proc 实在是太辛苦了。很好的解决方案。
      • 是的,我在 SSMS 中使用过它,添加 SELECT * FROM 会导致其他应用程序/用户出现问题。
      • 在旧版本的 SQL Server 上,您需要 DECLARE @xmltmp xml; SELECT @xmltmp = (SELECT * FROM table FOR XML AUTO); PRINT CONVERT(NVARCHAR(MAX), @xmltmp)
      • 感谢@richard - FWIW,如果您使用的是早于 SQL 2008R2 的版本,那么您就超出了 MSFT 的(扩展)支持窗口,应该寻求更新。当然,这可能不会阻止您的工作场所继续使用 2005 或其他任何东西......
      • 是否有在线实用程序可以获取 XML 并以表格形式显示数据 - 在浏览器中在线显示?
      【解决方案6】:

      试试这个查询

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

      【讨论】:

        【解决方案7】:

        添加

        PRINT 'Hardcoded table name -' + CAST(@@RowCount as varchar(10))
        

        查询之后。

        【讨论】:

          【解决方案8】:

          如果您希望为每个表执行此操作,也可以使用未记录的 sp_MSforeachtable 存储过程:

          sp_MSforeachtable @command1 ="PRINT 'TABLE NAME: ' + '?' DECLARE @RowCount INT SET @RowCount = (SELECT COUNT(*) FROM ?) PRINT @RowCount" 
          

          【讨论】:

            【解决方案9】:

            如果您希望(像我一样)得到包含“标记”的各种 SELECT 查询的多行的结果,并且无法在 PRINT 语句的约束下与 Messages 选项卡一起管理它,您可以将其转过来并简单地添加根据以下内容向“结果”选项卡发送消息:

            SELECT 'Results from scenario 1'
            SELECT
                *
            FROM tblSample
            

            【讨论】:

            • 这并不能完全回答这个问题,但对我有用。 => 点赞
            【解决方案10】:

            如果要打印多个结果,只需将行选择到临时表中,然后从该临时表中选择到缓冲区,然后打印缓冲区:

            drop table if exists #temp
            
            -- we just want to see our rows, not how many were inserted
            set nocount on
            
            select * into #temp from MyTable
            
            -- note: SSMS will only show 8000 chars
            declare @buffer varchar(MAX) = ''
            
            select @buffer = @buffer + Col1 + ' ' + Col2 + CHAR(10) from #temp
            
            print @buffer
            
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2018-06-08
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2021-02-12
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多