如何检索存储过程的 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
我有一个 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