You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在.NET中提取SQL Server可空输出参数的底层系统类型?

在.NET中提取SQL Server可空输出参数的底层系统类型

我正在尝试在.NET中提取SQL Server可空输出参数的底层系统类型(即使参数值为NULL)。这类参数类型的FullName示例如下:

FullName = "System.Nullable`1[[System.Int32, System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]]&"}

使用Nullable.GetUnderlyingType(pinfo.parameterType)时,仅针对输出参数会返回null。我想找到一种正规方法替代当前的字符串处理方式,目前的代码如下:

if (pi != null)
{
    t = Nullable.GetUnderlyingType(pi.ParameterType) ?? pi.ParameterType;
    isOut = pi.IsOut;
}
if (isOut)
{
    //output vars do weird 5#1T with types
    //FullName = "System.Nullable`1[[System.Int32, System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]]&"}
    // so we to get the underlying type by this kludge for now.
    // need a better way in future
//
    if (t.Name == "Nullable`1&")
    {
        int pos1 = t.FullName.IndexOf("[[") + 2;
        int pos2 = t.FullName.IndexOf(",", pos1 + 1);
        string tname = t.FullName.Substring(pos1, pos2 - pos1);
        t = System.Type.GetType(tname);

    }
}

用于测试的SQL存储过程如下:

ALTER PROCEDURE [dbo].[spTestOutputVariableHandling]
    -- Add the parameters for the stored procedure here
    @ErrorSeverity INT,
    @ErrorState INT,
    @idVar UNIQUEIDENTIFIER OUTPUT ,
    @boolVar BIT OUTPUT,
    @stringVar NVARCHAR(255) OUTPUT,
    @intVar INT OUTPUT,
    @decVar DECIMAL(18,2) OUTPUT,
    @singleVar REAL OUTPUT,
    @doubleVar FLOAT OUTPUT,
    @dateVar DATETIME2 OUTPUT
    AS
BEGIN
    -- SET NOCOUNT ON added to prevent extra result sets from

    SET @idVar= NEWID()
    SET @boolVar = 1
    SET @stringVar = 'Test String'
    Set @intVar = 1000
    SET @decVar = 234.67
    SET @singleVar = 7474747.587598
    SET @doubleVar = 8876543212345.98767
    SET @dateVar = GETDATE()


SELECT TOP 1 * FROM Things
IF (@ErrorSeverity > 0) 
BEGIN

    DECLARE @erMsg NVARCHAR(MAX)
    Set @erMsg = 'Test Error Severity:'+STR(@ErrorSeverity,3,0)+'State: '+STR(@ErrorState,3,0)
    RAISERROR(@erMSg,@ErrorSeverity, @ErrorState) WITH LOG
END

END

正规解决方案

问题根源在于输出参数的类型是引用类型(ByRef),对应示例中的&标记,直接用Nullable.GetUnderlyingType无法处理这种类型。需要先获取引用类型指向的实际元素类型,再提取底层类型。

修改后的代码如下:

if (pi != null)
{
    isOut = pi.IsOut;
    Type parameterType = pi.ParameterType;
    // 处理输出参数的引用类型,提取实际元素类型
    if (parameterType.IsByRef)
    {
        parameterType = parameterType.GetElementType();
    }
    // 正常提取可空类型的底层类型
    t = Nullable.GetUnderlyingType(parameterType) ?? parameterType;
}

关键逻辑说明

  1. IsByRef:判断当前类型是否为引用类型(对应输出参数的&标记)
  2. GetElementType():获取引用类型指向的实际元素,比如Nullable<int>&会被转换为Nullable<int>
  3. 后续调用Nullable.GetUnderlyingType即可正确提取出底层的int类型,完全替代不可靠的字符串解析逻辑

内容的提问来源于stack exchange,提问作者Matthew Hudson

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 17:14:56