sql-server - 存储过程默认参数标识

标签 sql-server tsql stored-procedures sql-server-2012

我有一个正在为 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,''),'')  

这工作正常。我很欣赏并非所有数据类型都被检查,但出于我的目的(这是一个封闭系统),它涵盖了所有必需的基础。但是我有一个问题,因为调用服务必须传递所有参数,甚至可能在 proc 中默认的参数。

sys.parameters 表中有一个字段是

has_default_value



和另一个领域

default_value



,但检查 Microsoft 文档,他们
说: -

Default values are recorded in the sys.parameters.default column only for CLR procedures. That column will be NULL for Transact-SQL procedure parameters.



我想要做的是确定我正在调用的 proc 是否有任何默认参数,如果有(并且调用服务没有通过它们)我可以使用默认值,否则这些可以被调用服务通过的任何内容替换.

所以......问题 - 有谁知道如何确定 proc 是否分配了任何默认参数?

最佳答案

您可以尝试这样做,但可能需要检查存储过程定义的格式,您可以从应用程序中调用它并在客户端缓存以防止性能下降:

Declare @ProcedureName VARCHAR(50) = 'MySP'
DECLARE @text VARCHAR(MAX)
DECLARE @startPos int = 0
DECLARE @endPos int = 0

SELECT @text=text FROM syscomments
WHERE id = object_id(@ProcedureName) and colid=1 AND text LIKE '%(%'

IF @text IS NULL 
BEGIN
    -- No Parameters in stored procedure
    PRINT 'No Parameters'
END
ELSE
BEGIN

    -- Find Start of parameter declaration
    SELECT @startPos = PATINDEX( '%(%' ,@text)
    -- Find end of parameter declaration
    SELECT @endPos = PATINDEX( '%AS' + CHAR(13) + '%' ,@text)

    -- Set Text to our parameters string
    SELECT @text = SUBSTRING(@text, @startPos + 1, @endpos - @startpos -4)

    -- Split parameters and insert into table 
    -- Alternatively use other string splitting techniques such as numbers table
    DECLARE @t1 TABLE (id INT IDENTITY(1,1), val NVARCHAR(MAX))
    DECLARE @xml XML
    SET @xml = N'<t>' + REPLACE(@text,',','</t><t>') + '</t>'
    INSERT INTO @t1(val)
    SELECT  r.value('.','varchar(MAX)') as item
    FROM  @xml.nodes('/t') as records(r)


    SELECT  SUBSTRING(val, PATINDEX('%@%', val), PATINDEX('% %', val) - PATINDEX('%@%', val)) as Parm, 
            SUBSTRING(val, PATINDEX('%=%',val) + 1, DATALENGTH(val) - PATINDEX('%=%',val)) As DefaultValue
    FROM @t1
    WHERE val like '%=%' -- Only get parameters with default value

END

关于sql-server - 存储过程默认参数标识,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37049135/

相关文章:

sql-server - sql server 中所有数据库的默认位置在哪里

sql - 在 SQL 中动态比较不同列和行中的日期

sql - 将 SQL 数据拆分为月份

java - 从存储过程中获取输出参数而不调用 execute()

mysql - MYSQL 上的 SELECT CASE 和 CALL 过程

mysql - FROM 子句中的子查询在 MySQL 中失败

SQL Server - 按月对存档等记录进行分组

sql - 在 SQL 中获取平均值忽略所有小于 0 的值

sql - 带外键引用行数的多表选择

nhibernate - 如何使用 NHibernate 调用从多个表返回结果的过程?