如何检索存储过程的 header 的一部分?

How to retrieve a part of a stored procedure's header?

我有一个 C# WinForms 应用程序来管理不同服务使用的存储过程。用户看到的是这样的:

exec stored_procedure_name param1, param2, param3

并且由于 param1 对他们没有任何意义(他们看不到存储过程),我想向他们介绍通常保存在 header 中的参数的简短描述存储过程。

典型的存储过程如下:

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 将存储过程检索为 text/table:

CREATE TABLE #tmpHeader
(
   TEXT NVARCHAR(1000)
)

INSERT INTO #tmpHeader
EXEC sp_helptext 'stored_procedure_name';

SELECT * FROM #tmpHeader

DROP TABLE #tmpHeader

关于如何从这里着手获取参数信息的内容有什么想法或建议吗? 我也愿意接受任何其他建议。

这应该是您正在寻找的想法。

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!!!')

它搜索参数信息并继续搜索,直到找到另一个 header 块(以 [ 开头)。您还可以指定它应该搜索 *.

考虑使用扩展属性来存储元数据。这比解析模块文本要干净得多。

编辑: 下面的示例 returns 所有参数以及具有扩展属性的那些参数的说明。在您的代码中,您可以将模式和对象名称作为参数传递,而不是此处用于说明的局部变量。

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