问题描述:在从视图中查询数据时,假如把convert放在WHERE语句中,SQL SERVER引擎仍然会去扫描CONVERT中的字段在视图所引用的表中所有行数,假如该字段存在不能被CONVERT的值,比如:123A,不能被CONVERT成DECIMAL类型,即便WHERE语句中的其他条件会过滤该错误数据,又或者视图并没有引用该错误数据,但由于SQL SERVER引擎会扫描所有行数,还是会遇到以下错误,在SELECT语句中的CONVERT则会根据WHERE中或者视图里面已经过滤后的数据进行转换,则不会遇到下面错误。
环境: SQLSERVER 2008
错误情况:can not convert varchar to numeric
SQL语句:
SELECT
CONVERT(DECIMAL(18, 4), column_nm1)
FROM
view_nm1
WHERE
DataLineNumber=2 AND
CONVERT(DECIMAL(18, 4), column_nm1)>1
注明:view_nm1中只引用了表table_nm1一条数据,其中字段column_nm1的值为2.89
疑问:
1. 按道理讲不该报错的,因为视图中只有一条正确的数据;
2. 如果把where条件里的CONVERT语句删除,只保留SELECT里面的CONVERT语句,则不会报错。
解答过程:
1. 将上述SQL语句中的视图名字替换为表名字:FROM table_nm1,SQL执行正确;
2. 删除表table_nm1中所有数据只剩该视图view_nm1中引用的一条数据,上述SQL语句执行正确(FROM view_nm1);
解决方法:
删除该视图view_nm1所引用表中该字段column_nm1中的所有不能转换成decimal的数据(尽管该视图并没有引用到,但还是会影响查询视图时WHERE条件中的convert),该SQL执行成功。
结论:视图所引用表中的不能被正确CONVERT的脏数据,会在查询视图的WHERE条件中引起报错,尽管视图并没有引用该数据或者在WHERE条件中被过滤掉,也许是因为SQL SERVER引擎会在查询视图的时候强制扫描所引用表的所有行数据。
在SQL SERVER查询时,将CONVERT函数用于WHERE条件可能导致错误,即使视图中没有错误数据。当试图将VARCHAR转换为DECIMAL且数据包含不可转换的值时,会出现错误。即使WHERE子句有其他过滤条件,SQL SERVER仍会扫描所有行。解决方法是删除引用表中不能转换的数据。将CONVERT仅放在SELECT语句中则不会引发此问题。

233

被折叠的 条评论
为什么被折叠?



