【发布时间】:2010-09-21 01:39:26
【问题描述】:
为什么 T-SQL 中的 PRINT 语句似乎只在某些时候有效?使用它有什么限制?有时,如果生成了结果集,它似乎会变成一个空函数,我假设是为了防止损坏结果集,但它的输出是否不能在另一个结果集中输出,例如行数?
【问题讨论】:
-
您能否举一个有时打印有时不打印的代码示例。我不认为我理解这个问题。
标签: sql-server tsql
为什么 T-SQL 中的 PRINT 语句似乎只在某些时候有效?使用它有什么限制?有时,如果生成了结果集,它似乎会变成一个空函数,我假设是为了防止损坏结果集,但它的输出是否不能在另一个结果集中输出,例如行数?
【问题讨论】:
标签: sql-server tsql
那么,如果您有类似以下的声明,您是说您没有得到“打印”结果?
从 sysobjects 中选择 * PRINT '刚刚从 sysobjects 中选择 *'
如果您使用的是 SQL 查询分析器,您会看到底部有两个选项卡,其中之一是“消息”,这就是“打印”语句将显示的位置。
如果您担心看到打印语句的时间,您可能想尝试使用类似
raiserror ('My Print Statement', 10,1) with nowait
这将在到达语句时立即为您提供消息,而不是像查询分析器在大多数情况下所做的那样缓冲输出。
【讨论】:
RaiseError 是否与PRINT 相同,只是时序不同?
TSQL 中的 Print 语句是一个被误解的东西,可能是因为它的名字。它实际上将消息发送到错误/消息处理机制,然后将其传输到调用应用程序。打印非常愚蠢。您只能发送 8000 个字符(4000 个 unicode 字符)。您可以发送文字字符串、字符串变量(varchar 或 char)或字符串表达式。如果您使用 RAISERROR,那么您只能使用 2,044 个字符的字符串。但是,使用它向调用应用程序发送信息要容易得多,因为它调用了一个类似于标准 C 库中旧 printf 的格式化函数。除了文本消息之外,RAISERROR 还可以指定错误号、严重性和状态代码,还可以用于返回使用 sp_addmessage 系统存储过程创建的用户定义消息。您还可以强制记录消息。
尽管消息和错误非常相似,但您的错误处理例程对于接收消息没有任何好处。当然,该技术会根据您连接到数据库的实际方式(OLBC、OLEDB 等)而有所不同。为了接收和处理来自 SQL Server 数据库引擎的消息,当您使用 System.Data.SQLClient 时,您需要创建一个 SqlInfoMessageEventHandler 委托,标识处理事件的方法,以侦听 InfoMessage 事件在 SqlConnection 类上。您会发现严重性和状态等消息上下文信息作为参数传递给回调,因为从系统的角度来看,这些消息就像错误一样。
在你的应用程序中获取这些消息总是一个好主意,即使你只是假脱机到一个文件,因为当你试图追逐一个真正的晦涩难懂的问题。但是,除非您可以保留在应用程序中显示内容的信息级别,否则我不希望最终用户看到它们。
【讨论】:
为了其他阅读此问题的人的利益,他们的输出中确实缺少打印语句,实际上存在打印执行但未返回给客户端的情况。我不能具体告诉你它们是什么。我可以告诉你,如果你在任何 print 语句之前和之后都放一个 go 语句,你会看到它是否被执行。
【讨论】:
GO 语句将我的PRINTs 刷新到我所追求的外壳中
查询分析器缓冲消息。 PRINT 和 RAISERROR 语句都使用此缓冲区,但 RAISERROR 语句具有 WITH NOWAIT 选项。要立即打印消息,请使用以下命令:
RAISERROR ('Your message', 0, 1) WITH NOWAIT
RAISERROR 只会显示 400 个字符的消息,并使用类似于 C printf 函数的语法来格式化文本。
请注意,使用带有 WITH NOWAIT 选项的 RAISERROR 将刷新消息缓冲区,因此所有先前缓冲的信息也将被输出。
【讨论】:
我最近遇到了这个问题,最终是因为我有一个关于 null 变量的转换语句。由于这会导致错误,因此整个打印语句都呈现为 null,并且根本不打印。
示例 - 这将失败:
declare @myID int=null
print 'First Statement: ' + convert(varchar(4), @myID)
示例 - 这将打印:
declare @myID int=null
print 'Second Statement: ' + coalesce(Convert(varchar(4), @myID),'@myID is null')
【讨论】:
您是否有与这些打印语句相关的变量被输出?如果是这样,我发现如果变量没有值,那么打印语句将不会被输出。
【讨论】:
NULL 与字符串连接起来的效果。 PRINT 'a' + CAST(NULL AS VARCHAR(MAX)); 的行为完全符合我的预期。