【发布时间】:2016-08-31 03:43:16
【问题描述】:
我有一个处理 Web 服务调用的过程。这是一个 SQL 2012 环境。 proc 采用存储过程名称和任意一组过程参数(用字符串分隔符分隔)。在 proc 中,我构建如下语句:-
INSERT INTO @Params
SELECT p.parameter_id, p.name AS ParameterName, t.name AS ParameterType, p.max_length AS ParameterLength, ''
FROM sys.parameters AS p
JOIN sys.types AS t ON t.user_type_id = p.user_type_id
WHERE object_id = OBJECT_ID(RTRIM(LTRIM(@ProcName)))
UPDATE P
SET pValue = s.data
FROM dbo.split(@ParamList,'ç') as S
INNER JOIN @Params as P ON P.id = S.ID
SELECT @ParamSplit = ISNULL(Stuff((SELECT ',' +
pName + '=' +
CASE
WHEN pValue = 'ÆNULL' THEN 'NULL'
WHEN pType = 'varchar' THEN char(39) + replace(pValue,char(39),char(39) + char(39)) + char(39)
WHEN pType = 'date' THEN char(39) + replace(pValue,char(39),char(39) + char(39)) + char(39)
WHEN pType = 'datetime' or pType='TIME' THEN char(39) + replace(pValue,char(39),char(39) + char(39)) + char(39)
else pValue
END
FROM @Params
FOR XML PATH ('')),1,1,''),'')
这很好用。我感谢并非所有数据类型都经过检查,但出于我的目的(这是一个封闭系统),它涵盖了所有必需的基础。但是我有一个问题,因为调用服务必须传递所有参数,甚至是过程中可能默认的参数。
sys.parameters 表中有一个字段
有默认值
和另一个字段
默认值
,但检查他们的 Microsoft 文档 说:-
默认值仅记录在 sys.parameters.default 列中 用于 CLR 程序。对于 Transact-SQL,该列将为 NULL 过程参数。
我想做的是确定我正在调用的 proc 是否有任何默认参数,如果它们有(并且调用服务没有传递它们)我可以使用默认值,否则这些可以被任何调用替换服务已过。
所以...问题 - 有谁知道如何识别 proc 是否分配了任何默认参数?
【问题讨论】:
-
this question 的答案包含解析过程定义以检索默认值的方法。我不确定是否有更清洁的方法。
-
您可以:1) 创建将拦截
CREATE/ALTER procedure的 DDL 触发器 2) 解析定义以检索默认值 3) 放入扩展属性 4) 在您的代码中列出来自sys.parameters的所有参数并获取扩展事件的默认值。类似于 demo。完全有可能以自动化的方式实现它。如果您在JSON/XML format中有某种文档作为注释,解析可能会更简单。 -
这是一个现有的生产数据库,因此打开引擎盖并不实用。我可以查询那里有什么 - 不能真正修改任何 procs。我认为在运行时解析会效率低下(这些过程被调用很多,每秒可能会调用很多次)。我想我可以假设如果 Web 服务没有传递所有参数,那么任何错过的都必须由默认值 - 所以可以在没有这些参数的情况下调用 proc。我认为这会奏效...
标签: sql-server tsql stored-procedures sql-server-2012