2011-02-02 67 views
0

有一些奇怪的這一說法 COALESCE(@param_ids + '', '')SP緩存計劃

@param_ids在爲PARAM過去了,有@param_ids VARCHAR(MAX)

任何想法爲什麼SQL-Server無法爲以下情況生成緩存計劃。 這個問題已經被微軟列爲他們仍在使用它。

不工作情況下 - 未緩存計劃生成 步驟1

改變SP

IF (LTRIM(RTRIM(ISNULL(@param_ids,''))) = '') 
    BEGIN 
    SELECT @param_ids = COALESCE(@param_ids + ',', '') + CONVERT(VARCHAR(50),ID) 
    FROM [dbo].Content_Type WITH (NOLOCK) 
    END 

步驟2 Exec的SP使用參數

步驟3(否緩存計劃)

SELECT * 
FROM sys.dm_exec_cached_plans 
CROSS APPLY sys.dm_exec_sql_text(plan_handle) 
WHERE [dbid] = DB_ID('databasename') 
AND [objectid] = OBJECT_ID('databasename.dbo.us_spname') 
GO 

工作場景 - 緩存p LAN產生 步驟1

改變SP

IF (LTRIM(RTRIM(ISNULL(@param_ids,''))) = '') 
    BEGIN 
    --SELECT @param_ids = COALESCE(@param_ids + ',', '') + CONVERT(VARCHAR(50),ID) 
    --FROM [dbo].Content_Type WITH (NOLOCK) 

    SELECT @param_ids = COALESCE('aaaaaaa' + ',', '') + CONVERT(VARCHAR(50),ID) 
    FROM [dbo].Content_Type WITH (NOLOCK) 
    END 

步驟2 Exec的SP使用參數

步驟3(高速緩存計劃退出)

SELECT * 
FROM sys.dm_exec_cached_plans 
CROSS APPLY sys.dm_exec_sql_text(plan_handle) 
WHERE [dbid] = DB_ID('databasename') 
AND [objectid] = OBJECT_ID('databasename.dbo.us_spname') 
GO 

Thankx

+0

雖然我嘗試在我的本地我得到不同的dbID和DB_ID('databasename')。請在您的select語句中包含DB_ID('databasename'),OBJECT_ID('databasename.dbo.us_spname')我認爲它們可能會不同於這兩種情況 – 2011-02-02 06:28:02

回答

0

我添加了一個WAITFOR,並且始終如一地得到一個計劃。這應該是獨立的參數

CREATE PROC dbo.testplan @param_ids varchar(max) OUTPUT 
AS 
IF (LTRIM(RTRIM(ISNULL(@param_ids,''))) = '') 
    BEGIN 
    SELECT @param_ids = COALESCE(@param_ids + ',', '') + CONVERT(VARCHAR(50),ID) 
    FROM [dbo].Content_Type WITH (NOLOCK) 
    END 
GO 
CREATE PROC dbo.testplan2 @param_ids varchar(max) OUTPUT 
AS 
IF (LTRIM(RTRIM(ISNULL(@param_ids,''))) = '') 
    BEGIN 
    SELECT @param_ids = COALESCE(@param_ids + ',', '') + CONVERT(VARCHAR(50),ID) 
    FROM [dbo].Content_Type WITH (NOLOCK) 
    END 
GO 

EXEC dbo.testplan 'bar' 
GO 
WAITFOR DELAY '00:00:02' 
SELECT OBJECT_NAME([objectid]), * 
FROM sys.dm_exec_cached_plans 
CROSS APPLY sys.dm_exec_sql_text(plan_handle) 
WHERE [dbid] = DB_ID() 
AND [objectid] = OBJECT_ID('testplan') 
GO 

EXEC dbo.testplan2 '' 
GO 
WAITFOR DELAY '00:00:02' 
SELECT OBJECT_NAME([objectid]), * 
FROM sys.dm_exec_cached_plans 
CROSS APPLY sys.dm_exec_sql_text(plan_handle) 
WHERE [dbid] = DB_ID() 
AND [objectid] = OBJECT_ID('testplan2') 
GO