为什么执行标量函数会导致"创建函数"操作?

时间:2016-06-16 16:50:08

标签: sql-server sql-server-2014

我需要在select语句中修剪一些字符串,所以我没有重复多个ltrim(rtrim('字符串')调用,而是创建了一个简单的trim函数,如下所示:

create function dbo.trim(@String varchar(max))
returns varchar(max)
as
begin
    return rtrim(ltrim(@String))
end
go

但是,在执行select(多次调用函数)期间,我在另一个窗口中运行以下select作为sa:

SELECT sqltext.TEXT,
req.session_id,
req.status,
req.command,
req.cpu_time,
req.total_elapsed_time
FROM sys.dm_exec_requests req
CROSS APPLY sys.dm_exec_sql_text(sql_handle) AS sqltext

并观察以下内容

TEXT    session_id  status  command cpu_time    total_elapsed_time
------------------------------------------------------------------    
**      99          running SELECT  12045       12388

其中第一列(由上面的**替换为可读性)包含以下内容:

create function dbo.trim(@String varchar(max))
returns varchar(max)
as
begin
    return rtrim(ltrim(@String))
end

我是否正确地解释了这意味着在调用SQL Server实际调用create的修剪函数时?

从上表中可以看出,执行时间相当长,在某些情况下,我发现创建操作完全挂起,从而阻止了对数据库的选择和进一步写操作的完成,我不得不杀死手术。

任何人都可以对此有所了解吗?

谢谢! PAB

1 个答案:

答案 0 :(得分:2)

  

我是否正确地解释了这意味着在调用修剪时   SQL Server实际上调用create?

的函数

不,SQL Server只显示SQL模块的全文 - 其中包含CREATE。您可以使用statement_start_offsetstatement_end_offset to see the statement actually being executed

SideNote:你最好不要使用标量UDF来处理像TRIM函数这样的小事。这些都有众所周知的性能问题。如果值得封装在函数中,请参阅Converting A Scalar User Defined Function To A Inline Table Valued Function以获取替代方法。