推荐.NET教程: ASP.NET C# 开发环境 Ajax教程 控件开发 统计报表 数据库 Web服务 安装部署 CommunityServer NHibernate DataGrid/GridView 实用代码 VS2005
示例源码 MVC/三层 SqlHelper 入门源码 开源 CMS Ajax/Atlas C#.net 毕业设计 源码 经典代码 商业 本站作品 持久层 随书源码 WebService 英文/汉化 Asp.net2.0

阿牛·乐园

每天进步一点点

  博客园 :: 首页 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::
  71 随笔 :: 14 文章 :: 367 评论 :: 13 Trackbacks
     我们写程序的,难免要和数据库进行打交道,存储过程的参数也是在编程中经常要用到的.
     但在存储过程参数中,如果有 int 型的参数,我一般习惯于这样写:
  
create PROCEDURE [dbo].[usp_jf_stat_log_jifen] 
(
    
@timebegin datetime,
    
@timeend datetime,
    
@stat     int --   0,所有  1,添加积分   2,消费积分
)
AS
begin
    
select * from table1 
end

     在客户端调用时代码如下:
            SqlParameter[] prms = new SqlParameter[] 
                
new SqlParameter("@timebegin",this.tbTimeBegin.Text.Trim()),
                
new SqlParameter("@timeend",this.tbTimeEnd.Text.Trim()),
                
new SqlParameter("@stat",0)                              //Convert.ToInt32(this.ddlStyle.SelectedValue))
            }
;

            DataSet ds 
= DbHelper.ExecuteDataset(DbHelper.ConnectionString, CommandType.StoredProcedure, "usp_jf_stat_log_jifen", prms);
    注意红色的"0",这时,这个参数,到底是DBNull.Value 呢?还是 (int32)0 呢?  我们打开SQL Server Profiler,发现执行的如下的TSQL语句:
   
exec usp_jf_stat_log_jifen @timebegin=N'2007-05-22',@timeend=N'2007-06-22',@stat=NULL
     是NULL,不是0.   真是一个臭虫.
     改成这样如何呢?   
                new SqlParameter("@stat",0D)                              
    结果还是这样:
exec usp_jf_stat_log_jifen @timebegin=N'2007-05-22',@timeend=N'2007-06-22',@stat=NULL
    最后改成这样:
                new SqlParameter("@stat",Convert.ToInt32(0))                              
   最后结果:
exec usp_jf_stat_log_jifen @timebegin=N'2007-05-22',@timeend=N'2007-06-22',@stat=0
   嘻嘻,终于成功了.

   本文章解决的只是一个小问题!为一个朋友解释什么是调程序,怎么调程序而写!
   哈哈!
posted on 2007-06-22 10:40 阿牛 阅读(1727) 评论(7)  编辑 收藏 所属分类: ASP.netC#TSQL

评论

#1楼  2007-06-22 10:50 S.Sams      
指定类型就不会出现这些问题的啦.
new SqlParameter("@stat", SqlDbType.Int, 4, 0)
  回复  引用  查看    

SqlParameter[] prms = new SqlParameter[] {
new SqlParameter("@timebegin",this.tbTimeBegin.Text.Trim()),
new SqlParameter("@timeend",this.tbTimeEnd.Text.Trim()),
new SqlParameter("@stat",0) //Convert.ToInt32(this.ddlStyle.SelectedValue))
};


这种编码风格是要被打板子的,所有参数必须指定类型和长度(楼上的方法),特别是char,varchar类型的字段,sql会默认为nvarchar(4000),这样导致你的索引无效。查询的时sql会用tab锁,进而导致数据库性能急剧下降。

  回复  引用    

#3楼  2007-06-22 11:45 Anders Liu      
S.Sams 说得对,任何时候在new SqlParameter时,都应该指定数据库方使用的类型。
  回复  引用  查看    

#4楼  2007-06-22 13:36 henry      
@oswica@gmail.com
是真的吗?和我在查询分析器看到的结果完全不一样.
其实在构造SqlParameter里如果不显式类型,SqlParameter是会根据当前参数类型进行匹配类型的(从效率上来说匹配是会带来一点点损耗),如果匹配不上会抛出一个非常怪异的异常...
  回复  引用  查看    

#5楼  2007-06-22 13:37 Lostinet      
DotNet2.0已经把这些方法obsolete掉.
要防止重载问题,声明为object就OK
new SqlParameter("@param",(object)val);

  回复  引用  查看    

#6楼 [楼主] 2007-06-22 14:27 阿牛      
@oswica@gmail.com
谢谢您的提醒!我会下次注意的.

@S.Sams
为了说明问题,才不指定类型的.哈哈
  回复  引用  查看    

#7楼  2007-06-25 04:10 csharp [未注册用户]
用了那麼久的SqlParameter
竟然沒發現會有這種事
  回复  引用