【问题标题】:PRINT statement in T-SQLT-SQL 中的 PRINT 语句
【发布时间】:2010-09-21 01:39:26
【问题描述】:

为什么 T-SQL 中的 PRINT 语句似乎只在某些时候有效?使用它有什么限制?有时,如果生成了结果集,它似乎会变成一个空函数,我假设是为了防止损坏结果集,但它的输出是否不能在另一个结果集中输出,例如行数?

【问题讨论】:

  • 您能否举一个有时打印有时不打印的代码示例。我不认为我理解这个问题。

标签: sql-server tsql


【解决方案1】:

那么,如果您有类似以下的声明,您是说您没有得到“打印”结果?

从 sysobjects 中选择 *
PRINT '刚刚从 sysobjects 中选择 *'

如果您使用的是 SQL 查询分析器,您会看到底部有两个选项卡,其中之一是“消息”,这就是“打印”语句将显示的位置。
如果您担心看到打印语句的时间,您可能想尝试使用类似

raiserror ('My Print Statement', 10,1) with nowait

这将在到达语句时立即为您提供消息,而不是像查询分析器在大多数情况下所做的那样缓冲输出。

【讨论】:

  • 很酷的交易。很高兴这对你有用。我通常告诉查询分析器给我文本输出,这样我就可以看到内联的消息 (Ctrl+T)。享受吧!
  • raiserror 示例中的 10 和 1 参数是什么?
  • 10, 1 实际上只是对服务器说“这里没什么可看的”。有关它们实际含义的详细信息,请参阅docs.microsoft.com/en-us/sql/t-sql/language-elements/…
  • 这样使用时,RaiseError 是否与PRINT 相同,只是时序不同?
  • 我相信是的。它可能具有立即输出缓冲区的额外好处,因此也会显示其他打印语句,但这是您想要验证的内容。我的理解是它会触发队列立即输出。
【解决方案2】:

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 类上。您会发现严重性和状态等消息上下文信息作为参数传递给回调,因为从系统的角度来看,这些消息就像错误一样。

在你的应用程序中获取这些消息总是一个好主意,即使你只是假脱机到一个文件,因为当你试图追逐一个真正的晦涩难懂的问题。但是,除非您可以保留在应用程序中显示内容的信息级别,否则我不希望最终用户看到它们。

【讨论】:

    【解决方案3】:

    为了其他阅读此问题的人的利益,他们的输出中确实缺少打印语句,实际上存在打印执行但未返回给客户端的情况。我不能具体告诉你它们是什么。我可以告诉你,如果你在任何 print 语句之前和之后都放一个 go 语句,你会看到它是否被执行。

    【讨论】:

    • 我也遇到过这样的情况,即打印语句在预期时写入消息窗口。它在提交或回滚后发生在我身上。
    • 添加GO 语句将我的PRINTs 刷新到我所追求的外壳中
    【解决方案4】:

    查询分析器缓冲消息。 PRINT 和 RAISERROR 语句都使用此缓冲区,但 RAISERROR 语句具有 WITH NOWAIT 选项。要立即打印消息,请使用以下命令:

    RAISERROR ('Your message', 0, 1) WITH NOWAIT
    

    RAISERROR 只会显示 400 个字符的消息,并使用类似于 C printf 函数的语法来格式化文本。

    请注意,使用带有 WITH NOWAIT 选项的 RAISERROR 将刷新消息缓冲区,因此所有先前缓冲的信息也将被输出。

    【讨论】:

    • RAISERROR 语法很痛苦,但是在我的 PRINT 完成这项工作后放一个空的,谢谢你的信息!
    【解决方案5】:

    我最近遇到了这个问题,最终是因为我有一个关于 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')
    

    【讨论】:

    • 不只是 PRINT:在 T-SQL 中的任何位置使用带有任何空值的 + 运算符都会导致空值,无论是否有其他非空值要连接在一起。使用 ISNULL(@myID, '') 或 COALESCE 将允许 null 能够与字符串连接。
    【解决方案6】:

    您是否有与这些打印语句相关的变量被输出?如果是这样,我发现如果变量没有值,那么打印语句将不会被输出。

    【讨论】:

    • 您听起来好像不明白将NULL 与字符串连接起来的效果。 PRINT 'a' + CAST(NULL AS VARCHAR(MAX)); 的行为完全符合我的预期。
    猜你喜欢
    • 1970-01-01
    • 2022-01-21
    • 1970-01-01
    • 1970-01-01
    • 2022-08-03
    • 2016-12-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多