视图过滤问题(100分)

  • 主题发起人 主题发起人 唐朝笨蛋
  • 开始时间 开始时间

唐朝笨蛋

Unregistered / Unconfirmed
GUEST, unregistred user!
1,一个表tmptable<br>&nbsp;id &nbsp; tmpdate<br>&nbsp;1 &nbsp; &nbsp;2008-1-1<br>&nbsp;2 &nbsp; &nbsp;2009-12-25<br>&nbsp;3 &nbsp; &nbsp;大富翁<br><br>2,通过tmptable建了视图<br>CREATE VIEW dbo.VIEW1<br>AS<br>SELECT *<br>FROM tmptable<br>WHERE (isdate(tmpdate) = 1)<br><br>&nbsp;表内容显示<br>&nbsp;id &nbsp; tmpdate<br>&nbsp;1 &nbsp; &nbsp;2008-1-1<br>&nbsp;2 &nbsp; &nbsp;2009-12-25<br>3,对表操作<br>SELECT *<br>FROM VIEW1<br>WHERE (DATEPART(mm, tmpdate) = 1)<br><br>出错,提示字符串转为datetime类型时发生语法错误<br><br>结论:也就是说第2步的isdate过滤对第3步的操作并没有效果,datepart时,仍旧把id为3的数据进行操作,于是报错<br><br>问题:为什么会这样,如何避免
 
另外说下,如果第3步是<br>SELECT *,DATEPART(mm, tmpdate) as mm<br>FROM VIEW1<br><br>则又不会报错……
 
呵呵,这说明数据库引擎的条件归并机制将你在最后写的Where条件归并到了VIEW1的内部<br>去,导致DATEPART函数和isdate函数同时参与了数据的过滤(这个归并机制在绝大多数情况<br>下都能非常有效的提高针对视图的查询效率,所以不可能关闭或绕过)。<br>&nbsp; 将DATEPART放在Select中以后,它就只有机会对经过了isdate函数过滤之后的数据执行运<br>算,自然不会出现任何问题。
 
那该如何解决呢?<br>建临时表 把视图数据写入后再操作?<br>但这样一来 数据量多的情况下 效率就低了
 
试试这个吧:<br><br>Select id, tmpdate<br>From<br>(<br>&nbsp; SELECT *,DATEPART(mm, tmpdate) as mm<br>&nbsp; FROM VIEW1<br>)<br>Where mm = 1<br><br>[:)]
 
……涛声依旧
 
我自己顶顶吧……
 
SQL Server似乎智能过头了... 看来,似乎只有用CASE语句才能避免多余的DATEPART运算了:<br><br>SELECT *<br>FROM VIEW1<br>WHERE (CASE WHEN isdate(tmpdate) = 1 THEN DATEPART(mm, tmpdate) ELSE 0 END) = 1
 
creation-zy高手
 
的確高手,這樣的表達式還沒想到,呵呵
 
creation-zy 谢谢 <br><br>另外两位朋友帮顶,少给点,不要介意。。。
 

Similar threads

后退
顶部