确定SP参数在T-SQL中是否具有默认值

San*_*tam 10 t-sql sql-server stored-procedures sql-server-2012

如果SP的参数具有默认值,有没有办法从SQL Server(我在2012年FYI)内确定?还有其他 线程,但建议似乎没有准确地告诉我这些信息.

这是我尝试过的几件事;

select *
from sys.objects so join sys.parameters sp on so.object_id = sp.object_id
where so.type='P'
and so.name = 'someSp'
Run Code Online (Sandbox Code Playgroud)

上面的查询返回了许多列,听起来像是在咆哮着正确的树(has_default_value,default_value在其中)但是这些似乎并没有变化我的SP中是否有默认值.(has_default值始终为0,default_value始终为null)

exec sp_sproc_columns 'someSp'
Run Code Online (Sandbox Code Playgroud)

同样的交易; 上面的SP返回多个列,包括NULLABLE和IS_NULLABLE; 无论我的SP内容如何,​​NULLABLE始终等于1且IS_NULLABLE = YES.

一张纸条; SQL Server管理工作室清楚地显示与每个SP参数关联的元数据.

Management Studio 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
Run Code Online (Sandbox Code Playgroud)

Dev*_*art 1

MS SQL 仅存储 CLR 存储过程和函数的默认设置,因此在这种情况下唯一的方法是解析对象定义。\n要运行该示例,您可以创建一个空白存储过程,或采用任何其他存储过程。

\n\n
ALTER PROCEDURE dbo.usp_test1\n(\n    @a UNIQUEIDENTIFIER = NULL,\n    @b DATETIME = '20100101',\n    @c DATETIME = DEFAULT,\n    @d BIT = 1,\n    @e BIT,\n    @k INT = 1,\n    @f BIT = 0, @g NVARCHAR(MAX) = '23235',\n    @h INT = 3,\n    @j DECIMAL(10,2) = DEFAULT\n)\nWITH RECOMPILE\nAS\nBEGIN\n\n    PRINT 1;\n\nEND\n
Run Code Online (Sandbox Code Playgroud)\n\n

此查询返回存储过程的默认值列表:

\n\n
SELECT  \n      data3.name\n    , [default_value] = REVERSE(RTRIM(SUBSTRING(\n          data3.rtoken\n        , CASE \n            WHEN CHARINDEX(N',', data3.rtoken) > 0 \n                THEN CHARINDEX(N',', data3.rtoken) + 1\n            WHEN CHARINDEX(N')', data3.rtoken) > 0 \n                THEN CHARINDEX(N')', data3.rtoken) + 1\n            ELSE 1 \n          END\n        , LEN(data3.rtoken)\n      )))\nFROM (\n    SELECT  \n          data2.name\n        , rtoken = REVERSE(\n            SUBSTRING(ptoken\n                    , CHARINDEX('=', ptoken, 1) + 1\n                    , LEN(data2.ptoken))\n                )\n    FROM (\n        SELECT  \n              data.name\n            , ptoken = SUBSTRING(\n                  data.tokens\n                , token_pos + name_length + 1\n                , ISNULL(ABS(next_token_pos - token_pos - name_length - 1), LEN(data.tokens))\n            )\n        FROM (\n            SELECT  \n                  sm3.tokens\n                , p.name\n                , name_length = LEN(p.name)\n                , token_pos = CHARINDEX(p.name, sm3.tokens)\n                , next_token_pos = CHARINDEX(p2.name, sm3.tokens)\n            FROM (\n                SELECT \n                      sm2.[object_id]\n                    , sm2.[type]\n                    , tokens = REVERSE(SUBSTRING(sm2.tokens, ISNULL(CHARINDEX('SA', sm2.tokens) + 2, 0), LEN(sm2.tokens))) \n                FROM (\n                    SELECT \n                          sm.[object_id]\n                        , o.[type]\n                        , tokens = REVERSE(SUBSTRING(\n                                      sm.[definition]\n                                    , CHARINDEX(o.name, sm.[definition]) + LEN(o.name) + 1\n                                    , ABS(CHARINDEX(N'AS', sm.[definition]))\n                                 )  \n                        ) \n                    FROM sys.sql_modules sm WITH (NOLOCK)\n                    JOIN sys.objects o WITH (NOLOCK) ON sm.[object_id] = o.[object_id]\n                    JOIN sys.schemas s WITH (NOLOCK) ON o.[schema_id] = s.[schema_id] \n                    WHERE o.[type] = 'P '\n                        AND s.name + '.' + o.name = 'dbo.usp_test1'\n                ) sm2\n                WHERE sm2.tokens LIKE '%=%'\n            ) sm3\n            JOIN sys.parameters p WITH (NOLOCK) ON sm3.[object_id] = p.[object_id]\n            OUTER APPLY (\n                SELECT p2.name\n                FROM sys.parameters p2 WITH (NOLOCK) \n                WHERE p2.is_output = 0\n                    AND sm3.[object_id] = p2.[object_id] \n                    AND p.parameter_id + 1 = p2.parameter_id\n            ) p2\n            WHERE p.is_output = 0\n        ) data\n    ) data2\n    WHERE data2.ptoken LIKE '%=%'\n) data3\n
Run Code Online (Sandbox Code Playgroud)\n\n

通过这个查询,您可以知道存储过程是否包含任何默认值\xe2\x80\x8b\xe2\x80\x8b:

\n\n
DECLARE @name SYSNAME = 'dbo.usp_test1'\n\nIF EXISTS(\n    SELECT 1\n    FROM (\n        SELECT \n              sm2.[object_id]\n            , tokens = SUBSTRING(sm2.tokens, ISNULL(CHARINDEX('SA', sm2.tokens) + 2, 0), LEN(sm2.tokens)) \n        FROM (\n            SELECT \n                  sm.[object_id]\n                , tokens = REVERSE(SUBSTRING(\n                                sm.[definition]\n                            , CHARINDEX(o.name, sm.[definition]) + LEN(o.name) + 1\n                            , ABS(CHARINDEX(N'AS', sm.[definition]))\n                        )  \n                ) \n            FROM sys.sql_modules sm WITH (NOLOCK)\n            JOIN sys.objects o WITH (NOLOCK) ON sm.[object_id] = o.[object_id]\n            JOIN sys.schemas s WITH (NOLOCK) ON o.[schema_id] = s.[schema_id] \n            WHERE o.[type] = 'P '\n                AND s.name + '.' + o.name = @name\n        ) sm2\n    ) sm3\n    WHERE sm3.tokens LIKE '%=%'\n) PRINT @name + ' have default values'\n
Run Code Online (Sandbox Code Playgroud)\n