【问题标题】:TSQL How do you output PRINT in a user defined function?TSQL 如何在用户定义的函数中输出 PRINT?
【发布时间】:2010-10-09 20:31:22
【问题描述】:

基本上我想在用户定义的函数中使用PRINT 语句来帮助调试。

但是我收到以下错误;

在“PRINT”中无效使用副作用或时间相关的运算符 在函数中。

这不能做吗?

无论如何帮助我的用户定义函数调试?

【问题讨论】:

  • 有关执行此操作的实际方法,请参阅:stackoverflow.com/a/10721985/65223
  • 无论您尝试测试什么值 - 只需声明一个稍后将删除的变量并将其作为数据集的一部分返回。只是另一种选择

标签: tsql user-defined-functions


【解决方案1】:

提示: 产生错误。

declare @Day int, @Config_Node varchar(50)

    set @Config_Node = 'value to trace'

    set @Day = @Config_Node

您将收到此消息:

在转换 varchar 值“值到跟踪”时转换失败 到数据类型 int。

【讨论】:

  • 如果要跟踪的值是 int 怎么办?
  • 非常好的技巧..我永远有这个问题! Roel 要跟踪一个 int 值,可以尝试 select @day = 'int value# ' + convert(varchar(10), @int_value_to_trace)
  • 明智的轻笑。当你不给我们一个方便的“正确”方式时,我们就会发明一个方便的“错误”方式。
【解决方案2】:

不,对不起。 SQL Server 中的用户定义函数非常有限,因为它们需要确定性。据我所知,没有办法。

您是否尝试过使用 Visual Studio 调试 SQL 代码?

【讨论】:

    【解决方案3】:

    我通过暂时将我的函数重写为类似这样的东西来解决这个问题:

    IF OBJECT_ID ('[dbo].[fx_dosomething]', 'TF') IS NOT NULL
      drop function [dbo].[fx_dosomething];
    GO
    
    create FUNCTION dbo.fx_dosomething ( @x numeric )
    returns @t table (debug varchar(100), x2 numeric)
    as
    begin
     declare @debug varchar(100)
     set @debug = 'printme';
    
     declare @x2 numeric
     set @x2 = 0.123456;
    
     insert into @t values (@debug, @x2)
     return 
    end
    go
    
    select * from fx_dosomething(0.1)
    

    【讨论】:

    • 我喜欢这种方法,很有创意。只需将调试输出作为返回表中的另一列返回 :-)。
    【解决方案4】:

    过去,我倾向于分两个阶段处理我的职能。第一阶段是将它们视为相当正常的 SQL 查询,并确保我从中得到正确的结果。在我确信它按预期执行后,我会将其转换为 UDF。

    【讨论】:

      【解决方案5】:

      使用扩展过程 xp_cmdshell 运行 shell 命令。我用它来打印输出到一个文件:

      exec xp_cmdshell 'echo "mytextoutput" >> c:\debuginfo.txt'
      

      如果文件 debuginfo.txt 不存在,这将创建它。然后它将文本“mytextoutput”(不带引号)添加到文件中。对该函数的任何调用都会多写一行。

      您可能需要先启用此 db-server 属性(默认 = 禁用),但我意识到这可能不符合生产环境中 dba 的喜好。

      【讨论】:

      • 别忘了提前运行:EXEC sp_configure'xp_cmdshell', 1 GO RECONFIGURE GO
      • 别忘了提前运行:EXEC sp_configure 'show advanced options', 1 GO RECONFIGURE GO
      • 要打印日期时间和对文件的注释,您可以执行以下操作: EXEC xp_cmdshell 'echo %DATE%_%TIME% Processing something >> d:\Log\debuginfo.log' This将在文件中创建一个输出,如下所示:Thu 02/21/2019_18:53:10.18 Processing something
      【解决方案6】:

      不,你不能。

      您可以从stored procedure 调用function 并调试stored procedure(这将进入function

      【讨论】:

      • 或将其设为存储过程
      【解决方案7】:

      您可以尝试返回要检查的变量。 例如。我有这个功能:

      --Contencates seperate date and time strings and converts to a datetime. Date should be in format 25.03.2012. Time as 9:18:25.
      ALTER FUNCTION [dbo].[ufn_GetDateTime] (@date nvarchar(11), @time nvarchar(11))
      RETURNS datetime
      AS
      BEGIN
      
              --select dbo.ufn_GetDateTime('25.03.2012.', '9:18:25')
      
          declare @datetime datetime
      
          declare @day_part nvarchar(3)
          declare @month_part nvarchar(3)
          declare @year_part nvarchar(5)
      
          declare @point_ix int
      
          set @point_ix = charindex('.', @date)
          set @day_part = substring(@date, 0, @point_ix)
      
          set @date = substring(@date, @point_ix, len(@date) - @point_ix)
          set @point_ix = charindex('.', @date)
      
          set @month_part = substring(@date, 0, @point_ix)
      
          set @date = substring(@date, @point_ix, len(@date) - @point_ix)
          set @point_ix = charindex('.', @date)
      
          set @year_part = substring(@date, 0, @point_ix)
      
          set @datetime = @month_part + @day_part  + @year_part + ' ' + @time
      
          return @datetime
      END
      

      当我运行它时.. 我得到: 消息 241,第 16 级,状态 1,第 1 行 从字符串转换日期和/或时间时转换失败。

      啊!!

      那么,我该怎么办?

      ALTER FUNCTION [dbo].[ufn_GetDateTime] (@date nvarchar(11), @time nvarchar(11))
      RETURNS nvarchar(22)
      AS
      BEGIN
      
              --select dbo.ufn_GetDateTime('25.03.2012.', '9:18:25')
      
          declare @day_part nvarchar(3)
          declare @point_ix int
      
          set @point_ix = charindex('.', @date)
          set @day_part = substring(@date, 0, @point_ix)
      
          return @day_part
      END
      

      我得到“25”。所以,我差了一个,所以我改成..

      set @day_part = substring(@date, 0, @point_ix + 1)
      

      瞧!现在可以了:)

      【讨论】:

        【解决方案8】:

        在我看来,每当我想打印或调试一个函数时。我将复制它的内容以作为普通 SQL 脚本运行。例如

        我的功能:

        create or alter function func_do_something_with_string(@input nvarchar(max)) returns nvarchar(max)
        as begin
           -- some function logic content
           declare @result nvarchar(max)
           set @result = substring(@input , 1, 10)
           -- or do something else
        
           return @result
        end
        

        然后我只是复制并运行这个函数来调试

            declare @input nvarchar(max) = 'Some string'      
        
            -- some function logic content
            declare @result nvarchar(max)
            set @result = substring(@input , 1, 10)
            -- this line is added to check while debugging
            print @result 
            
            -- or do something else
            -- print the final result
            print @result
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-10-25
          • 2022-09-23
          • 1970-01-01
          • 1970-01-01
          • 2021-10-31
          • 1970-01-01
          相关资源
          最近更新 更多