日期:2014-05-18  浏览次数:20847 次

经验分享:实例化SqlParameter时,如果是字符型,一定要指定size属性
以前在实例化SqlParameter时,通常都是用下面的语句,没有设置size属性:
C# code
new SqlParameter("@name", SqlDbType.Varchar) { Value = name };
根据MSDN解释:如果未在 size 参数中显式设置 Size,则从 dbType 参数的值推断出该大小。
我一直以为是从SqlDbType类型推断,实际上是从参数的值推断,比如"ab",则size值为2,"abcd",则size值为4,且经测试发现,size的值不同时,会导致执行计划不会重用,下面的代码:
C# code
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如下:
SQL code
exec sp_executesql N'select top 1 * from tb where name = @o',N'@o nvarchar(2)',@o=N'ab'
如果把参数的值改成abcd,则通过SqlProfiler捕获到的sql如下:
SQL code
exec sp_executesql N'select top 1 * from tb where name = @o',N'@o nvarchar(4)',@o=N'abcd'
通过下面的sql,可以看出执行计划是否有重用:
SQL code
--先清空执行计划缓存
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属性,如:
C# code
new SqlParameter("@name", SqlDbType.Varchar, 4000) { Value = name };
如果是Int、Float、Bigint之类的参数,可以不用指定size属性


------解决方案--------------------
嗯,受教了,以前还真没注意过
------解决方案--------------------
不错,
------解决方案--------------------
int之类的可以不用指定,但float,decimal之类的需要指定
------解决方案--------------------
C# code
分享必属极品,感谢楼主分享。

------解决方案--------------------
学无止境
------解决方案--------------------
受教了
------解决方案--------------------
SQL code

SELECT
 est.text AS batchtext,
 SUBSTRING(est.text, (eqs.statement_start_offset/2)+1, 
 (CASE eqs.statement_end_offset WHEN -1 
 THEN DATALENGTH(est.text) 
 ELSE eqs.statement_end_offset END - 
 ((eqs.statement_start_offset/2) + 1))) AS querytext,
 eqs.creation_time, eqs.last_execution_time, eqs.execution_count, 
 eqs.total_worker_time, eqs.last_worker_time, 
 eqs.min_worker_time, eqs.max_worker_time, 
 eqs.total_physical_reads, eqs.last_physical_reads, 
 eqs.min_physical_reads, eqs.max_physical_reads, 
 eqs.total_elapsed_time, eqs.last_elapsed_time, 
 eqs.min_elapsed_time, eqs.max_elapsed_time, 
 eqs.total_logical_writes, eqs.last_logical_writes, 
 eqs.min_logical_writes, eqs.max_logical_writes,
 eqs.query_plan_hash 
FROM
 sys.dm_exec_query_stats AS eqs
 CROSS APPLY sys.dm_exec_sql_text(eqs.sql_handle) AS est
ORDER BY eqs.total_physical_reads DESC