2017-05-19 52 views
0

我有以下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 

存储过程冻结,或者至少需要很长时间才能保持不变。

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

回答

0

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

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

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