如何在用户定义的函数中输出 PRINT?

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

然而,我得到了下面的错误;

在“ PRINT”中使用副作用或时间依赖运算符无效 在一个函数中。

不能这样做吗?

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

143806 次浏览

没有,抱歉。SQLServer 中的用户定义函数实际上是有限的,因为要求它们是确定性的。据我所知,没有别的办法。

您是否尝试使用 VisualStudio 调试 SQL 代码?

不,你不能。

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

在过去,我倾向于分两个阶段来完成我的工作。第一个阶段是将它们视为相当普通的 SQL 查询,并确保从中得到正确的结果。在我确信它的性能符合预期之后,我将把它转换成一个 UDF。

我通过将函数临时重写成这样的形式来解决这个问题:

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)

您可以尝试返回希望检查的变量。 例如,我有这样一个函数:

--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)

瞧! 现在它起作用了:)

提示: 产生错误。

declare @Day int, @Config_Node varchar(50)


set @Config_Node = 'value to trace'


set @Day = @Config_Node

你会收到这条信息:

转换 varchar 值‘ value to trace’时失败 数据类型 int.

使用扩展过程 xp _ cmdshell 运行 shell 命令:

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

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

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

在我看来,无论何时我想打印或调试一个函数。我将复制它的内容,以作为一个普通的 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