2017-05-19 79 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,然後交叉應用。