项目总结——SqlParameter的参数设置长度(size属性)

本文解析SqlParameter实例化时指定参数长度的重要性。未指定长度时,SQL Server会根据参数值推断长度,导致每次执行SQL时可能生成不同的执行计划,降低执行效率。文章提供了正确示例并强调了指定size属性的必要性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

看到很多朋友在实例化SqlParameter时,通常都没有指定参数的长度就直接给参数赋值了。就像下面的写法:

newSqlParameter("@address",SqlDbType.Varchar){Value=address};

以前也一直都觉的加与不加参数长度应该没有什么区别,仅是写法上的不同而已,直到做完这个项目,才明白其实两者不一样的,为了提高sql执行速度,请为SqlParameter参数加上size属性。

下面我们分析一下两者的区别:

根据MSDN解释:如果未在size参数中显式设置Size,则从dbType参数的值推断出该大小

如果你认为上面的推断出该大小是指从SqlDbType类型推断,那你就错了,它实际上是从你传过来的参数的值来推断的,比如传递过来的值是"shengzhen",则size值为9,"shanghai",则size值为8。那么,不同的size值会引发什么样的结果呢?且经测试发现,size的值不同时,会导致数据库的执行计划不会重用,这样就会每次执行sql的时候重新生成新的执行计划,而浪费数据库执行时间。

比如:

stringsql="selecttop1*fromtable1whereaddress=@address";
SqlParameter[]parameter=newSqlParameter("@address",SqlDbType.VarChar){Value="shanghai"};
SqlHelper.ExecuteReader(ConnectionString,CommandType.Text,sql,parameter)

我们通过数据库跟踪工具SqlProfiler捕获到的sql如下:

execsp_executesqlN'selecttop1*fromtable1whereaddress=@address',N'@addressnvarchar(8)',@address=N'shanghai'

如果把参数的值改成shengzhen,则通过SqlProfiler捕获到的sql如下:


execsp_executesqlN'selecttop1*fromtable1whereaddress=@address',N'@addressnvarchar(9)',@o=N'shengzhen'

然后通过下面的sql来测试执行计划是否有重用:


--清空执行计划缓存
DBCC FREESYSTEMCACHE('ALL')
DBCC FREEPROCCACHE
GO
exec sp_executesql N'select top 1 * from T_GroupInfo where groupName = @groupName',N'@groupName nvarchar(8)',@groupName=N'第1组'
GO
SELECT * FROM sys.dm_exec_cached_plans WHERE cacheobjtype = 'Compiled Plan'
GO
exec sp_executesql N'select top 1 * from T_GroupInfo where groupName = @groupName',N'@groupName nvarchar(9)',@groupName=N'第2组'
GO
SELECT * FROM sys.dm_exec_cached_plans WHERE cacheobjtype = 'Compiled Plan'
GO

你会发现,第一条sql与第二条sql会各自生成自己的执行计划,而如果@address参数的长度一样的话,会使用同一个执行计划。

总结:

实例化SqlParameter时,如果是字符型,一定要指定size属性,如最上面的定义,应该修改为:

newSqlParameter("@address",SqlDbType.Varchar,4000){Value=address};

如果是Int、Float、Bigint,DateTime之类的参数,可以不用指定size属性。但如果size指定错误,则可能出现无法预知的错误。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值