如何确定C#数据访问层中存储过程输出参数的大小属性

如何确定C#数据访问层中存储过程输出参数的大小属性,c#,sql-server,stored-procedures,ado.net,parameters,C#,Sql Server,Stored Procedures,Ado.net,Parameters,我制作了一个数据访问层,它无耻地模仿了Castle项目的ActiveRecord实现。为了让它获得认可,它必须支持我的组织中使用的大量存储过程库,这些存储过程被编写为使用每个可以想象的输入/输出结构,包括每个可以想象的数据类型的返回值和输出参数 我的问题在于开发将输出参数添加到用于执行存储过程的命令对象的参数集合的代码。现在我只是使用了一个很大的默认值,希望它足以抓住所有的案例,但这感觉很差劲 如何提前知道输出参数的长度 这是我的DAL类,使用属性表示输出参数: [StoredProcedur

我制作了一个数据访问层,它无耻地模仿了Castle项目的ActiveRecord实现。为了让它获得认可,它必须支持我的组织中使用的大量存储过程库,这些存储过程被编写为使用每个可以想象的输入/输出结构,包括每个可以想象的数据类型的返回值和输出参数

我的问题在于开发将输出参数添加到用于执行存储过程的命令对象的参数集合的代码。现在我只是使用了一个很大的默认值,希望它足以抓住所有的案例,但这感觉很差劲

如何提前知道输出参数的长度

这是我的DAL类,使用属性表示输出参数:

 [StoredProcedure("usp_PostARTransaction", OperationType.Insert)]
    public class ARTranPost : DataObjectBase<ARTranPost>
    {
        [StoredProcedureParameter("sARTranID",OperationType.Insert,ParameterDirection.Output)]
        public string ARTranID {get;set;}
        [StoredProcedureParameter("sDueDate", OperationType.Insert, ParameterDirection.Input)]
        public string DueDate { get; set; }
        [StoredProcedureParameter("sPostDate", OperationType.Insert, ParameterDirection.Input)]
        public string PostDate { get; set; }

    }
[存储过程(“usp\U PostartTransaction”,OperationType.Insert)]
公共类ARTranPost:DataObjectBase
{
[StoredProcedureParameter(“sARTranID”,OperationType.Insert,ParameterDirection.Output)]
公共字符串ARTranID{get;set;}
[StoredProcedureParameter(“sDueDate”,OperationType.Insert,ParameterDirection.Input)]
公共字符串DueDate{get;set;}
[StoredProcedureParameter(“sPostDate”,OperationType.Insert,ParameterDirection.Input)]
公共字符串PostDate{get;set;}
}

是否需要使用SMO或其他库从数据库获取长度?

您必须查看SQL代码。或反射(和缓存)

编辑:这里强调了一些技巧

  • 自动生成存储过程的包装类

存储过程中的输出参数具有数据类型/大小。用那个

如果您的SP类似于:

create procedure DoThis
    @parm1 int
    , @parm2 varchar(50) output
as

select @parm2 = (
select breed from dogs
where dogid = @parm1
)
您知道输出参数是什么。叫它

public string DoThis(int dogid)
{
    SqlCommand cmd = new SqlCommand("DoThis");
    cmd.CommandType = CommandType.StoredProcedure;
    cmd.Connection = theConnection;

    cmd.Parameters.Add(new SqlParameter("@parm1", dogid);
    cmd.Parameters["@parm1"].DbType = DbType.Int32;

    cmd.Parameters.Add(new SqlParameter("@parm2", DbType.String, 50));
    cmd.Parameters["@parm2"].Direction = ParameterDirection.Output;

    db.ExecuteNonQuery(cmd);

    return (string) cmd.Parameters["@parm2"];

}
如果在SQL Server上工作(OP中未指定),则可以使用sysobjects和syscolumns目录视图检索存储过程及其参数:

SELECT p.name, t.name, c.*
FROM sysobjects p
INNER JOIN syscolumns c ON p.id = c.id
INNER JOIN systypes t on c.xusertype = t.xusertype
WHERE p.type = 'P'
AND p.name NOT LIKE 'dt[_]%'
ORDER BY p.name, c.colid
(在SQL2005+中,使用sys.objects、sys.types和sys.columns,但旧视图仍然存在)

这将为您提供SP名称、类型名称、参数名称、长度和输入/输出方向(c.isoutparam)


我在我的博客上写道。我没有在这里介绍参数,但是将代码调整为输出参数应该很简单。

这是针对通用DAL的,我不知道将调用什么SP。我将更新我的问题,使其更加明显。当然,您可以获得列的长度,但这并不能告诉您访问表的存储过程将返回什么。SP可以从一个或二十个表中获取列信息、连接它们、截断它们或替换自己的值。根据这张表无法预测这一点。你必须知道SP正在发送回什么。这太酷了!我一读到这篇文章就拍了拍额头。我用过sys。以前的东西,但我从来没有想到这可以用于SP的。狡猾,德维奥!