您的位置:首页 > 数据库

总结:实例化SqlParameter时,如果是字符型,一定要指定size属性,还有制定具体的类型

2013-08-08 16:42 387 查看
源地址

在csdn上逛看到了这篇帖子,值得学习,就需要记录下来,转载给大家看!

 

以前在实例化SqlParameter时,通常都是用下面的语句,没有设置size属性:

new SqlParameter("@name", SqlDbType.Varchar) { Value = name };


根据MSDN解释:如果未在 size 参数中显式设置 Size,则从 dbType 参数的值推断出该大小。
我一直以为是从SqlDbType类型推断,实际上是从参数的值推断,比如"ab",则size值为2,"abcd",则size值为4,且经测试发现,size的值不同时,会导致执行计划不会重用,下面的代码:

string sql = "select top 1 * from tb where name = @o";
var para = new SqlParameter("@o", SqlDbType.VarChar) {Value = "ab"};
SqlHelper.ExecuteReader(ReadConnectionString, CommandType.Text, sql, para);


通过SqlProfiler捕获到的sql如下:

exec sp_executesql N'select top 1 * from tb where name = @o',N'@o nvarchar(2)',@o=N'ab'


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

exec sp_executesql N'select top 1 * from tb where name = @o',N'@o nvarchar(4)',@o=N'abcd'


通过下面的sql,可以看出执行计划是否有重用:

--先清空执行计划缓存
DBCC FREESYSTEMCACHE ('ALL')
DBCC FREEPROCCACHE
GO
SELECT * FROM sys.dm_exec_cached_plans WHERE cacheobjtype = 'Compiled Plan'
GO
exec sp_executesql N'select top 1 * from tb where name = @o',N'@o nvarchar(2)',@o=N'ab'
GO
SELECT * FROM sys.dm_exec_cached_plans WHERE cacheobjtype = 'Compiled Plan'
GO
exec sp_executesql N'select top 1 * from tb where name = @o',N'@o nvarchar(4)',@o=N'abcd'
GO
SELECT * FROM sys.dm_exec_cached_plans WHERE cacheobjtype = 'Compiled Plan'
GO


最后的说明,实例化SqlParameter时,如果是字符型,一定要指定size属性,如:

new SqlParameter("@name", SqlDbType.Varchar, 4000) { Value = name };


如果是Int、Float、Bigint之类的参数,可以不用指定size属性

另见13楼所说,不光要指明size的大小,还有制定具体的类型
比如name是varchar类型的,如果不指明具体类型,sql接受的是nvarchar类型的,也会出现问题

如下地址

如果数据库中的数据类型和程序指定的数据类型不一致,可能会导致很多转换,导致性能的底下!

MSDN中关于SqlParameter的备注

当在 value 参数中指定 Object 时,SqlDbType 将从
Object 的 .NET Framework 类型推断出。

请小心使用 SqlParameter 构造函数的这个重载来指定整数参数值。因为此重载接受 Object 类型的
value,所以当此值为零时,必须将整数值转换为 Object 类型,如下面的 C# 示例所示。

Parameter = new SqlParameter("@pname", Convert.ToInt32(0));


如果不执行该转换,则编译器将认为您尝试调用 SqlParameter(string、 SqlDbType)构造函数重载。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: