存储过程冻结了调用功能

时间:2017-05-19 10:41:15

标签: sql-server tsql stored-procedures

我有以下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为false,则此方法正常,但如果为true则调用以下函数:

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

存储过程会冻结,或者至少花费很长时间才会产生差异。

有关如何更好地编码的任何建议吗?

1 个答案:

答案 0 :(得分:0)

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

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

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