2015-06-17 54 views
1

我有一個C#WinForms管理不同服務使用的存儲過程的應用程序。什麼是用戶看到的是這樣的事情:如何檢索部分存儲過程的頭文件?

exec stored_procedure_name param1, param2, param3 

而且,由於參數1並不意味着任何東西給他們(他們不能看到存儲過程),我想呈現給它們的參數的小說明,這些通常保存在存儲過程的頭文件中。

一個典型的存儲過程想:

IF EXISTS (SELECT * FROM sys.objects WHERE object_id = OBJECT_ID(N'[dbo].[stored_procedure_name]') AND type in (N'P', N'PC')) 
DROP PROCEDURE [dbo].[stored_procedure_name] 
GO 

SET ANSI_NULLS ON 
GO 

SET QUOTED_IDENTIFIER ON 
GO 

/************************************************************************************* 
[Procedure Info] 
Author = myName 
Description = this stored procedure returns results. 

************************************************************************************** 
[Parameters Info] 
@param1 = this is parameter one 
@param2 = this is parameter two 
@param3 = this is parameter three 

************************************************************************************** 
[Changes] 
2015-06-17 The stored procedure is optimized. 

*/ 

CREATE PROCEDURE [dbo].[stored_procedure_name] 
@param1 int, 
@param2 nvarchar(20), 
@param3 nvarchar(10) 
AS 
BEGIN 
    -- SP code here 
END 
GO 

從上面的,我想在參數信息的描述。我知道我可以使用下面的SQL檢索存儲過程作爲文/表:

CREATE TABLE #tmpHeader 
(
    TEXT NVARCHAR(1000) 
) 

INSERT INTO #tmpHeader 
EXEC sp_helptext 'stored_procedure_name'; 

SELECT * FROM #tmpHeader 

DROP TABLE #tmpHeader 

任何意見或建議,就如何從這裏出發,以獲取這些參數信息的內容? 我也接受任何其他建議。

回答

4

考慮使用擴展屬性來存儲元數據。這比解析模塊文本更清晰。

編輯: 以下示例返回所有參數以及具有擴展屬性的參數的描述。在您的代碼中,您可以傳遞模式和對象名稱作爲參數,而不是用於說明的局部變量。

EXEC sp_addextendedproperty @name = N'Description', 
    @value = 'this is parameter one', @level0type = N'Schema', 
    @level0name = 'dbo', @level1type = N'Procedure', 
    @level1name = 'stored_procedure_name', @level2type = N'Parameter', 
    @level2name = '@param1'; 
    GO 
EXEC sp_addextendedproperty @name = N'Description', 
    @value = 'this is parameter two', @level0type = N'Schema', 
    @level0name = 'dbo', @level1type = N'Procedure', 
    @level1name = 'stored_procedure_name', @level2type = N'Parameter', 
    @level2name = '@param2'; 
    GO 
EXEC sp_addextendedproperty @name = N'Description', 
    @value = 'this is parameter three', @level0type = N'Schema', 
    @level0name = 'dbo', @level1type = N'Procedure', 
    @level1name = 'stored_procedure_name', @level2type = N'Parameter', 
    @level2name = '@param3'; 
    GO 

DECLARE 
     @SchemaName sysname = 'dbo' 
    , @ObjectName sysname = 'stored_procedure_name'; 

SELECT properties.objtype 
     , properties.objname 
     , parms.name 
     , properties.value 
FROM sys.parameters AS parms 
LEFT JOIN fn_listextendedproperty('Description', 'Schema', @SchemaName, 'Procedure', 
           @ObjectName, 'Parameter', DEFAULT) AS properties ON 
    properties.objname COLLATE DATABASE_DEFAULT = parms.name 
WHERE 
    parms.object_id = OBJECT_ID(QUOTENAME(@SchemaName) + '.' + QUOTENAME(@ObjectName)); 
GO 
+0

這是一個很好的建議。如果存儲過程發生變化,並且參數被添加,刪除或編輯,那麼會怎麼做呢? – Apostrofix

+0

@Apostrofix,就像註釋一樣,擴展屬性需要獨立於參數本身來維護。我將更新我的答案,以便查詢返回所有已定義的參數,併爲缺少的參數描述返回NULL。 –

1

這應該讓你的想法尋找。

SELECT SUBSTRING(definition,CHARINDEX(N'[Parameters Info]',definition),CHARINDEX(N'[',definition,CHARINDEX(N'[Parameters Info]',definition)+1)-CHARINDEX(N'[Parameters Info]',definition)) 
FROM sys.sql_modules 
WHERE object_id = OBJECT_ID('YOUR PROCEDURE!!!') 

它搜索參數信息並繼續前進,直到找到另一個標題塊(以[開頭]開頭。你也可以指定它應該搜索*。

+0

好主意,它比我要去的方向簡單得多。是否有可能將參數信息塊拆分爲單獨的行,就像它在頭中一樣? – Apostrofix

+0

是的,這應該是可行的。我目前沒有時間做短代碼。但我會建議將這些字符串放入一個cte中,然後遍歷它並搜索回車符。 :-) – Ionic