2013-11-04 63 views
0

由另一個程序員創建的SQL函數會減慢我的存儲過程。導致緩存過程的XML函數

任何人都不會有爲什麼這會導致該存儲過程減慢的任何想法它在查詢稱爲where子句這樣

AND (dbo.fn_XmlElementDateValue(ua.details, 'start_date') >= @StartDate) 
AND (dbo.fn_XmlElementDateValue(ua.details, 'end_date') <= @EndDate) 

功能

Create FUNCTION [dbo].[fn_XmlAttributeDateValue](@xml text, @tagname varchar(100)) 
RETURNS DATETIME 
AS 
BEGIN 
    DECLARE @startpos int, @endpos int, @returnvalue varchar(100) 

    IF (NOT @tagname IS NULL) 
     BEGIN 

    SET @startpos = CHARINDEX('<field name="' + @tagname + '" value="', @xml) + LEN('<field name="' + @tagname + '" value="') 

    IF (@startpos > 0) 
    BEGIN 
     SET @endpos = CHARINDEX('" />', @xml, @startpos) 

     IF (@endpos > @startpos) 
     BEGIN  -- Return the requested value 
      SET @returnvalue = SUBSTRING(@xml, @startpos, @endpos - @startpos) 

      IF (ISDATE(@returnvalue) = 1) 
      BEGIN 
       RETURN CAST(@returnvalue AS DATETIME) 
      END 
     END 
    END 
    END -- Tag empty or not found 
    RETURN NULL 
END 
+0

顯示我們代碼在哪裏被使用。 – acfrancis

+1

這看起來像SQL-Server,因此如果您要存儲XML數據,爲什麼不使用[XML數據類型](http://technet.microsoft.com/zh-cn/library/hh403385.aspx )所以你可以正確地查詢它,而不是使用循環和昂貴的標量函數? – GarethD

+1

將在未來的SQL Server版本中刪除'ntext','text'和'image'數據類型。避免在新的開發工作中使用這些數據類型,並計劃修改當前正在使用它們的應用程序。改爲使用'nvarchar(max)','varchar(max)'和'varbinary(max)'。 [請參閱此處](http://msdn.microsoft.com/en-us/library/ms187993.aspx) –

回答

0

我會強烈建議您使用用於查詢XML數據的XML類型。字符串操作是昂貴且低效的。

這將涉及到更改功能是這樣的:

Create FUNCTION [dbo].[fn_XmlAttributeDateValue](@xml XML, @tagname varchar(100)) 
RETURNS DATETIME 
AS 
BEGIN 
    DECLARE @returnvalue varchar(100) 
    IF ISNULL(@tagname, '') = ''   
     RETURN NULL 

    SELECT @returnvalue = @xml.value('(//field[@name=(sql:variable("@tagname"))])[1]/@value', 'varchar(100)') 
    RETURN CAST(@returnvalue AS DATETIME) 
END 

然後傳遞給函數,像這樣:

DECLARE @InXML VARCHAR(MAX) = '<root><field name="test1" value="not interested" /><field name="test2" value="2013-11-04 00:00:01" /></root>' 

SELECT [dbo].[fn_XmlAttributeDateValue](CONVERT(XML, @InXML), 'test2') 

測試了這個在2012年SQL