如果SP的参数具有默认值,有没有办法从sql Server(我在2012年FYI)内确定?这有
other
threads,但建议似乎没有准确地告诉我这些信息.
这是我尝试过的几件事;
select * from sys.objects so join sys.parameters sp on so.object_id = sp.object_id where so.type='P' and so.name = 'someSp'
上面的查询返回了一些听起来像我正在咆哮右侧树的列(has_default_value,其中包含default_value)但这些列似乎没有变化,无论我的SP中是否有默认值. (has_default值始终为0,default_value始终为null)
exec sp_sproc_columns 'someSp'
同样的交易;上面的SP返回多个列,包括NULLABLE和IS_NULLABLE;无论我的SP内容如何,NULLABLE始终等于1且IS_NULLABLE = YES.
一张纸条; sql Server管理工作室清楚地显示与每个SP参数关联的元数据.
我使用sql事件探查器来检查在Management Studio的对象资源管理器中查看SP的参数时会发生什么.展开参数文件夹时,会运行两个查询.第一个查询在这里粘贴有点长(虽然如果有帮助我会这么做).它包含一个名为DEFAULT VALUE的列;但据我所知,它总是为NULL.第二个查询只返回SP的主体;大概是输出到文本编辑器窗口(虽然我担心在mgmt studio中可能会发生一些解析!)
作为参考/只是为了确保我没有丢失我的弹珠我已经创建了两个无意义的Sps仅用于测试.他们看着像是:
CREATE PROCEDURE TestDefaultSpValue_Default @I INT = 2 AS BEGIN SET NOCOUNT ON; SELECT @I END CREATE PROCEDURE TestDefaultSpValue_NoDefault @I INT AS BEGIN SET NOCOUNT ON; SELECT @I END
解决方法
MS sql仅为CLR存储过程和函数存储默认设置,因此在这种情况下只能解析对象定义.
若要运行该示例,您可以创建一个空白存储过程,或采取任何其他过程.
若要运行该示例,您可以创建一个空白存储过程,或采取任何其他过程.
ALTER PROCEDURE dbo.usp_test1 ( @a UNIQUEIDENTIFIER = NULL,@b DATETIME = '20100101',@c DATETIME = DEFAULT,@d BIT = 1,@e BIT,@k INT = 1,@f BIT = 0,@g NVARCHAR(MAX) = '23235',@h INT = 3,@j DECIMAL(10,2) = DEFAULT ) WITH RECOMPILE AS BEGIN PRINT 1; END
此查询返回存储过程的默认值列表:
SELECT data3.name,[default_value] = REVERSE(RTRIM(SUBSTRING( data3.rtoken,CASE WHEN CHARINDEX(N',',data3.rtoken) > 0 THEN CHARINDEX(N',data3.rtoken) + 1 WHEN CHARINDEX(N')',data3.rtoken) > 0 THEN CHARINDEX(N')',data3.rtoken) + 1 ELSE 1 END,LEN(data3.rtoken) ))) FROM ( SELECT data2.name,rtoken = REVERSE( SUBSTRING(ptoken,CHARINDEX('=',ptoken,1) + 1,LEN(data2.ptoken)) ) FROM ( SELECT data.name,ptoken = SUBSTRING( data.tokens,token_pos + name_length + 1,ISNULL(ABS(next_token_pos - token_pos - name_length - 1),LEN(data.tokens)) ) FROM ( SELECT sm3.tokens,p.name,name_length = LEN(p.name),token_pos = CHARINDEX(p.name,sm3.tokens),next_token_pos = CHARINDEX(p2.name,sm3.tokens) FROM ( SELECT sm2.[object_id],sm2.[type],tokens = REVERSE(SUBSTRING(sm2.tokens,ISNULL(CHARINDEX('SA',sm2.tokens) + 2,0),LEN(sm2.tokens))) FROM ( SELECT sm.[object_id],o.[type],tokens = REVERSE(SUBSTRING( sm.[definition],CHARINDEX(o.name,sm.[definition]) + LEN(o.name) + 1,ABS(CHARINDEX(N'AS',sm.[definition])) ) ) FROM sys.sql_modules sm WITH (NOLOCK) JOIN sys.objects o WITH (NOLOCK) ON sm.[object_id] = o.[object_id] JOIN sys.schemas s WITH (NOLOCK) ON o.[schema_id] = s.[schema_id] WHERE o.[type] = 'P ' AND s.name + '.' + o.name = 'dbo.usp_test1' ) sm2 WHERE sm2.tokens LIKE '%=%' ) sm3 JOIN sys.parameters p WITH (NOLOCK) ON sm3.[object_id] = p.[object_id] OUTER APPLY ( SELECT p2.name FROM sys.parameters p2 WITH (NOLOCK) WHERE p2.is_output = 0 AND sm3.[object_id] = p2.[object_id] AND p.parameter_id + 1 = p2.parameter_id ) p2 WHERE p.is_output = 0 ) data ) data2 WHERE data2.ptoken LIKE '%=%' ) data3
通过此查询,您可以知道存储过程是否包含任何默认值:
DECLARE @name SYSNAME = 'dbo.usp_test1' IF EXISTS( SELECT 1 FROM ( SELECT sm2.[object_id],tokens = SUBSTRING(sm2.tokens,LEN(sm2.tokens)) FROM ( SELECT sm.[object_id],tokens = REVERSE(SUBSTRING( sm.[definition],sm.[definition])) ) ) FROM sys.sql_modules sm WITH (NOLOCK) JOIN sys.objects o WITH (NOLOCK) ON sm.[object_id] = o.[object_id] JOIN sys.schemas s WITH (NOLOCK) ON o.[schema_id] = s.[schema_id] WHERE o.[type] = 'P ' AND s.name + '.' + o.name = @name ) sm2 ) sm3 WHERE sm3.tokens LIKE '%=%' ) PRINT @name + ' have default values'