ASP.net:调用存储过程 -- 代码取不到输出(Output)参数值 - 因ExecuteReader不当使用

        存储过程的输出参数的使用,相信大家早晚多少都(会)用到过。不知用到过朋友,有没有遇到在程序中“咋就”取不到想要的输出值的情况;始终是null值。昨天本人就遇到了,也可能是用的不多,这种情况也是第一次遇到。项目中也不是只有一次用到输出参数,但也没有出现这样情况。跟同事讨论一下也没问出个所以然来,让搞架构师的同事调试一下也没结果。他也一直纳闷,其它地方用的好好的,咋这地方就不行呢!项目中的业务逻辑基础通用代码都是通过模板自动生成的。没办法,只好笨方法了;对比一下能用的地方的代码,一点一点的追根溯源;看看到底区别在哪里。最后锁定在数据访问层用到的系统方法ExecuteReaderExecuteNonQuery上;也是大概猜的,难道是出在这里吗?为方便读者观察就把最后代码贴出来了。

        public int ExecuteSPNonQuery(string procedureName)
        {
            SqlCommand cmd = new SqlCommand();
            this.Connect();
            int effectedRows = -1;
            cmd.CommandTimeout = this.CommandTimeout;
            cmd.CommandText = procedureName;
            cmd.Connection = _connection;
            if (_transaction != null) cmd.Transaction = _transaction;
            cmd.CommandType = CommandType.StoredProcedure;
            this.CopyParameters(cmd);

            effectedRows = cmd.ExecuteNonQuery();

            _parameterCollection = cmd.Parameters;
            cmd.Dispose();

            if (this.AutoCloseConnection) this.Disconnect();
            return effectedRows;
        }

        public DbDataReader ExecuteSPReader(string procedureName)
        {
            SqlDataReader reader;
            SqlCommand cmd = new SqlCommand();
            this.Connect();

            cmd.CommandTimeout = this.CommandTimeout;
            cmd.CommandText = procedureName;
            cmd.Connection = _connection;
            if (_transaction != null) cmd.Transaction = _transaction;
            cmd.CommandType = CommandType.StoredProcedure;
            this.CopyParameters(cmd);

            CommandBehavior behavior = CommandBehavior.Default;

            if (this.AutoCloseConnection) behavior = behavior | CommandBehavior.CloseConnection;
            if (_isSingleRow) behavior = behavior | CommandBehavior.SingleRow;

            reader = cmd.ExecuteReader(behavior);

            _parameterCollection = cmd.Parameters;
            cmd.Dispose();

            return reader;
        }

基本上一样,除了些不相干代码;问题大概就在那个地方了。此时咋办?打开搜索引擎,输入“Output ExecuteReader “,点击搜索。结果又是一大堆!打开一看热心的网友早把情况贴出来了。通过ExecuteReader(), 要想能取出输出参数值,必须把reader close掉后可以。二话不说试了一下,果不其然;关掉再从cmd.Parameters 中取出对应的输出参数值就可以了。而用ExecuteNonQuery()是不会出现这样问题的。后来和那个搞架构的同事说了,他才恍然大悟。他说遇到过,而且也改了对应模板;只是忘记迁入到我们项目模板中了。晕倒!


引发思考:ParameterDirection枚举里面四个成员的区别(来自微软官方网)http://technet.microsoft.com/zh-cn/magazine/system.data.parameterdirection(VS.90).aspx

Input 参数是输入参数。
Output 参数是输出参数。
InputOutput 参数既能输入,也能输出。
ReturnValue 参数表示诸如存储过程、内置函数或用户定义函数之类的操作的返回值。

 

注意事项:http://www.cnblogs.com/Dlonghow/archive/2008/11/19/1336406.html

1、.Net中的参数定义为形式参数 而把存储过程的参数定义为实际参数;

2、数据库存储过程的实际参数如果没有默认值则形式参数必须传值给实际参数; 

3、但是如果形式参数的类型为ParameterDirection.Output 则传给实际参数的永远是空值;

4、如果形式参数的类型为ParameterDirection.ReturnValue 则形式参数不会传值给实际参数 实际参数必须有默认值  否则代码会报错;

5、如果形式参数类型为ParameterDirection.InputOutput 或者 ParameterDirection.Output 则实际参数必须有output 关键字.

 

引用他例:http://hi.baidu.com/jeloly/blog/item/05743424d25e653a8744f904.html

ParameterDirection.ReturnValue 和ParameterDirection.OutPut返回值的区别?

Output 参数是输出参数。
ReturnValue 参数表示诸如存储过程、内置函数或用户定义函数之类的操作的返回值。

示例如下:

create proc 名称 @out int out
as
begin

set @out = 100;
return 200;
end

这个out就是output参数

返回的200是returnvalue,
output参数可能有多个,return value只有一个

总结:Output、ReturnValue都可以返回存储过程处理过的值,ReturnValue只能返回一个值,而output可以设置一个或多个返回值,这就是区别。

 

kevin.chen

2012-02-28

 

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

奋斗的小壁虎

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值