【问题标题】:Stored procedure freezes calling function存储过程冻结调用函数
【发布时间】:2017-05-19 18:53:14
【问题描述】:

我有以下 SQL Server 存储过程:

ALTER PROCEDURE [dbo].[stg_GetFileDetails]
    @file_name AS NVARCHAR(255),
    @remove_dots AS BIT
AS
BEGIN
    SET NOCOUNT ON;

    IF (@remove_dots = 1)
    BEGIN
        SELECT  
            o.r_object_id,
            '' AS [DAP ID],
            p.nhs_patientid AS [MRN],
            p.nhs_firstname AS [First Name],
            p.nhs_surname AS [Surname],
            o.object_name AS [File Name]
        FROM    
            dm_sysobject_s o
        INNER JOIN 
            nhs_instance_audit_s a ON o.r_object_id = a.r_object_id
        INNER JOIN 
            nhs_patient_document_s d ON d.r_object_id = a.dia_edms_document_id
        INNER JOIN 
            nhs_patient_s p ON d.nhs_patdoc_patientid = p.nhs_patientid
        WHERE 
            [dbo].[No_dots_filename](o.object_name) =  @file_name
    END
    ELSE
    BEGIN
        SELECT  
            o.r_object_id,
            '' AS [DAP ID],
            p.nhs_patientid AS [MRN],
            p.nhs_firstname AS [First Name],
            p.nhs_surname AS [Surname],
            o.object_name AS [File Name]
        FROM    
            dm_sysobject_s o
        INNER JOIN 
            nhs_instance_audit_s a ON o.r_object_id = a.r_object_id
        INNER JOIN 
            nhs_patient_document_s d ON d.r_object_id = a.dia_edms_document_id
        INNER JOIN 
            nhs_patient_s p ON d.nhs_patdoc_patientid = p.nhs_patientid     
        WHERE 
            o.object_name =  @file_name
    END

现在,如果@remove_dots 为假,它可以正常工作,但是当它为真时,它会调用以下函数:

ALTER FUNCTION [dbo].[No_dots_filename]
    (@file_name AS NVARCHAR(255))
RETURNS NVARCHAR(255)
AS
BEGIN
    DECLARE @revised_filename AS NVARCHAR(255)
    DECLARE @ext AS NVARCHAR(5)

    IF (LEN(@file_name) > 4)
    BEGIN
        -- see if the extension is a traditional 3 character one
        IF SUBSTRING(@file_name, LEN(@file_name) - 4, 1) = '.'
        BEGIN
            SET @ext = RIGHT(@file_name, 4)
        END
        ELSE            -- otherwise it might be one of the 4 character extensions like .docx
        BEGIN
            SET @ext = RIGHT(@file_name, 5)
        END 

        -- remove dots from the main filename and then replace the extension
        SET @revised_filename = REPLACE(LEFT(@file_name, LEN(@file_name) - LEN(@ext)), '.', '') + @ext
    END
    ELSE
    BEGIN
        SET @revised_filename = @file_name
    END

    RETURN @revised_filename
END

存储过程冻结,或者至少需要很长时间以至于没有任何区别。

关于如何更好地编写代码有什么建议吗?

【问题讨论】:

    标签: sql-server tsql stored-procedures


    【解决方案1】:

    有几个资源可以避免在 WHERE 条件的左侧使用函数,这正是因为它会导致非常糟糕的性能。 您的函数正在针对整个结果集中的每一行执行,这导致了您的问题。

    其中一个资源是Common SQL Server Mistakes – Functions in the WHERE Clause

    避免这种情况的一种方法是将您的函数转换为 table-valued 并交叉应用它。

    【讨论】:

      猜你喜欢
      • 2017-04-23
      • 1970-01-01
      • 2014-10-09
      • 1970-01-01
      • 2020-01-09
      • 1970-01-01
      • 1970-01-01
      • 2011-12-05
      • 1970-01-01
      相关资源
      最近更新 更多