﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>博客园-Wind-Snail</title><link>http://www.cnblogs.com/Wind-Snail/</link><description /><language>zh-cn</language><lastBuildDate>Sun, 23 Nov 2008 08:45:50 GMT</lastBuildDate><pubDate>Sun, 23 Nov 2008 08:45:50 GMT</pubDate><ttl>60</ttl><item><title>JavaScript去除空格的三种方法 (trim)</title><link>http://www.cnblogs.com/Wind-Snail/archive/2008/11/12/1332099.html</link><dc:creator>Wind Snail</dc:creator><author>Wind Snail</author><pubDate>Wed, 12 Nov 2008 07:37:00 GMT</pubDate><guid>http://www.cnblogs.com/Wind-Snail/archive/2008/11/12/1332099.html</guid><wfw:comment>http://www.cnblogs.com/Wind-Snail/comments/1332099.html</wfw:comment><comments>http://www.cnblogs.com/Wind-Snail/archive/2008/11/12/1332099.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnblogs.com/Wind-Snail/comments/commentRss/1332099.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/Wind-Snail/services/trackbacks/1332099.html</trackback:ping><description><![CDATA[摘要: 方法一:个人认为最好的方法.采用的是正则表达式,这是最核心的原理.其次.这个方法使用了JavaScript 的prototype 属性其实你不使用这个属性一样可以用函数实现.但这样做后用起来比较方便.下面就来看看这个属性是怎么来用的.返回对象类型原型的引用。objectName.prototypeobjectName 参数是对象的名称。说明用 prototype 属性提供对象的类的一组基本功能。对&nbsp;&nbsp;<a href='http://www.cnblogs.com/Wind-Snail/archive/2008/11/12/1332099.html'>阅读全文</a><img src ="http://www.cnblogs.com/Wind-Snail/aggbug/1332099.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/43630/" target="_blank">[新闻]Silverlight 2 SDK中文版发布</a><br/><a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻频道</a>&nbsp;<a href="http://space.cnblogs.com/group.htm" target="_blank">小组</a>&nbsp;<a href="http://space.cnblogs.com/q" target="_blank">博问</a>&nbsp;<a href="http://wz.cnblogs.com/" target="_blank">网摘</a>&nbsp;<a href="http://space.cnblogs.com/ing" target="_blank">闪存</a>]]></description></item><item><title>Redirecting to custom 401 page when "Access denied" occures within an ASP.NET application with Windows authentication</title><link>http://www.cnblogs.com/Wind-Snail/archive/2008/11/12/1332097.html</link><dc:creator>Wind Snail</dc:creator><author>Wind Snail</author><pubDate>Wed, 12 Nov 2008 07:35:00 GMT</pubDate><guid>http://www.cnblogs.com/Wind-Snail/archive/2008/11/12/1332097.html</guid><wfw:comment>http://www.cnblogs.com/Wind-Snail/comments/1332097.html</wfw:comment><comments>http://www.cnblogs.com/Wind-Snail/archive/2008/11/12/1332097.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnblogs.com/Wind-Snail/comments/commentRss/1332097.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/Wind-Snail/services/trackbacks/1332097.html</trackback:ping><description><![CDATA[<p>If you have an ASP.NET application with authentication mode set to Windows:</p>
<pre lang="xml" id="pre0" style="margin-top: 0px"> <span class="code-keyword">&lt;</span><span class="code-leadattribute">authentication</span> <span class="code-attribute">mode</span><span class="code-keyword">="</span><span class="code-keyword">Windows"</span><span class="code-keyword">/</span><span class="code-keyword">&gt;</span>
<span class="code-keyword">&lt;</span><span class="code-leadattribute">authorization</span><span class="code-keyword">&gt;</span>
<span class="code-keyword">&lt;</span><span class="code-leadattribute">deny</span> <span class="code-attribute">users</span><span class="code-keyword">="</span><span class="code-keyword">?"</span> <span class="code-keyword">/</span><span class="code-keyword">&gt;</span>
<span class="code-keyword">&lt;</span><span class="code-keyword">/</span><span class="code-leadattribute">authorization</span><span class="code-keyword">&gt;</span></pre>
<p>Then all Windows users can access your pages but those without Windows login (from internet) will receive an ASP.NET "Access Denied 401" page. I have decided to replace this default message with some custom page. After couple of hours Googling, I found out that this is a very common problem and all the workarounds which seem to be reasonable does not work. Here are some of them:</p>
<ol>
    <li>Use a custom error page in <em>Web.config</em>:
    <pre lang="xml" id="pre1" style="margin-top: 0px"><span class="code-keyword">&lt;</span><span class="code-leadattribute">customErrors</span> <span class="code-attribute">defaultRedirect</span><span class="code-keyword">="</span><span class="code-keyword">ErrorPage.asp&amp;shy;x"</span> <span class="code-attribute">mode</span><span class="code-keyword">="</span><span class="code-keyword">On"</span><span class="code-keyword">&gt;</span>
    <span class="code-keyword">&lt;</span><span class="code-leadattribute">error</span> <span class="code-attribute">statusCode</span><span class="code-keyword">="</span><span class="code-keyword">401"</span> <span class="code-attribute">redirect</span><span class="code-keyword">="</span><span class="code-keyword">AccessDenied.aspx"</span> <span class="code-keyword">/</span><span class="code-keyword">&gt;</span>
    <span class="code-keyword">&lt;</span><span class="code-keyword">/</span><span class="code-leadattribute">customErrors</span><span class="code-keyword">&gt;</span></pre>
    <p>This works fine with <code>statusCode=<span class="code-string">"</span><span class="code-string">404"</span></code> but not with 401.</p>
    </li>
    <li>Try to catch an unauthorized request in one of the application events in <em>Global.asax.cs</em>:
    <pre lang="cs" id="pre2" style="margin-top: 0px"><span class="code-keyword">protected</span> <span class="code-keyword">void</span> Application_AuthenticateRequest(<span class="code-SDKkeyword">Object</span> sender,
    EventArgs e)
    {
    <span class="code-keyword">if</span> (!Request.IsAuthenticated) Response.Redirect(
    <span class="code-string">"</span><span class="code-string">AccessDenied.aspx"</span>);
    }</pre>
    <p>It is also useless, because even the browsers with valid credentials make two posts, one without credentials and having <code lang="cs">Request.IsAuthenticated=false</code> and the other one with credentials and having <code lang="cs">Request.IsAuthenticated=true</code>. Browsers without credentials make only one post. It means you are not able to determine if the first post having <code lang="cs">Request.IsAuthenticated=false</code> comes from an unauthorized browser or not.</p>
    </li>
</ol>
<h2>The problem</h2>
<p>Then I found an answer from a Guru at microsoft.public.dotnet.framework.aspnet.security newsgroup.</p>
<blockquote>
<p>That's correct. There's no way around that. The way wininet authentication works is that if the resource you are requesting does not allow anonymous access, a 401 is sent back to the browser. If the resource is using Windows Integrated authentication and the browser is configured to automatically send credentials, the token is sent back and the user is authenticated. In the case of Basic authentication, a login prompt is displayed and the user must log in.</p>
<p>If you intercept the 401 and redirect somewhere, you hijack the browser's ability to challenge. There is no way around that.</p>
<p>Jxx Cxxxxxx, MCSE, MCSD [MSFT], Developer Support, ASP.NET.</p>
</blockquote>
<h2>Resolution</h2>
<p>That was also the result of my research. The whole thing works like this:</p>
<ol>
    <li>The browser sends request without credentials to the server.</li>
    <li>Server rejects this request and answers with "401 Access Denied".</li>
    <li>Browser recognizes 401 and if it has appropriate credentials does not show this message. The second request with credentials will be posted. The requested page will be sent to the browser.</li>
    <li>If the browser has <strong>no credentials</strong> the second post will not take place. The received "401 Access Denied" will be shown. </li>
</ol>
<p>The workaround is to manipulate the content of "401 Access Denied" response. The browser uses the header of this response to determine 401 case. It means we can manipulate the HTML content without influencing the whole challenge. For instance we can add the following code in the <code>Application_EndRequest</code> event of <em>Global.asax.cs</em>.</p>
<pre lang="cs" id="pre3" style="margin-top: 0px">  <span class="code-keyword">protected</span> <span class="code-keyword">void</span> Application_EndRequest(<span class="code-SDKkeyword">Object</span> sender,
EventArgs e)
{
HttpContext context = HttpContext.Current;
<span class="code-keyword">if</span> (context.Response.Status.Substring(<span class="code-digit">0</span>,<span class="code-digit">3</span>).Equals(<span class="code-string">"</span><span class="code-string">401"</span>))
{
context.Response.ClearContent();
context.Response.Write(<span class="code-string">"</span><span class="code-string">&lt;script language="</span>javascript<span class="code-string">"</span><span class="code-string">&gt;"</span> +
<span class="code-string">"</span><span class="code-string">self.location='../login.aspx';&lt;/script&gt;"</span>);
}
}</pre>
<p>Now, the whole thing works like this:</p>
<ol>
    <li>The browser sends request without credentials to the server.</li>
    <li>Server rejects this request and answers with "401 Access Denied" Header + our JavaScript.</li>
    <li>Browser recognizes 401 and if it has appropriate credentials does not show this message. Our HTML will not be rendered and JavaScript will not be executed. The second request with credentials will be posted. The requested page will be sent to the browser.</li>
    <li>If the browser has <strong>no credentials</strong>, the second post will not take place. The received "401 Access Denied" will be shown. Our HTML will be rendered and JavaScript will be executed. The client side redirection will take place. The browser will show a custom 401 page. </li>
</ol>
<img src ="http://www.cnblogs.com/Wind-Snail/aggbug/1332097.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/43630/" target="_blank">[新闻]Silverlight 2 SDK中文版发布</a><br/><a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻频道</a>&nbsp;<a href="http://space.cnblogs.com/group.htm" target="_blank">小组</a>&nbsp;<a href="http://space.cnblogs.com/q" target="_blank">博问</a>&nbsp;<a href="http://wz.cnblogs.com/" target="_blank">网摘</a>&nbsp;<a href="http://space.cnblogs.com/ing" target="_blank">闪存</a>]]></description></item><item><title>新版.Net开发必备十大工具</title><link>http://www.cnblogs.com/Wind-Snail/articles/1247378.html</link><dc:creator>Wind Snail</dc:creator><author>Wind Snail</author><pubDate>Mon, 21 Jul 2008 01:52:00 GMT</pubDate><guid>http://www.cnblogs.com/Wind-Snail/articles/1247378.html</guid><wfw:comment>http://www.cnblogs.com/Wind-Snail/comments/1247378.html</wfw:comment><comments>http://www.cnblogs.com/Wind-Snail/articles/1247378.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cnblogs.com/Wind-Snail/comments/commentRss/1247378.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/Wind-Snail/services/trackbacks/1247378.html</trackback:ping><description><![CDATA[<p>几年前MSDN上的一篇文章《Ten Must-Have Tools Every Developer Should Download Now》中介绍了.NET开发中必备的十大工具，几年过去之后，.NET Framework发展到了3.5版本，这些工具中，有些已经转向商业化，有些因为推出了新的工具而已经停止了开发，有些则继续免费提供给开发者使用。 <br />
<br />
&nbsp;&nbsp; 笔者对.NET开发中必备的十大工具重新做了整理，推出新版.NET开发必备十大工具。本文只是简单的对其进行介绍，更加详细的用法我将会陆续进行讲解。 <br />
<br />
<strong>Snippet Compiler</strong> <br />
<br />
&nbsp;&nbsp; Snippet Compiler是一个基于 Windows 的小型应用程序，你可以通过它来编写、编译和运行代码。如果你具有较小的代码段，并且你不想创建完整的 Visual Studio .NET 项目（以及该项目附带的所有文件），则该工具会很有用。现在Snippet Compiler已经支持.NET Framework 3.5，最新版本为Snippet Compiler Live 2008 Ultimate Edition for Developers (Alpha)，如下图所示： <br />
<br />
<img height="465" alt="" src="http://image.it168.com/cms/2008-6-19/Image/2008619214523.JPG" width="475" /><br />
<br />
&nbsp;&nbsp; 官方主页：<a href="http://www.sliver.com/dotnet/SnippetCompiler/">http://www.sliver.com/dotnet/SnippetCompiler/</a> <br />
<br />
<strong>Microsoft Source Analysis for C# <br />
<br />
</strong>&nbsp;&nbsp; Microsoft Source Analysis for C#是一款C#（不支持VB.NET）代码规范检查工具，前身是微软内部代码规范检查和代码格式强制工具StyleCop，目的是帮助项目团队执行一系列常用的源代码格式规范，它会根据预定义的C#代码格式的最佳实践进行检查，与FxCop不同的是它直接对源代码进行检查，且并不提供灵活的规则设置，强制开发者使用相同的习惯进行C#代码的编写。如下图所示： <br />
<br />
<img height="373" alt="" src="http://image.it168.com/cms/2008-6-19/Image/2008619224412.JPG" width="488" /><br />
</p>
<p><strong><br />
GhostDoc <br />
<br />
</strong>&nbsp;&nbsp; GhostDoc是Visual Studio的一个免费插件，可以帮助开发者生成比较完整规范的XML格式代码注释，如果你的代码遵循微软类库开发人员设计规范 ，由它自动产生的注释就已经完全可以很好地表达开发者创建的方法或者属性的意图，无需手工再进行修改。有了这些标准的XML注释，我们可以使用微软的文档工具Sandcastle生成专业级别的帮助文档。如我们有这样一段代码： <br />
</p>
<div style="scrollbar-highlight-color: buttonhighlight; overflow: auto; width: 500px">
<pre style="border-right: black 1px solid; padding-right: 4px; border-top: black 1px solid; padding-left: 4px; padding-bottom: 4px; border-left: black 1px solid; padding-top: 4px; border-bottom: black 1px solid; background-color: #ededed">public bool Add(string item) <br />
{ <br />
//...... <br />
} <br />
<br />
public void AppendHtmlText(IHtmlProvider htmlProvider) <br />
{ <br />
//...... <br />
} <br />
<div><!-- Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/
--></div>
</pre>
</div>
<p>&nbsp;&nbsp; 使用GhostDoc生成的注释如下：<br />
</p>
<div style="scrollbar-highlight-color: buttonhighlight; overflow: auto; width: 500px">
<pre style="border-right: black 1px solid; padding-right: 4px; border-top: black 1px solid; padding-left: 4px; padding-bottom: 4px; border-left: black 1px solid; padding-top: 4px; border-bottom: black 1px solid; background-color: #ededed">/// &lt;summary&gt; <br />
/// Adds the specified item. <br />
/// &lt;/summary&gt; <br />
/// &lt;param name="item"&gt;The item.&lt;/param&gt; <br />
/// &lt;returns&gt;&lt;/returns&gt; <br />
public bool Add(string item) <br />
{ <br />
//...... <br />
} <br />
<br />
/// &lt;summary&gt; <br />
/// Appends the HTML text. <br />
/// &lt;/summary&gt; <br />
/// &lt;param name="htmlProvider"&gt;The HTML provider.&lt;/param&gt; <br />
public void AppendHtmlText(IHtmlProvider htmlProvider) <br />
{ <br />
//...... <br />
} <br />
<div><!-- Code highlighting produced by Actipro CodeHighlighter (freeware)
http://www.CodeHighlighter.com/
--></div>
</pre>
</div>
<p>&nbsp;&nbsp; 官方主页：<a href="http://www.roland-weigelt.de/ghostdoc/">http://www.roland-weigelt.de/ghostdoc/</a> <br />
<br />
<strong>Sandcastle</strong> <br />
<br />
&nbsp;&nbsp; Sandcastle是微软发布的一个帮助文档生成工具，它通过反射程序集中的源代码和添加代码到中的XML注释来创建专业级别的帮助文档。Sandcastle于2006年推出，它的面世也使得曾经列入.NET开发必备十大工具之一的文档生成工具NDoc的作者Kevin Downs在2006年7月宣告不再投入NDoc Open Source Project的开发。生成的文档效果如下图所示：<br />
<br />
<img height="311" alt="" src="http://image.it168.com/cms/2008-6-19/Image/2008619224912.JPG" width="459" /><br />
<br />
Nunit <br />
<br />
&nbsp;&nbsp; NUnit 是为 .NET 框架生成的开放源代码单元测试框架。NUnit 使你可以用你喜欢的语言编写测试，从而测试应用程序的特定功能。当你首次编写代码时，单元测试是一种测试代码功能的很好方法，它还提供了一种对应用程序进行回归测试的方法。NUnit 应用程序提供了一个用于编写单元测试的框架，以及一个运行这些测试和查看结果的图形界面。 <br />
官方主页：<a href="http://www.nunit.org/">http://www.nunit.org/</a> <br />
<br />
<strong>MyGeneration <br />
<br />
</strong>&nbsp;&nbsp; 作为.NET开发人员，手边有一款代码生成工具必不可少。旧版.NET开发必备十大工具中，作者曾经推荐了非常著名的CodeSmith，不幸的是现在CodeSmith已经商业化，需要花钱购买；幸运的是我们又有一款免费并开源的代码生成工具选择MyGeneration，它的功能丝毫不亚于CodeSmith，完全基于模板引擎进行代码的生成，如下图所示： <br />
<br />
<img height="339" alt="" src="http://image.it168.com/cms/2008-6-19/Image/2008619225610.JPG" width="441" /><br />
<br />
&nbsp;&nbsp; 官方主页：<a href="http://sourceforge.net/projects/mygeneration">http://sourceforge.net/projects/mygeneration</a> <br />
<br />
<strong>Reflector for .NET <br />
<br />
</strong>&nbsp;&nbsp; 相信大名鼎鼎的Reflector for .NET大家都已经用过了，几年前它已经位于.NET开发必备十大工具榜，现在自然也不能例外。它是一个类浏览器和反编译器，可以分析程序集并向你展示它的所有秘密。使用Reflector for .NET可以浏览程序集的类和方法，可以分析由这些类和方法生成的 Microsoft 中间语言 (MSIL)，并且可以反编译这些类和方法并查看 C# 或 Visual Basic.NET 中的等价类和方法。经过多年的发展，Reflector for .NET已经发展到了5.1版本，并且提供了相当丰富的插件，利用这些插件我们可以浏览Silverlight程序结构、浏览WPF资源文件、与TestDriven.net集成等。如下图所示： <br />
<br />
<img height="339" alt="" src="http://image.it168.com/cms/2008-6-19/Image/2008619225740.JPG" width="460" /> </p>
<div id="ParagraphCount" style="display: none">&nbsp;</div>
<div style="display: none">The Regulator <br />
<br />
&nbsp;&nbsp; The Regulator能够使生成和测试正则表达式变得很容易，它允许你输入一个正则表达式以及一些针对其运行该表达式的输入。这样，在应用程序中实现该正则表达式之前，你便可以了解它将产生什么效果以及它将返回哪些种类的匹配项。另外它还提供了正则表达式库管理功能，在线更新正则表达式库，可以在RegexLib.com上搜索需要的正则表达式，如下图所示：<br />
<br />
<img height="328" alt="" src="http://image.it168.com/cms/2008-6-19/Image/200861923023.JPG" width="450" /><br />
<br />
官方主页：<a href="http://sourceforge.net/projects/regulator/">http://sourceforge.net/projects/regulator/</a> <br />
<br />
<strong>LINQPad</strong> <br />
<br />
&nbsp;&nbsp;&nbsp; 随着在.NET Framework 3.5中对于LINQ的支持，越来越多的开发者在开发中使用了LINQ to SQL，但是编写LINQ to SQL查询似乎又成了一件很麻烦的事情，好在我们还有LINQPad这个工具，用来编写LINQ查询，不仅仅是LINQ to SQL，同时它也支持LINQ to XML、LINQ to Objects，另外LINQPad是完全免费的且无需安装，只要下载它的可执行文件就可以了。官方主页：<a href="http://www.linqpad.net/">http://www.linqpad.net/</a> <br />
<br />
<strong>NAnt <br />
<br />
</strong>&nbsp;&nbsp; NAnt 是一个基于 .NET 的生成工具，与当前版本的 Visual Studio .NET 不同，它使得为你的项目创建生成过程变得非常容易。当你拥有大量从事单个项目的开发人员时，你不能依赖于从单个用户的座位进行生成。你也不希望必须定期手动生成该项目。你更愿意创建每天晚上运行的自动生成过程。NAnt 使你可以生成解决方案、复制文件、运行 NUnit 测试、发送电子邮件，等等。遗憾的是，NAnt 缺少漂亮的图形界面，但它的确具有可以指定应该在生成过程中完成哪些任务的控制台应用程序和 XML 文件。目前NAnt已经支持.NET Framework 3.5，它的最新版本是0.86 Beta 1。官方主页：http://nant.sourceforge.net/&nbsp;<br />
<br />
<strong>总结</strong> <br />
<br />
&nbsp;&nbsp; 以上工具笔者在原有的.NET开发必备十大工具基础之上，加以整理，添加了一些新的优秀的工具，也许有朋友会说，还有很多比这些工具更优秀的工具，没错，是有这样的工具，但是笔者要说的是，上述十个工具，不仅考虑它的实用性，有一点更为重要的是，它们都是免费的，而且有很多是开源的！ <br />
<br />
&nbsp;&nbsp; 为了便于大家对比，此处列出旧版.NET开发必备十大工具： <br />
&nbsp;&nbsp; 代码段编译工具：Snippet Compiler <br />
&nbsp;&nbsp; 正则表达式工具：Regulator <br />
&nbsp;&nbsp; 代码生成工具：CodeSmith（已经商业化） <br />
&nbsp;&nbsp; 编写单元测试工具：NUnit <br />
&nbsp;&nbsp; 监视代码工具：FxCop <br />
&nbsp;&nbsp; 程序集分析检查工具：Reflector <br />
&nbsp;&nbsp; 创建代码文档工具：NDoc（已经停止开发） <br />
&nbsp;&nbsp; 生成解决方案工具：NAnt <br />
&nbsp;&nbsp; ASPNET版本转换器 <br />
&nbsp;&nbsp; VSNET项目转换器 <br />
<div id="ParagraphCount" style="display: none">1</div>
</div>
<p><br />
&nbsp;</p>
 <img src ="http://www.cnblogs.com/Wind-Snail/aggbug/1247378.html?type=2" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/43629/" target="_blank">[新闻][译稿]微软将 jQuery IntelliSense整合到Visual Studio</a><br/><a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻频道</a>&nbsp;<a href="http://space.cnblogs.com/group.htm" target="_blank">小组</a>&nbsp;<a href="http://space.cnblogs.com/q" target="_blank">博问</a>&nbsp;<a href="http://wz.cnblogs.com/" target="_blank">网摘</a>&nbsp;<a href="http://space.cnblogs.com/ing" target="_blank">闪存</a>]]></description></item><item><title>周鸿祎：太牛的人都不会成功</title><link>http://www.cnblogs.com/Wind-Snail/archive/2008/04/21/1163702.html</link><dc:creator>Wind Snail</dc:creator><author>Wind Snail</author><pubDate>Mon, 21 Apr 2008 04:48:00 GMT</pubDate><guid>http://www.cnblogs.com/Wind-Snail/archive/2008/04/21/1163702.html</guid><wfw:comment>http://www.cnblogs.com/Wind-Snail/comments/1163702.html</wfw:comment><comments>http://www.cnblogs.com/Wind-Snail/archive/2008/04/21/1163702.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnblogs.com/Wind-Snail/comments/commentRss/1163702.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/Wind-Snail/services/trackbacks/1163702.html</trackback:ping><description><![CDATA[太牛的人都不会成功。&#8221; 周鸿祎说，创业者能否反思和学习，从错误中吸取教训，才是成功的关键。
<div></div>
<div id="endText">
<center><a title="点击查看原图" href="http://images.itdb.cn/News/2008/04/21/1AE0816E5E3.jpg" target="_blank"></a><br />
</center>
<p style="text-indent: 2em">昨天对重庆IT界来说是个喜庆的日子，丁磊、熊晓鸽、周鸿祎等国内业界精英齐聚重庆，出席第三届电脑报中国数字英雄会。</p>
<p style="text-indent: 2em">此次盛会由第三届数字英雄榜颁奖典礼、电脑报第三届DIY产业发展高峰论坛、电脑报首届天使投资论坛等内容组成。会议邀请了网易董事长丁磊、IDG（美国国际数据集团）副总裁兼亚洲区总裁熊晓鸽、联想集团高级副总裁陈绍鹏等业内人士，一起探讨中国IT产业发展得失，展望中国IT产业辉煌前景。</p>
<p style="text-indent: 2em">今天，会议将发布《2007年度中国IT品牌市场占有率调查报告》、《2008年度中国IT品牌消费趋向调查报告》、《2008年度中国IT品牌价格竞争力调查报告》、《2007-2008年度中国网络与软件市场调查报告》。记者 万里</p>
<p style="text-indent: 2em"><strong>奇虎董事长、天使投资人周鸿祎——</strong></p>
<p style="text-indent: 2em"><strong>谁说没钱就不能创业</strong></p>
<p style="text-indent: 2em">&#8220;现在IT界既不缺钱，又不缺创意和商业模式，但是找到一个好的创业团队非常难。&#8221;昨天，奇虎董事长、天使投资人周鸿祎在论坛上介绍风险投资选择合作伙伴的标准时说，&#8220;创业者仅有资源和点子是不够的。&#8221;</p>
<p style="text-indent: 2em"><strong>做出东西再找风投</strong></p>
<p style="text-indent: 2em">&#8220;太牛的人都不会成功。&#8221; 周鸿祎说，创业者能否反思和学习，从错误中吸取教训，才是成功的关键。周鸿祎认为，一个好的创业者需要在自己不熟悉的领域里学会寻找更适合的人来帮助自己，而好的风投就有这个能力。&#8220;而创业者想光凭一个点子和技术就找风投，那是不会成功的，只有把东西做出来才有价值，才能让风投看到你团队的执行力。&#8221;</p>
<p style="text-indent: 2em">周鸿祎说，老是有人向他感叹&#8220;没有钱就无法创业&#8221;。但他认为，创业者一开始如果很有钱，往往是把大部分资金投入到推广中去了，反而不能把产品做好。而没有钱，创业者才会认真琢磨用户体验，把产品做好。&#8220;穷有穷过法，富有富过法，没有钱就不能创业的想法是错误的。&#8221;</p>
<p style="text-indent: 2em"><strong>教写商业计划书</strong></p>
<p style="text-indent: 2em">如何写一份好的商业计划书，让目前很多创业者费尽心思。周鸿祎在论坛现场向创业者传授写作方法：&#8220;商业计划书不要长篇大论，不要讴歌自己。用PPT（幻灯片）写最好，就用大白话，越朴实越好。&#8221;</p>
<p style="text-indent: 2em">他说，商业计划书最好就是十页篇幅：第一页是市场介绍；第二页分析市场问题；第三页写解决问题的方式；第四页调研市场；第五页分析竞争对手；第六页介绍核心竞争力；第七页写盈利模式；第八页写近期目标；第九页写资金预算；第十页就介绍团队。</p>
</div>
<img src ="http://www.cnblogs.com/Wind-Snail/aggbug/1163702.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/43628/" target="_blank">[新闻]微软：不裁员也不削减研发开支</a><br/><a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻频道</a>&nbsp;<a href="http://space.cnblogs.com/group.htm" target="_blank">小组</a>&nbsp;<a href="http://space.cnblogs.com/q" target="_blank">博问</a>&nbsp;<a href="http://wz.cnblogs.com/" target="_blank">网摘</a>&nbsp;<a href="http://space.cnblogs.com/ing" target="_blank">闪存</a>]]></description></item><item><title>2个关于移民的新路子</title><link>http://www.cnblogs.com/Wind-Snail/archive/2008/03/18/1110960.html</link><dc:creator>Wind Snail</dc:creator><author>Wind Snail</author><pubDate>Tue, 18 Mar 2008 01:38:00 GMT</pubDate><guid>http://www.cnblogs.com/Wind-Snail/archive/2008/03/18/1110960.html</guid><wfw:comment>http://www.cnblogs.com/Wind-Snail/comments/1110960.html</wfw:comment><comments>http://www.cnblogs.com/Wind-Snail/archive/2008/03/18/1110960.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnblogs.com/Wind-Snail/comments/commentRss/1110960.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/Wind-Snail/services/trackbacks/1110960.html</trackback:ping><description><![CDATA[英国高技术移民HSMP <br />
新加坡：EPEC和In-principle Permanent Residence PR <br />
<br />
这2者的好处都是无需中介（自己办，价格低廉），周期很短。和加拿大，澳大利亚那种龟速比起来，简直就是火箭）我很多朋友申请加拿大，等到批下来都快2年了，也不想去了。有人如果想在半年内出发的可以考虑这2个（加拿大，澳大利亚作为华人众多的福利国家还是有独特的好处的，但是等待的时间太长，有时还要面世，中介还要吃钱） <br />
<br />
英国高技术移民HSMP的申请周期最长不超过3个月，90%的申请在一个月内就可以批准。 <br />
新加坡那2个准证的好处是无需英语考试，而且绿卡快，入籍也快。 <br />
<br />
其实都不难，关键是敢不敢走出去。也许行动起来，2个月后就在伦敦开始求职了:) <br />
<br />
至于工作，有那么难吗？ 
<img src ="http://www.cnblogs.com/Wind-Snail/aggbug/1110960.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/43625/" target="_blank">[新闻]2008年11月22日科技博客精选</a><br/><a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻频道</a>&nbsp;<a href="http://space.cnblogs.com/group.htm" target="_blank">小组</a>&nbsp;<a href="http://space.cnblogs.com/q" target="_blank">博问</a>&nbsp;<a href="http://wz.cnblogs.com/" target="_blank">网摘</a>&nbsp;<a href="http://space.cnblogs.com/ing" target="_blank">闪存</a>]]></description></item><item><title>Five Ways to Rev up Your SQL Performance </title><link>http://www.cnblogs.com/Wind-Snail/archive/2008/03/18/1110938.html</link><dc:creator>Wind Snail</dc:creator><author>Wind Snail</author><pubDate>Tue, 18 Mar 2008 01:30:00 GMT</pubDate><guid>http://www.cnblogs.com/Wind-Snail/archive/2008/03/18/1110938.html</guid><wfw:comment>http://www.cnblogs.com/Wind-Snail/comments/1110938.html</wfw:comment><comments>http://www.cnblogs.com/Wind-Snail/archive/2008/03/18/1110938.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnblogs.com/Wind-Snail/comments/commentRss/1110938.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/Wind-Snail/services/trackbacks/1110938.html</trackback:ping><description><![CDATA[sometimes all it takes is a little tweak here or there to make your application run much faster. Ah, but the key is figuring out how to tweak it! Sooner or later you'll face a situation where a SQL query in your application isn't responding the way you intended. Either it doesn't return the data you want or it takes entirely too long to be reasonable. If it slows down a report or your enterprise application, users won't be pleased if they have to wait inordinate amounts of time. And just like your parents didn't want to hear why you were coming in past curfew, users don't want to hear why your query is taking so long. ("Sorry, Mom, I used too many LEFT JOINs.") Users want applications to respond quickly and their reports to return analytical data in a flash. I myself get impatient when I surf the Web and a page takes more than ten seconds to load (OK, more like five seconds).<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;To resolve these issues, it is important to get to the root of the problem. So where do you start? The root cause is usually in the database design and the queries that access it. In this month's column I'll demonstrate four techniques that can be used to either improve your SQL Server&#8482;-based application's performance or improve its scalability. I'll examine the use of LEFT JOINs, CROSS JOINs, and retrieving an IDENTITY value. Keep in mind that there is no magic solution. Tuning your database and its queries takes time, analysis, and a lot of testing. While the techniques here are proven, some may work better than others in your application.<br />
<h3>Returning an IDENTITY From an INSERT</h3>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;I figured I would start with something I get a lot of questions about: how to retrieve an IDENTITY value after performing a SQL INSERT. Often, the problem is not how to write the query to retrieve the value, but rather where and when to do it. In SQL Server, the statement to retrieve the IDENTITY value created by the most recent SQL statement run on the active database connection is as follows: <br />
<pre><code>SELECT @@IDENTITY
</code></pre>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;While this SQL is far from daunting, it is important to keep in mind that if the most recent SQL statement was not an INSERT or you run this SQL against a different connection than the INSERT SQL, you will not get back the value you expect. You must run this code to retrieve the IDENTITY immediately following the INSERT SQL and on the same connection, like this:<br />
<pre><code>INSERT INTO Products (ProductName) VALUES ('Chalk')
SELECT @@IDENTITY
</code></pre>
Running these queries on a single connection against the Northwind database will return to you the IDENTITY value for the new product called Chalk. So in your Visual Basic&#174; application using ADO, you could run the following statement:<br />
<pre><code>Set oRs = oCn.Execute("SET NOCOUNT ON;INSERT INTO Products _
(ProductName) VALUES ('ChalkSELECT @@IDENTITY")
lProductID = oRs(0)
</code></pre>
This code tells SQL Server not to return a row count for the query, then executes the INSERT statement and returns the IDENTITY value just created for the new row. The SET NOCOUNT ON statement means the Recordset that is returned has one row and one column that contains the new IDENTITY value. Without this statement, an empty Recordset is returned (because the INSERT statement returns no data) and then a second Recordset is returned, which contains the IDENTITY value. This can be confusing, especially since you never intended the INSERT to return a Recordset. This situation occurs because SQL Server sees the row count (that is, one row affected) and interprets it as representing a Recordset. So the true data is pushed back into a second Recordset. While you can get to this second Recordset using the NextRecordset method in ADO, it is much easier (and more efficient) if you can always count on the Recordset being the first and only one returned.<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;While this technique gets the job done, it does require extra code in the SQL statement. Another way of getting the same result is to use the SET NOCOUNT ON statement preceding the INSERT and to put the SELECT @@IDENTITY statement in a FOR INSERT trigger on the table, as shown in the following code snippet. This way, any INSERT statement into that table will automatically return the IDENTITY value.<br />
<pre><code>CREATE TRIGGER trProducts_Insert ON Products FOR INSERT AS
SELECT @@IDENTITY
GO
</code></pre>
The trigger only fires when an INSERT occurs on the Products table, so it always will return an IDENTITY after a successful INSERT. Using this technique, you can consistently retrieve IDENTITY values in the same manner across your application.<br />
<h3>Inline Views Versus Temp Tables</h3>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Queries sometimes need to join data to other data that may only be gathered by performing a GROUP BY and then a standard query. For example, if you want to return the information about the five most recently placed orders, you would first need to know which orders they are. This can be retrieved by using a SQL query that returns the orders' IDs. This data could be stored in a temporary table, a common technique, and then joined to the Product table to return the quantity of products sold on those orders:<br />
<pre><code>CREATE TABLE #Temp1 (OrderID INT NOT NULL, _
OrderDate DATETIME NOT NULL)
INSERT INTO #Temp1 (OrderID, OrderDate)
SELECT     TOP 5 o.OrderID, o.OrderDate
FROM Orders o ORDER BY o.OrderDate DESC
SELECT     p.ProductName, SUM(od.Quantity) AS ProductQuantity
FROM     #Temp1 t
INNER JOIN [Order Details] od ON t.OrderID = od.OrderID
INNER JOIN Products p ON od.ProductID = p.ProductID
GROUP BY p.ProductName
ORDER BY p.ProductName
DROP TABLE #Temp1
</code></pre>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;This batch of SQL creates a temporary table, inserts the data into it, joins other data to it, and drops the temporary table. This is a lot of I/O for this query, which could be rewritten to use an inline view instead of a temporary table. An inline view is simply a query that can be joined to in the FROM clause. So instead of spending a lot of I/O and disk access in tempdb on a temporary table, you could instead use an inline view to get the same result:<br />
<pre><code>SELECT p.ProductName,
SUM(od.Quantity) AS ProductQuantity
FROM     (
SELECT TOP 5 o.OrderID, o.OrderDate
FROM     Orders o
ORDER BY o.OrderDate DESC
) t
INNER JOIN [Order Details] od ON t.OrderID = od.OrderID
INNER JOIN Products p ON od.ProductID = p.ProductID
GROUP BY
p.ProductName
ORDER BY
p.ProductName
</code></pre>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;This query is not only more efficient than the previous one, it's shorter. Temporary tables consume a lot of resources. If you only need the data to join to other queries, you might want to try using an inline view to conserve resources.<br />
<h3>Avoid LEFT JOINs and NULLs</h3>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;There are, of course, times when you need to perform a LEFT JOIN and use NULL values. But they are not a solution for all occasions. Changing the way you structure your SQL queries can mean the difference between a report that takes minutes to run and one that takes only seconds. Sometimes you have to morph the data in a query to look the way your application wants it to look. While the TABLE datatype reduces resource gluttony, there are still plenty of areas in a query that can be optimized. One valuable, commonly used feature of SQL is the LEFT JOIN. It can be used to retrieve all of the rows from a first table and all matching rows from a second table, plus all rows from the second table that do not match the first one. For example, if you wanted to return every Customer and their orders, a LEFT JOIN would show the Customers who did and did not have orders.<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;This tool can be overused. LEFT JOINs are costly since they involve matching data against NULL (nonexistent) data. In some cases this is unavoidable, but the cost can be high. A LEFT JOIN is more costly than an INNER JOIN, so if you could rewrite a query so it doesn't use a LEFT JOIN, it could pay huge dividends (see the diagram in <strong>Figure&nbsp;1</strong>).<br />
<br />
<img height="160" alt="Figure 1 Query" src="http://msdn2.microsoft.com/zh-cn/magazine/Cc301622.data0207fig01(en-us,MSDN.10).gif" width="109" /><br />
<strong>Figure 1</strong> <strong>Query</strong><br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;One technique to speed up a query that uses a LEFT JOIN involves creating a TABLE datatype and inserting all of the rows from the first table (the one on the left-hand side of the LEFT JOIN), then updating the TABLE datatype with the values from the second table. This technique is a two-step process, but could save a lot of time compared to a standard LEFT JOIN. A good rule is to try out different techniques and time each of them until you get the best performing query for your application.<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;When you are testing your query's speed, it's important to run it several times and take an average. Your query (or stored procedure) could be stored in the procedure cache in SQL Server's memory and thus would appear to take longer the first time and shorter on all subsequent tries. In addition, other queries could be running against the same tables while your query runs. This could cause your query to stand in line while other queries lock and unlock tables. For example, if you are querying while someone is updating data in that table, your query may take longer to execute while the update commits.<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;One of the easiest ways to avoid slowdowns with LEFT JOINs is to design the database around them as much as possible. For example, let's assume that a product may or may not have a category. If the product table stores the ID of its category and there was no category for a particular product, you could store a NULL value in the field. Then you would have to perform a LEFT JOIN to get all of the products and their categories. You could create a category with the value of "No Category" and thus specify the foreign key relationship to disallow NULL values. By doing this, you can now use an INNER JOIN to retrieve all products and their categories. While this may seem like a workaround with extra data, this can be a valuable technique as it can eliminate costly LEFT JOINs in SQL batches. Using this concept across the board in a database can save you lots of processing time. Remember, even a few seconds means a lot to your users, and those seconds really add up when you have many users accessing an online database application.<br />
<h3>Use Cartesian Products Wisely</h3>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;For this tip, I will go against the grain and advocate the use of Cartesian products in certain situations. For some reason, Cartesian products (CROSS JOINS) got a bad rap and developers are often cautioned not to use them at all. In many cases, they are too costly to use effectively. But like any tool in SQL, they can be valuable if used properly. For example, if you want to run a query that will return data for every month, even on customers that had no orders that particular month, you could use a Cartesian product quite handily. The SQL in Figure 2 does just that.<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;While this may not seem like magic, consider that if you did a standard INNER JOIN from Customers to Orders, grouped by the month and summed the sales, you would only get the months where the customer had an order. Thus, you would not get back a 0 value for the months in which the customer didn't order any products. If you wanted to plot a graph per customer showing every month and its sales, you would want the graph to include 0 month sales to identify those months visually. If you use the SQL in Figure 2, the data skips over the months that had $0 in sales because there are no rows in the Orders table for nonsales (it is assumed that you do not store what did not occur).<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;The code in&nbsp;Figure 3&nbsp; is longer, but can achieve the same goal of getting all the sales data, even for months without sales. First, it grabs a list of all of the months in the past year and puts them in the first TABLE datatype table (@tblMonths). Next, the code gets a list of all customers' company names who had sales during that time period and puts them in another TABLE datatype table (@tblCus-tomers). These two tables store all of the basic data required to create the resultset except the actual sales numbers.<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;All of the months are listed in the first table (12 rows) and all of the customers who had sales in that time frame are listed in the second table (81 for me). Not every customer purchased a product in each of the past 12 months, so performing an INNER or LEFT JOIN won't return every customer for every month. These operations will only return the customers and the months when they did purchase something.<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;A Cartesian product can return all customers for all months. A Cartesian product basically multiplies the first table by the second table and results in a rowset that contains the number of rows in the first table times the number of rows in the second table. Thus, the Cartesian product returns 972 rows into the table @tblFinal. The last steps are to update the table @tblFinal with the monthly sales totals for each customer during the date range and to select the final rowset.<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Use CROSS JOINs with caution if you do not need a true Cartesian product because they can be very resource intensive. For example, if you do a CROSS JOIN on products and categories and then use a WHERE clause, DISTINCT or GROUP BY to filter out most of the rows, you could have gotten to the same result in a much more efficient manner by using an INNER JOIN. Cartesian products can be very useful when you need the data returned for all possibilities, as in the case when you want to load a graph with monthly sales dates. But you should not use them for other purposes as INNER JOINs are much more efficient in most scenarios.<br />
<h3>Odds and Ends</h3>
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Here are a few other common techniques that can help improve the efficiency of your SQL querying. Let's assume you are going to group all of your salespeople by region and sum their sales, but you only want salespeople who were marked active in your database. You could group the salespeople by region and use a HAVING clause to eliminate the salespersons who are not active, or you could do this in the WHERE clause. Doing this in the WHERE clause reduces the number of rows that need to be grouped, so it is more efficient than doing it in the HAVING clause. Filtering row-based criteria in the HAVING clause forces the query to group data that could have been eliminated in the WHERE clause.<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;Another efficiency trick is to use the DISTINCT keyword to find a distinct list of data rows instead of using the GROUP BY clause. In this case, the SQL using the DISTINCT keyword will be more efficient. Reserve use of the GROUP BY for occasions when you need to calculate an aggregate function (SUM, COUNT, MAX, and so on). Also, avoid using the DISTINCT keyword if your query will always return a unique row on its own. In that case, the DISTINCT keyword will only add overhead.<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;You've seen that numerous techniques can be employed to optimize queries and implement specific business rules; the trick is to try a few and compare their performance. Most important is to test, test, and test again. In future installments of this column, I'll continue to explore SQL Server concepts including database design, good indexing practices, and SQL Server security paradigms.<br />
<img src ="http://www.cnblogs.com/Wind-Snail/aggbug/1110938.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/43625/" target="_blank">[新闻]2008年11月22日科技博客精选</a><br/><a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻频道</a>&nbsp;<a href="http://space.cnblogs.com/group.htm" target="_blank">小组</a>&nbsp;<a href="http://space.cnblogs.com/q" target="_blank">博问</a>&nbsp;<a href="http://wz.cnblogs.com/" target="_blank">网摘</a>&nbsp;<a href="http://space.cnblogs.com/ing" target="_blank">闪存</a>]]></description></item><item><title>使用 PIVOT 和 UNPIVOT</title><link>http://www.cnblogs.com/Wind-Snail/archive/2008/03/18/1110928.html</link><dc:creator>Wind Snail</dc:creator><author>Wind Snail</author><pubDate>Tue, 18 Mar 2008 01:26:00 GMT</pubDate><guid>http://www.cnblogs.com/Wind-Snail/archive/2008/03/18/1110928.html</guid><wfw:comment>http://www.cnblogs.com/Wind-Snail/comments/1110928.html</wfw:comment><comments>http://www.cnblogs.com/Wind-Snail/archive/2008/03/18/1110928.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnblogs.com/Wind-Snail/comments/commentRss/1110928.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/Wind-Snail/services/trackbacks/1110928.html</trackback:ping><description><![CDATA[<p>可以使用 PIVOT 和 UNPIVOT 关系运算符将表值表达式更改为另一个表。PIVOT 通过将表达式某一列中的唯一值转换为输出中的多个列来旋转表值表达式，并在必要时对最终输出中所需的任何其余列值执行聚合。UNPIVOT 与 PIVOT 执行相反的操作，将表值表达式的列转换为列值。</p>
<div class="alert"><strong>注意</strong>：对升级到 Microsoft SQL Server 2005 的数据库使用 PIVOT 和 UNPIVOT 时，数据库的兼容级别必须设置为 90。
<p>PIVOT 提供的语法比一系列复杂的 SELECT...CASE 语句中所指定的语法更简单和更具可读性。<br />
以下是带批注的 PIVOT 语法。</p>
</div>
<p><tt>SELECT</tt> &lt;<em>non-pivoted column</em>&gt; <tt>,</tt></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;[<em>first pivoted column</em>] <tt>AS</tt> &lt;<em>column name</em>&gt; <tt>,</tt></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;[<em>second pivoted column</em>] AS &lt;<em>column name</em>&gt; <tt>,</tt></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<tt>...</tt></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;[<em>last pivoted column</em>] <tt>AS</tt> &lt;<em>column name</em>&gt;</p>
<p><tt>FROM</tt></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<tt>( </tt>&lt;<em>SELECT query that produces the data</em>&gt; <tt>)</tt> </p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<tt>AS</tt> &lt;<em>alias for the source query</em>&gt;</p>
<p><tt>PIVOT</tt></p>
<p><tt>(</tt></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<tt>&lt;aggregation function&gt;( </tt>&lt;<em>column being aggregated</em>&gt; <tt>)</tt></p>
<p><tt>FOR </tt></p>
<p>[&lt;<em>column that contains the values that will become column headers</em>&gt;] </p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<tt>IN</tt> <tt>(</tt> [<em>first pivoted column</em>] <tt>,</tt> [<em>second pivoted column</em>] <tt>,</tt></p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;<tt>...</tt> [<em>last pivoted column</em>] <tt>)</tt></p>
<p><tt>)</tt> <tt>AS</tt> &lt;<em>alias for the pivot table</em>&gt;</p>
<p>&lt;<em>optional ORDER BY clause</em>&gt;</p>
<p><tt>SELECT &lt;non-pivoted column&gt;,</tt></p>
<p><tt>&nbsp;&nbsp;&nbsp;&nbsp;[first pivoted column] AS &lt;column name&gt;,</tt></p>
<p><tt>&nbsp;&nbsp;&nbsp;&nbsp;[second pivoted column] AS &lt;column name&gt;,</tt></p>
<p><tt>&nbsp;&nbsp;&nbsp;&nbsp;...</tt></p>
<p><tt>&nbsp;&nbsp;&nbsp;&nbsp;[last pivoted column] AS &lt;column name&gt;</tt></p>
<p><tt>FROM</tt></p>
<p><tt>&nbsp;&nbsp;&nbsp;&nbsp;(&lt;SELECT query that produces the data&gt;) </tt></p>
<p>&nbsp;<tt>&nbsp;&nbsp;&nbsp;AS &lt;alias for the source query&gt;</tt></p>
<p><tt>PIVOT</tt></p>
<p><tt>(</tt></p>
<p><tt>&nbsp;&nbsp;&nbsp;&nbsp;&lt;aggregation function&gt;(&lt;column being aggregated&gt;)</tt></p>
<p><tt>FOR </tt></p>
<p><tt>[&lt;column that contains the values that will become column headers&gt;] </tt></p>
<p><tt>&nbsp;&nbsp;&nbsp;&nbsp;IN ( [first pivoted column], [second pivoted column],</tt></p>
<p><tt>&nbsp;&nbsp;&nbsp;&nbsp;... [last pivoted column])</tt></p>
<p><tt>) AS &lt;alias for the pivot table&gt;</tt></p>
<p><tt>&lt;optional ORDER BY clause&gt;</tt></p>
<div class="MTPS_CollapsibleRegion" id="ctl00_rs1_mainContentContainer_cpe46597">
<div class="CollapseRegionLink" id="ctl00_rs1_mainContentContainer_cpe46597_h">简单 PIVOT 示例 ,下面的代码示例生成一个两列四行的表。<br />
USE AdventureWorks ;<br />
GO<br />
SELECT DaysToManufacture, AVG(StandardCost) AS AverageCost <br />
FROM Production.Product<br />
GROUP BY DaysToManufacture<br />
</div>
<div class="MTPS_CollapsibleSection" id="ctl00_rs1_mainContentContainer_cpe46597_c" style="display: block; overflow: visible; width: auto; height: auto">
<div class="MTPS_CollapsibleSection" id="" style="border-right: medium none; border-top: medium none; display: block; border-left: medium none; border-bottom: medium none">
<p>下面是结果集：</p>
<p><tt>DaysToManufacture&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;AverageCost</tt></p>
<p><tt>0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;5.0885</tt></p>
<p><tt>1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;223.88</tt></p>
<p><tt>2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;359.1082</tt></p>
<p><tt>4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;949.4105</tt></p>
<p>没有定义 <tt>DaysToManufacture</tt> 为 3 的产品。</p>
<p>以下代码显示相同的结果，该结果经过透视以使 <tt>DaysToManufacture</tt> 值成为列标题。提供一个列表示三 <tt>[3]</tt> 天，即使结果为 <tt>NULL</tt>。</p>
<div class="code" id="ctl00_rs1_mainContentContainer_ctl08_other">
<div class="CodeSnippetTitleBar">
<div class="CodeDisplayLanguage"></div>
<div class="CopyCodeButton">-- Pivot table with one row and five columns<br />
SELECT 'AverageCost' AS Cost_Sorted_By_Production_Days, <br />
[0], [1], [2], [3], [4]<br />
FROM<br />
(SELECT DaysToManufacture, StandardCost <br />
&nbsp;&nbsp;&nbsp;&nbsp;FROM Production.Product) AS SourceTable<br />
PIVOT<br />
(<br />
AVG(StandardCost)<br />
FOR DaysToManufacture IN ([0], [1], [2], [3], [4])<br />
) AS PivotTable<br />
</div>
</div>
</div>
<p>下面是结果集：</p>
<p><tt>Cost_Sorted_By_Production_Days&nbsp;&nbsp;&nbsp;&nbsp;0&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</tt></p>
<p><tt>AverageCost&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;5.0885&nbsp;&nbsp;&nbsp;&nbsp;223.88&nbsp;&nbsp;&nbsp;&nbsp;359.1082&nbsp;&nbsp;&nbsp;&nbsp;NULL&nbsp;&nbsp;&nbsp;&nbsp;949.4105</tt></p>
</div>
</div>
</div>
<div class="MTPS_CollapsibleRegion" id="ctl00_rs1_mainContentContainer_cpe46598">
<div class="CollapseRegionLink" id="ctl00_rs1_mainContentContainer_cpe46598_h">复杂 PIVOT 示例 </div>
<div class="MTPS_CollapsibleSection" id="ctl00_rs1_mainContentContainer_cpe46598_c" style="display: block; overflow: visible; width: auto; height: auto">
<div class="MTPS_CollapsibleSection" id="" style="border-right: medium none; border-top: medium none; display: block; border-left: medium none; border-bottom: medium none">
<p>可能会用到 <tt>PIVOT</tt> 的常见情况是：需要生成交叉表格报表以汇总数据。例如，假设需要在 <tt>AdventureWorks</tt> 示例数据库中查询 <tt>PurchaseOrderHeader</tt> 表以确定由某些特定雇员所下的采购订单数。以下查询提供了此报表（按供应商排序）。</p>
<div class="code" id="ctl00_rs1_mainContentContainer_ctl16_other">
<div class="CodeSnippetTitleBar">
<div class="CodeDisplayLanguage"></div>
<div class="CopyCodeButton">USE AdventureWorks;<br />
GO<br />
SELECT VendorID, [164] AS Emp1, [198] AS Emp2, [223] AS Emp3, [231] AS Emp4, [233] AS Emp5<br />
FROM <br />
(SELECT PurchaseOrderID, EmployeeID, VendorID<br />
FROM Purchasing.PurchaseOrderHeader) p<br />
PIVOT<br />
(<br />
COUNT (PurchaseOrderID)<br />
FOR EmployeeID IN<br />
( [164], [198], [223], [231], [233] )<br />
) AS pvt<br />
ORDER BY VendorID</div>
</div>
</div>
<p>以下为部分结果集。</p>
<div class="code" id="ctl00_rs1_mainContentContainer_ctl17_other">
<div class="CodeSnippetTitleBar">
<div class="CodeDisplayLanguage"></div>
<div class="CopyCodeButton">VendorID&nbsp;&nbsp;&nbsp; Emp1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Emp2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Emp3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Emp4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Emp5<br />
1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 5&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4<br />
2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 5&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 5&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 5<br />
3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 5&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4<br />
4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 5&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 5&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4<br />
5&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 5&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 5&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 5&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 5</div>
</div>
</div>
<p>将在 <tt>EmployeeID</tt> 列上透视此嵌套 select 语句返回的结果。</p>
<div class="code" id="ctl00_rs1_mainContentContainer_ctl18_other">
<div class="CodeSnippetTitleBar">
<div class="CodeDisplayLanguage"></div>
<div class="CopyCodeButton">SELECT PurchaseOrderID, EmployeeID, VendorID<br />
FROM PurchaseOrderHeader</div>
</div>
</div>
<p>这意味着 <tt>EmployeeID</tt> 列返回的唯一值自行变成了最终结果集中的字段。结果，在透视子句中指定的每个 <tt>EmployeeID</tt> 号都有相应的一列：在本例中为雇员 <tt>164</tt>、<tt>198</tt>、<tt>223</tt>、<tt>231</tt> 和 <tt>233</tt>。<tt>PurchaseOrderID</tt> 列作为值列，将根据此列对最终输出中返回的列（称为分组列）进行分组。在本例中，通过 <tt>COUNT</tt> 函数聚合分组列。请注意，将显示一条警告消息，指出为每个雇员计算 <tt>COUNT</tt> 时未考虑显示在 <tt>PurchaseOrderID</tt> 列中的任何空值。</p>
<div class="alert"><strong>重要提示</strong>：如果聚合函数与 PIVOT 一起使用，则计算聚合时将不考虑出现在值列中的任何空值。
<p>UNPIVOT 将与 PIVOT 执行几乎完全相反的操作，将列转换为行。假设以上示例中生成的表在数据库中存储为 <tt>pvt</tt>，并且您需要将列标识符 <tt>Emp1</tt>、<tt>Emp2</tt>、<tt>Emp3</tt>、<tt>Emp4</tt> 和 <tt>Emp5</tt> 旋转为对应于特定供应商的行值。这意味着必须标识另外两个列。包含要旋转的列值（<tt>Emp1</tt>、<tt>Emp2</tt>...）的列将被称为 <tt>Employee</tt>，将保存当前位于待旋转列下的值的列被称为 <tt>Orders</tt>。这些列分别对应于 Transact-SQL 定义中的 <em>pivot_column</em> 和 <em>value_column</em>。以下为该查询。</p>
</div>
<div class="code" id="ctl00_rs1_mainContentContainer_ctl19_other">
<div class="CodeSnippetTitleBar">
<div class="CodeDisplayLanguage"></div>
<div class="CopyCodeButton">--Create the table and insert values as portrayed in the previous example.<br />
CREATE TABLE pvt (VendorID int, Emp1 int, Emp2 int,<br />
Emp3 int, Emp4 int, Emp5 int)<br />
GO<br />
INSERT INTO pvt VALUES (1,4,3,5,4,4)<br />
INSERT INTO pvt VALUES (2,4,1,5,5,5)<br />
INSERT INTO pvt VALUES (3,4,3,5,4,4)<br />
INSERT INTO pvt VALUES (4,4,2,5,5,4)<br />
INSERT INTO pvt VALUES (5,5,1,5,5,5)<br />
GO<br />
--Unpivot the table.<br />
SELECT VendorID, Employee, Orders<br />
FROM <br />
&nbsp;&nbsp; (SELECT VendorID, Emp1, Emp2, Emp3, Emp4, Emp5<br />
&nbsp;&nbsp; FROM pvt) p<br />
UNPIVOT<br />
&nbsp;&nbsp; (Orders FOR Employee IN <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (Emp1, Emp2, Emp3, Emp4, Emp5)<br />
)AS unpvt<br />
GO</div>
</div>
</div>
<p>以下为部分结果集。</p>
<div class="code" id="ctl00_rs1_mainContentContainer_ctl20_other">
<div class="CodeSnippetTitleBar">
<div class="CodeDisplayLanguage"></div>
<div class="CopyCodeButton">VendorID&nbsp;&nbsp; Employee&nbsp;&nbsp; Orders<br />
1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Emp1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4<br />
1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Emp2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3<br />
1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Emp3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 5<br />
1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Emp4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4<br />
1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Emp5&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4<br />
2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Emp1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 4<br />
2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Emp2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1<br />
2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Emp3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 5<br />
2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Emp4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 5<br />
2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Emp5&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 5<br />
...</div>
</div>
</div>
<p>请注意，UNPIVOT 并不完全是 PIVOT 的逆操作。PIVOT 会执行一次聚合，从而将多个可能的行合并为输出中的单个行。而 UNPIVOT 不会重现原始表值表达式的结果，因为行已经被合并了。另外，UNPIVOT 的输入中的空值不会显示在输出中，而在执行 PIVOT 操作之前，输入中可能有原始的空值。</p>
<p><strong>AdventureWorks</strong> 示例数据库中的 <strong>Sales.vSalesPersonSalesByFiscalYears</strong> 视图将使用 PIVOT 返回每个销售人员在每个会计年度的总销售额。若要在 SQL Server Management Studio 中编写视图脚本，请在<strong>&#8220;对象资源管理器&#8221;</strong>中，在<strong>&#8220;视图&#8221;</strong>文件夹下找到 <strong>AdventureWorks</strong> 数据库对应的视图。右键单击该视图名称，再选择<strong>&#8220;编写视图脚本为&#8221;</strong>。 </p>
</div>
</div>
</div>
<img src ="http://www.cnblogs.com/Wind-Snail/aggbug/1110928.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/43625/" target="_blank">[新闻]2008年11月22日科技博客精选</a><br/><a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻频道</a>&nbsp;<a href="http://space.cnblogs.com/group.htm" target="_blank">小组</a>&nbsp;<a href="http://space.cnblogs.com/q" target="_blank">博问</a>&nbsp;<a href="http://wz.cnblogs.com/" target="_blank">网摘</a>&nbsp;<a href="http://space.cnblogs.com/ing" target="_blank">闪存</a>]]></description></item><item><title>Exceptions and Error Codes</title><link>http://www.cnblogs.com/Wind-Snail/archive/2008/03/18/1110802.html</link><dc:creator>Wind Snail</dc:creator><author>Wind Snail</author><pubDate>Tue, 18 Mar 2008 01:16:00 GMT</pubDate><guid>http://www.cnblogs.com/Wind-Snail/archive/2008/03/18/1110802.html</guid><wfw:comment>http://www.cnblogs.com/Wind-Snail/comments/1110802.html</wfw:comment><comments>http://www.cnblogs.com/Wind-Snail/archive/2008/03/18/1110802.html#Feedback</comments><slash:comments>12</slash:comments><wfw:commentRss>http://www.cnblogs.com/Wind-Snail/comments/commentRss/1110802.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/Wind-Snail/services/trackbacks/1110802.html</trackback:ping><description><![CDATA[<p style="margin-left: 0.5in"><span style="font-size: 10pt; color: black; font-family: Verdana">The beauty of returning a pointer to an object, is that you can return NULL as your standard error return value, and if the value mattered, you will most likely take the necessary steps to check its return value, or they application will just crash the moment you try to use it. </span></p>
<p style="margin-left: 0.5in"><span style="font-size: 10pt; color: black; font-family: Verdana">This could be applied to the .NET and Java APIs to reduce the amount of required try/catchs. For example, the File.IO.OpenRead method could be (shown here is the artist's representation): </span></p>
<pre id="code" style="margin-left: 0.5in"><span style="color: black"><font size="2">&nbsp;public static FileStream OpenRead (string file)</font></span></pre>
<pre style="margin-left: 0.5in"><span style="color: black"><font size="2">&nbsp;{</font></span></pre>
<pre style="margin-left: 0.5in"><span style="color: black"><font size="2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int fd = open (file);</font></span></pre>
<pre style="margin-left: 0.5in"><span style="color: black"><font size="2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </font></span></pre>
<pre style="margin-left: 0.5in"><span style="color: black"><font size="2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (f == -1)</font></span></pre>
<pre style="margin-left: 0.5in"><span style="color: black"><font size="2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return null;</font></span></pre>
<pre style="margin-left: 0.5in"><span style="color: black"><font size="2">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return new FileStreamFromFD (f);</font></span></pre>
<pre style="margin-left: 0.5in"><span style="color: black"><font size="2">&nbsp;}</font></span></pre>
<p style="margin-left: 0.5in"><span style="font-size: 10pt; color: black; font-family: Verdana">Which makes null a valid return value. If you fail to check for the return value, you would get a nice NullReferenceException, but you would allow the expensive creation of an exception object, and the ugly try/catch block in the call site. </span></p>
<p style="margin-left: 0.5in"><span style="font-size: 10pt; color: black; font-family: Verdana">Obviously we can not change the existing APIs, but we could encourage developers to minimize their use of exceptions. In my limited personal experience with software design, when I have faced applications with tons of Exceptions it was extremely hard to keep up with them. A rewrite of the software to avoid exceptions and use the more sane API paid for.</span></p>
<p style="margin: 0in 0in 0pt"><span style="font-size: 10pt; font-family: Arial">Here is the rationale for exceptions rather than error codes for <em>exceptional </em>situations. (thanks to Jason Clark for&nbsp;writting these up for us)&nbsp;&nbsp;</span></p>
<p style="margin: 3pt 0in 3pt 0.25in"><font size="2"><font face="Verdana">There are many benefits to exception handling as compared to return value based error reporting. In fact, the Framework exposes more of the benefits of exception handling then some other common exception models such as Win32 SEH or C++ exception handling. Good managed API design does not restrict the application developer from realizing the benefits of exceptions. The following are some of these benefits.</font></font></p>
<h4 style="margin: 9pt 0in 3pt"><a name="Consistency"><font face="Verdana" size="2">Exceptions Promote API Consistency</font></a></h4>
<p style="margin: 3pt 0in 3pt 0.25in"><font size="2"><font face="Verdana">Consistency of API is important to developers.&nbsp; Exceptions promote consistency, because they are designed to be used for failure reporting (and nothing else).&nbsp; In contrast, return values have many uses of which failure reporting is only a subset.&nbsp; For this reason, it is likely that APIs that report failure through return values will find a number of patterns, while exceptions can be constrained to specific patterns.&nbsp; The Win32 API is a clear example of this inconsistency through BOOLs, HRESULTS, and GetLastError() among others.</font></font></p>
<h4 style="margin: 9pt 0in 3pt"><font size="2"><font face="Verdana">Exceptions are Compatible with Object Oriented Features</font></font></h4>
<p style="margin: 3pt 0in 3pt 0.25in"><font size="2"><font face="Verdana">Object-Oriented languages tend to impose constraints on method signatures that are not imposed by functions in functional programming.&nbsp; For example, constructor methods, operator overloads, virtual methods, generic methods, interface methods and properties all resolve to functions, and yet the developer writing the method has no choice in the return value (if any) of the method.&nbsp; For this reason, it is not possible to standardize on return value based error reporting for object oriented APIs. An error reporting method, such as exceptions, which is out of band of the method signature is the only option.</font></font></p>
<h4 style="margin: 9pt 0in 3pt"><font size="2"><font face="Verdana">With Exceptions, Error Handling Code Need not be Near Failing Code</font></font></h4>
<p style="margin: 3pt 0in 3pt 0.25in"><font size="2"><font face="Verdana">With return-value based error reporting error handling code is always very near to the code that could fail.&nbsp; However, with exception handling the application developer has a choice.&nbsp; Code can be written to catch exceptions near the failure point, or the handling code can be further up in the call stack.</font></font></p>
<h4 style="margin: 9pt 0in 3pt"><font size="2"><font face="Verdana">With Exceptions, Error Handling Code is More Localized</font></font></h4>
<p style="margin: 3pt 0in 3pt 0.25in"><font size="2"><font face="Verdana">Very robust code that reports failure through return values tends to have an if statement for every functional line of code.&nbsp; The job of these if statements is to handle the failure case.&nbsp; With exception oriented code, robust code can often be written such that a number of methods and operations can be performed with the error handling logic grouped at the end of the try block (or even higher in the call-stack).&nbsp; </font></font></p>
<p style="margin: 6pt 0in 6pt 0.25in"><font style="background-color: #e9fdf3" face="Verdana" size="2">A common argument is that exception handling code is unsightly.&nbsp; This argument is usually being made by someone comparing well written exception handling code with return value oriented code that is not sufficiently checking return values of functions.&nbsp; </font></p>
<h4 style="margin: 9pt 0in 3pt"><font size="2"><font face="Verdana">Exceptions Are Not Easily Ignored</font></font></h4>
<p style="margin: 3pt 0in 3pt 0.25in"><font size="2"><font face="Verdana">Return values can be easily ignored, and often are. Exceptions, on the other hand, take an active role in the flow of your code.&nbsp; This makes failures reported as exceptions difficult to ignore, and improves the robustness of code.<br />
For example the Win32 API CloseHandle() fails very rarely, and so it is common (and appropriate) for many applications to ignore the return value of the API.&nbsp; However, if any application has a bug which causes CloseHandle() to be called twice on the same handle, it would not be obvious unless the code was written to test the return value.&nbsp; A managed equivalent to this API would throw an exception in this case and the unhandled exception handler would log the failure and the bug would be found. </font></font></p>
<h4 style="margin: 9pt 0in 3pt"><font size="2"><font face="Verdana">Exceptions Allow for Unhandled Exception Handlers</font></font></h4>
<p style="margin: 3pt 0in 3pt 0.25in"><font size="2"><font face="Verdana">Ideally, every application is written to intelligently handle all forms of failure.&nbsp; However, this is not realistic as all forms of failure can&#8217;t be known.&nbsp; With return value oriented code, failures that are unexpected are ignored by code and the application continues to run with undefined results.&nbsp; With well written exception based code, unexpected failures eventually cause an unhandled exception handler to be called.&nbsp; This handler can be designed to log the failure, and can also make the choice to shut down the application.&nbsp; This is far preferable to running with indeterminate results, and also provides for logging that makes it possible to add more significant error handling for the previously unexpected case.&nbsp; (Today, Microsoft Office uses an unhandled exception handler to gracefully recover and re-launch the application as well as send error information to Microsoft to improve the product.)</font></font></p>
<p style="margin: 6pt 0in 6pt 0.25in"><font style="background-color: #e9fdf3"><font size="2"><font face="Verdana">You should only have a custom unhandled exception handler, if you have a have specific, app-oriented work to do in the handler. If you just want error reporting to occur, the runtime will handle that automatically for you and you do not need to (and should not) use a UEF. An application should only register a UEF if it can provide functionality above and beyond the standard error reporting that comes with the system and runtime.</font></font></font></p>
<h4 style="margin: 9pt 0in 3pt"><font size="2"><font face="Verdana">Exceptions Provide Robust Error Info for Logging</font></font></h4>
<p style="margin: 3pt 0in 3pt 0.25in"><font size="2"><font face="Verdana">Exceptions provide for a consistent error handling mechanism, and as such make it possible to have consistent logging of error information.&nbsp; The System.Exception type in the Framework encapsulates stack-frame information as well as other useful information such as a nested exception type.&nbsp; This is great for error logging and discovery of unexpected error cases during the QA phase.&nbsp; Exceptions are objects, so it is possible to extend exceptions to add additional information.</font></font></p>
<p style="margin: 3pt 0in 3pt 0.25in"><strong><font size="2"><font face="Verdana">Handling Errors Consistently and Thoroughly are Essential for Creating a Good User Experience</font></font></strong></p>
<p style="margin: 3pt 0in 3pt 0.25in"><font size="2"><font face="Verdana">The application developer needs to provide specific information about what error occurred, why it occurred, and what can be done to mitigate it. This requires detailed and specific error returns from API calls. The exception mechanism allows detailed error information to be created by the API developer. There is no need for the API developer to change global header files to add new error codes. The API developer can customize the exception subclass as much as necessary to transmit all of the details of the error to the caller.</font></font></p>
<h4 style="margin: 9pt 0in 3pt"><font size="2"><font face="Verdana">Exceptions Promote Instrumentation</font></font></h4>
<p style="margin: 3pt 0in 3pt 0.25in"><font size="2"><font face="Verdana">Exceptions are a well-defined method-failure model.&nbsp; Because of this, it is possible for tools such as debuggers, profilers, performance counters, and others to be intimately aware of exceptions.&nbsp; The PerfMon application, for example, keeps track of exception statistics.&nbsp; In the future automatic instrumentation from profiling to auto-documentation will be more sophisticated related to exceptions.&nbsp; Methods that return failure do not share in the benefits of instrumentation.</font></font></p>
<h4 style="margin: 9pt 0in 3pt"><font size="2"><font face="Verdana">Exceptions Unify the Error Model (Hard and Logical Errors)</font></font></h4>
<p style="margin: 3pt 0in 3pt 0.25in"><font size="2"><font face="Verdana">Exception handling or interrupts are the only option for hard errors such as null references and divisions by zero (certain operations have no return-value means of reporting failure).&nbsp; Using exception handling for API and logical failure reporting is beneficial in that it unifies error handling for all failure types</font></font></p>
<img src ="http://www.cnblogs.com/Wind-Snail/aggbug/1110802.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/43625/" target="_blank">[新闻]2008年11月22日科技博客精选</a><br/><a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻频道</a>&nbsp;<a href="http://space.cnblogs.com/group.htm" target="_blank">小组</a>&nbsp;<a href="http://space.cnblogs.com/q" target="_blank">博问</a>&nbsp;<a href="http://wz.cnblogs.com/" target="_blank">网摘</a>&nbsp;<a href="http://space.cnblogs.com/ing" target="_blank">闪存</a>]]></description></item><item><title>Lesson 6       Smash-and-grab</title><link>http://www.cnblogs.com/Wind-Snail/archive/2008/02/12/1067256.html</link><dc:creator>Wind Snail</dc:creator><author>Wind Snail</author><pubDate>Tue, 12 Feb 2008 05:15:00 GMT</pubDate><guid>http://www.cnblogs.com/Wind-Snail/archive/2008/02/12/1067256.html</guid><wfw:comment>http://www.cnblogs.com/Wind-Snail/comments/1067256.html</wfw:comment><comments>http://www.cnblogs.com/Wind-Snail/archive/2008/02/12/1067256.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnblogs.com/Wind-Snail/comments/commentRss/1067256.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/Wind-Snail/services/trackbacks/1067256.html</trackback:ping><description><![CDATA[<p><font face="Verdana"><strong>Lesson 6&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Smash-and-grab&nbsp;&nbsp;&nbsp;&nbsp; 砸橱窗抢劫</strong></font></p>
<p><font face="Verdana">&nbsp;&nbsp;&nbsp; The expensive shops in a famous near Piccadilly were just opening. At this time of the morning, the arcade was almost empty. Mr. Taylor, the owner of a jewellery shop was admiring a new display. Two of his assistants had been working busily since eight o'clock and had only just finished. Diamond necklaces and rings had been beautifully arranged on a background of black velvet. After gazing at the display for several minutes, Mr. Taylor went back into his shop.</font>&nbsp;</p>
<p><font face="Verdana">&nbsp;&nbsp;&nbsp; The silence was suddenly broken when a large car, with its headlights on and its horn blaring, roared down the arcade. It came to a stop outside the jeweller's. One man stayed at the wheel while two others with black stocking over their faces jumped out and smashed the window of the shop with iron bars. While this was going on, Mr. Taylor was upstairs. He and his staff began throwing furniture out of the window. Chairs and tables went flying into the arcade. One of the thieves was struck by a heavy statue, but he was too busy helping himself to diamonds to notice any pain. The raid was all over in three minutes, for the men scrambled back into the car and it moved off at a fantastic speed. Just as it was leaving, Mr. Taylor rushed out and ran after it throwing ashtrays and vases, but it was impossible to stop the thieves. They had got away with thousands of pounds worth of diamonds. <br />
</font></p>
<p><font face="Verdana"></font><strong>Language points:</strong><br />
Smash-and-grab<br />
<br />
open<br />
v. When do you open/close?<br />
a. We are open/closed.<br />
opening hours --&nbsp;营业时间<br />
<br />
jewellery -- 珠宝总称<br />
jewel --&nbsp;宝石<br />
jeweller -- 珠宝商人<br />
<br />
jeweller's -- 珠宝商店<br />
grocer's -- 杂货店<br />
Mary's -- Mary家<br />
St. Paul's -- 圣保罗教堂<br />
<br />
admire -- 欣赏<br />
I admire your courage.<br />
We stopped to admire the view.<br />
<br />
display -- 展示，陈列<br />
on display<br />
<br />
arrange -- 安排，摆放，计划<br />
He was arranging a surpirse party for his wife's birthday.<br />
Who arranged these flowers so beautifully?<br />
<br />
backgroud -- 背景<br />
historical background<br />
educational background<br />
<br />
gaze&nbsp;at --&nbsp;（出于惊讶、沉思或其他情绪）常时间的盯着看<br />
start at --&nbsp;盯着看，带有不礼貌或者愤怒的情绪<br />
If you stare at people like that, you might upset them.<br />
<br />
break -- 打破<br />
break silence<br />
break the tension<br />
break the deadlock -- 打破僵局<br />
break the monotony -- 打破单调<br />
break my train of thought<br />
<br />
the wheel --&nbsp;方向盘<br />
wheel -- 轮胎<br />
<br />
go flying -- go + ing强调动作的方向<br />
<br />
be busy doing something<br />
She is busy preparing for the exams.<br />
<br />
help onself to something<br />
Please help yourselt!<br />
<br />
raid -- <font face="Verdana">n.袭击, 搜捕 v. 奇袭, 搜捕<br />
</font>a bombing raid -- 空袭<br />
a police raid -- 警察临检<br />
a bank raid -- 抢银行<br />
<br />
fantastic<br />
You lokk fantastic!<br />
a fantastic tale about dragons<br />
a fanstatic amount of money<br />
<br />
worth<br />
n. $4,000 of equipment<br />
a. The had got&nbsp;away with diamonds worth thousands of pounds.<br />
<br />
with + n. / prep. / adj. / pp.<br />
One man stayed at the wheel while two others with balck stocking over their faces jumped out and smashed the window of the shop with iron bars.<br />
The silence was suddenly broken when a large car, with&nbsp;its headlights on and its horn blaring, roared down the arcade.<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
&nbsp;</p>
<img src ="http://www.cnblogs.com/Wind-Snail/aggbug/1067256.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/43624/" target="_blank">[新闻]诺基亚将支持Lotus Notes 和黑莓争夺市场</a><br/><a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻频道</a>&nbsp;<a href="http://space.cnblogs.com/group.htm" target="_blank">小组</a>&nbsp;<a href="http://space.cnblogs.com/q" target="_blank">博问</a>&nbsp;<a href="http://wz.cnblogs.com/" target="_blank">网摘</a>&nbsp;<a href="http://space.cnblogs.com/ing" target="_blank">闪存</a>]]></description></item><item><title>Lesson 5 The facts 确切数字</title><link>http://www.cnblogs.com/Wind-Snail/archive/2008/02/12/1067248.html</link><dc:creator>Wind Snail</dc:creator><author>Wind Snail</author><pubDate>Tue, 12 Feb 2008 04:55:00 GMT</pubDate><guid>http://www.cnblogs.com/Wind-Snail/archive/2008/02/12/1067248.html</guid><wfw:comment>http://www.cnblogs.com/Wind-Snail/comments/1067248.html</wfw:comment><comments>http://www.cnblogs.com/Wind-Snail/archive/2008/02/12/1067248.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnblogs.com/Wind-Snail/comments/commentRss/1067248.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/Wind-Snail/services/trackbacks/1067248.html</trackback:ping><description><![CDATA[<p><font face="Verdana"><strong>Lesson 5&nbsp;The facts&nbsp;确切数字</strong></font>&nbsp;</p>
<p><font face="Verdana">&nbsp;&nbsp;&nbsp; Editors of newspapers and magazines often go to extremes to provide their readers with unimportant facts and statistics. Last year a journalist had been instructed by a well-known magazine to write an article on the president's palace in a new African republic. When the article arrived, the editor read the first sentence and then refuse to publish it. The article began: 'Hundreds of steps lead to the high wall which surrounds the president's palace'. The editor at once sent the journalist a fax instructing him to find out the exact number of steps and the height of the wall.</font>&nbsp;</p>
<p><font face="Verdana">The journalist immediately set out to obtain these important facts, but he took a long time to send them .Meanwhile, the editor was getting impatient, for the magazine would soon go to press. He sent the journalist two more faxes, but received no reply. He sent yet another fax informing the journalist that if he did not reply soon he would be fired. When the journalist again failed to reply, the editor reluctantly published the article as it had originally been written. A week later, the editor at last received a fax from the journalist. Not only had the poor man been arrested, but he had been sent to prison as well. However, he had at last been allowed to send a fax in which he informed the editor that&nbsp; he had been arrested while counting the 1,084 steps leading to the fifteen-foot wall which surrounded the president's palace.</font></p>
<p><font face="Verdana"></font>&nbsp;</p>
<img src ="http://www.cnblogs.com/Wind-Snail/aggbug/1067248.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/43624/" target="_blank">[新闻]诺基亚将支持Lotus Notes 和黑莓争夺市场</a><br/><a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻频道</a>&nbsp;<a href="http://space.cnblogs.com/group.htm" target="_blank">小组</a>&nbsp;<a href="http://space.cnblogs.com/q" target="_blank">博问</a>&nbsp;<a href="http://wz.cnblogs.com/" target="_blank">网摘</a>&nbsp;<a href="http://space.cnblogs.com/ing" target="_blank">闪存</a>]]></description></item><item><title>Lesson 4    The double life of `Alfred Bloggs</title><link>http://www.cnblogs.com/Wind-Snail/archive/2008/02/11/1066920.html</link><dc:creator>Wind Snail</dc:creator><author>Wind Snail</author><pubDate>Mon, 11 Feb 2008 07:30:00 GMT</pubDate><guid>http://www.cnblogs.com/Wind-Snail/archive/2008/02/11/1066920.html</guid><wfw:comment>http://www.cnblogs.com/Wind-Snail/comments/1066920.html</wfw:comment><comments>http://www.cnblogs.com/Wind-Snail/archive/2008/02/11/1066920.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnblogs.com/Wind-Snail/comments/commentRss/1066920.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/Wind-Snail/services/trackbacks/1066920.html</trackback:ping><description><![CDATA[<p><font face="Verdana"><strong>Lesson 4&nbsp;&nbsp;&nbsp; The double life of `Alfred Bloggs 阿尔弗雷德.布洛格斯的双重生活</strong></font>&nbsp;</p>
<p><font face="Verdana">&nbsp;&nbsp;&nbsp; These days, people who do manual work often receive far more money than people who work in offices. People who work in offices are `frequently referred to as "white-collar workers' for the simple reason that they usually wear a collar and tie to go to work. Such is human nature, that a great many people are often willing to `sacrifice higher pay for the `privilege of becoming white-collar workers. This can give rise to curious situations, as it did in the case of Alfred Bloggs who worked as a dustman for the Ellesmere Corporation.</font>&nbsp;</p>
<p><font face="Verdana">&nbsp;&nbsp;&nbsp; When he got married, Alf was too embarrassed to say anything to his wife about his job. He simply told her that he worked for the Corporation. Every morning, he left home dressed in a smart black suit. He then changed into overalls and spent the next eight hours as a dustman. Before returning home at night. He took a shower and changed back into his suit. Alf did this for over two years and his fellow dustmen kept his secret Alf's wife has never discovered that she married a dustman and she never will, for Alf has just found another job. He will soon be working in an office. He will be earning only half as much as he used to, but he feels that his rise in status is well worth the loss of money. From now on, he will wear a suit all day and others will call him 'Mr. Bloggs', not 'Alf'.<br />
</font></p>
<p><strong>Language points:<br />
</strong>double&nbsp;<br />
co<em>ll</em>ar<br />
<em>44</em>13<em>22</em><br />
double bed/room<br />
double standard&nbsp;<br />
<br />
manual -- by hand<br />
a manual typewriter<br />
manual work/labour//mental work/labour<br />
<br />
refer to -- be descriped<br />
He spoke without referring to the notes.<br />
<br />
such that<br />
Such is life.<br />
<br />
sacrifiee -- 为了...牺牲，give up<br />
Many women sacrifiee their careers for their family.<br />
<br />
privilege -- 特权<br />
aristocratic privilege<br />
<br />
give rise to -- be the reason whay somehing happened<br />
The recent accident is giving rise to national concern.<br />
<br />
curious -- 奇怪的,好奇的<br />
Bayies are curious about everything around them.<br />
She was wearing a curious smile on her face.<br />
<br />
embarrassed -- 为难的，困窘的<br />
I was really embrassed when i spilt coffee on his shirt.<br />
He was ashamed of having lied to hi family.<br />
He was too shy to ask her to dance with him.<br />
He feels awkward with women.<br />
<br />
smart -- 漂亮的，聪明的，老练的，时尚的<br />
a smart restaurant<br />
a smart kid<br />
a smart lawyer<br />
<br />
well <br />
well ahead of time<br />
<br />
... far more money than ...<br />
<br />
... half as much as ...</p>
<img src ="http://www.cnblogs.com/Wind-Snail/aggbug/1066920.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/43623/" target="_blank">[新闻]Mozilla公布去年收入报告</a><br/><a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻频道</a>&nbsp;<a href="http://space.cnblogs.com/group.htm" target="_blank">小组</a>&nbsp;<a href="http://space.cnblogs.com/q" target="_blank">博问</a>&nbsp;<a href="http://wz.cnblogs.com/" target="_blank">网摘</a>&nbsp;<a href="http://space.cnblogs.com/ing" target="_blank">闪存</a>]]></description></item><item><title>Lesson 3  An unknown goddess</title><link>http://www.cnblogs.com/Wind-Snail/archive/2008/02/10/1066695.html</link><dc:creator>Wind Snail</dc:creator><author>Wind Snail</author><pubDate>Sun, 10 Feb 2008 12:34:00 GMT</pubDate><guid>http://www.cnblogs.com/Wind-Snail/archive/2008/02/10/1066695.html</guid><wfw:comment>http://www.cnblogs.com/Wind-Snail/comments/1066695.html</wfw:comment><comments>http://www.cnblogs.com/Wind-Snail/archive/2008/02/10/1066695.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnblogs.com/Wind-Snail/comments/commentRss/1066695.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/Wind-Snail/services/trackbacks/1066695.html</trackback:ping><description><![CDATA[<p><font face="Verdana"><strong>Lesson 3&nbsp; An unknown goddess&nbsp; 无名女神</strong></font>&nbsp;</p>
<p><font face="Verdana">Some time ago, an interesting discovery was made by archaeologists on the Aegean island of Kea. An American team explored a temple which stands in an ancient city on the promontory of Ayia Irini. The city at one time must have been prosperous, for it enjoyed a high level of civilization. Houses -- often three storeys（story） high -- were built of stone. They had large rooms with beautifully &#8216;decorated walls. The city was equipped with a drainage system, for a great many clay pipes were found be`neath the narrow streets.</font>&nbsp;</p>
<p><font face="Verdana">&nbsp;&nbsp;&nbsp; The temple which the archaeologists explored was used as a place of worship from the fifteenth century B.C. until Roman times. In the most sacred room of temple, clay fragments of fifteen statues were found. Each of these represented a goddess and had, at one time, been painted. The body of one statue was found among remains dating from the fifteenth century B.C. It's missing head happened to be among remains of the fifth century B.C. This head must have been found in Classical times and carefully preserved. It was very old and precious even then. When the archaeologists reconstructed the fragments, they were amazed to find that the goddess turned out to be a very modern-looking woman. She stood three feet high and her hands rested on her hips. She was wearing a full-length skirt which swept the ground. De`spite her great age, she was very graceful indeed, but, so far, the archaeologists have been unable to discover her identity.<br />
<br />
<strong>Language points:<br />
</strong>archaeologist<br />
n. archaeology<br />
a. archaeological<br />
<br />
explore -- to search and discover考察,研究<br />
explore space<br />
explore the issue/topic/question<br />
<br />
promontory -- 海角 <br />
<br />
enjoy -- 喜欢，享受，享有，拥有<br />
I enjoy meeting people.<br />
enjoy oneself<br />
This arctress has always enjoyed a good reputation.<br />
<br />
be built of&nbsp;<br />
This house is built of wood.<br />
<br />
worship -- 崇拜<br />
act of worship<br />
hero worship<br />
<br />
times<br />
Classical times -- 特指古希腊罗马时期<br />
<br />
scared -- 神圣的， holy, divine<br />
<br />
statue<br />
Statue of liberty<br />
stature -- 升高,水平<br />
an artist of great stature<br />
status -- 地位，身份，状态<br />
marital status<br />
statue -- 法令，法规<br />
college statue<br />
<br />
paint<br />
paint her room pink<br />
paint her nails<br />
paint a picture -- 画画<br />
<br />
remains -- 遗迹，残骸，遗体<br />
The remains of the day -- 去日留痕<br />
the remains of lunch<br />
the remains of an aircraft<br />
His remains were returened to his homeland after his death.<br />
<br />
date from -- have been existed from<br />
Thanks for your letter date August 15, 2002.<br />
Archaeologists were unable to date the fossils.<br />
Are you still dating hime?<br />
<br />
amaze -- 惊奇，困惑，惊异，强调wonder<br />
surpirse,astonish, astound<br />
<br />
turn out to be -- 含有出乎意料的意思<br />
The guy I went to meet turned out to be my former classmate.<br />
<br />
full-lenght <br />
full-length dress/coat<br />
full-lenght mirror/photograph<br />
<br />
sweep<br />
sweep the floor<br />
<br />
great <br />
<br />
so far -- 到现在为止<br />
so far so good<br />
<br />
identity<br />
identity card(ID card)<br />
a sense of identity -- 身份感，归属感<br />
<br />
a&nbsp;temple which stands in an ancient city<br />
she stood three feet high<br />
The bicycle rested against the wall.<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
</font></p>
<img src ="http://www.cnblogs.com/Wind-Snail/aggbug/1066695.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/43621/" target="_blank">[新闻]2008年11月21日科技博客精选</a><br/><a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻频道</a>&nbsp;<a href="http://space.cnblogs.com/group.htm" target="_blank">小组</a>&nbsp;<a href="http://space.cnblogs.com/q" target="_blank">博问</a>&nbsp;<a href="http://wz.cnblogs.com/" target="_blank">网摘</a>&nbsp;<a href="http://space.cnblogs.com/ing" target="_blank">闪存</a>]]></description></item><item><title>Lesson 2  Thirteen equals one</title><link>http://www.cnblogs.com/Wind-Snail/archive/2008/02/10/1066561.html</link><dc:creator>Wind Snail</dc:creator><author>Wind Snail</author><pubDate>Sun, 10 Feb 2008 05:44:00 GMT</pubDate><guid>http://www.cnblogs.com/Wind-Snail/archive/2008/02/10/1066561.html</guid><wfw:comment>http://www.cnblogs.com/Wind-Snail/comments/1066561.html</wfw:comment><comments>http://www.cnblogs.com/Wind-Snail/archive/2008/02/10/1066561.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnblogs.com/Wind-Snail/comments/commentRss/1066561.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/Wind-Snail/services/trackbacks/1066561.html</trackback:ping><description><![CDATA[<p><font face="Verdana"><strong>Lesson 2&nbsp; Thirteen equals one&nbsp; 十三等于一</strong></font></p>
<p><font face="Verdana"></font>&nbsp;<font face="Verdana">&nbsp;&nbsp;&nbsp; Our vicar is always raising money for one cause or another, but he has never managed to get enough money to have the church clock repaired. The big clock which used to strike the hours day and night was damaged many years ago and has been silent ever since. One night, however, our vicar work up with a start: the clock was striking the hours! Looking at his watch, he saw that it was one o'clock, but the bell struck thirteen times before it stopped. Armed with a torch, the vicar went up into the clock tower to see what was going on. In the torchlight, he caught sight of a figure whom he immediately recognized as Bill Wilkins, our local grocer.'Whatever are you doing up here Bill?' asked the vicar in surprise. 'I'm trying to repair the bell,' answered Bill. 'I've been coming up here night after night for weeks now. You see, I was hoping to give you a surprise.''You certainly did give me a surprise!' said the vicar. 'You've probably woken up everyone in the village as well. Still, I'm glad the bell is working again. That's the trouble, vicar,' answered Bill. 'It's working all right, but I'm afraid that at one o'clock it will strike thirteen times and there's nothing I can do about it."We'll get used to that, Bill,' said the vicar. "Thirteen is not as good as one, but it's better than nothing. Now let's go downstairs and have a cup of tea.' </font></p>
<p><font face="Verdana"></font><strong>Language points:</strong><br />
equal --平等,等于<br />
v. Two plus two equals 4.<br />
a. All men are created equal.<br />
&nbsp;&nbsp;&nbsp;&nbsp;equal pay for equal work<br />
n. Our boss treated us all as equal.<br />
<br />
vicar -- 牧师,神父<br />
priest, pastor, rector, clergyman<br />
<br />
raise -- 筹集<br />
raise cash/captial/foud<br />
<br />
for one cause or another<br />
cause -- 这里是事业的意思<br />
the cause of world peace<br />
for one thing or another -- 总会<br />
We'll get out of the mess in one way or another.</p>
have sth done<br />
have my car reparied<br />
have my hair done/cut<br />
<br />
strike the hours -- 报时<br />
When the clock was striking twelve, Cinderella ran away.<br />
Twelve had just struck when she ran away.<br />
<br />
day and night = night and day -- all the time<br />
night after night -- every night<br />
<br />
damage -- 事物被损害<br />
injure -- 人身体上受到伤害<br />
hurt -- 人心灵上受到伤害<br />
<br />
slient -- 安静的,强调无声的安静<br />
a slient film<br />
The letter 'h' in 'hour' is slient.<br />
still -- 强调没有动作的安静<br />
quiet -- 气氛上的安详和安宁<br />
<br />
start -- 猛地一惊<br />
One night, our vicar woke up with a start.<br />
<br />
arm -- 武装，军队，佩戴<br />
armed to the teeth<br />
She came to the meeting armed with the facts and figures.<br />
<br />
catch sight of&nbsp; -- 看见<br />
lose sight of&nbsp; -- 看不见了<br />
<br />
local -- 当地的，本地的<br />
local government<br />
local time<br />
<br />
better than nothing <br />
The only hotel here was dirty, but it was better than nothing<br />
Better late than never.<br />
<br />
what was going on<br />
It's working all right. -- 还行<br />
Whatever are you doning up here. -- What on earth are you doing here?<br />
You certainly did give me a surprise!<br />
Do sit down.<br />
<br />
<br />
<img src ="http://www.cnblogs.com/Wind-Snail/aggbug/1066561.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/43621/" target="_blank">[新闻]2008年11月21日科技博客精选</a><br/><a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻频道</a>&nbsp;<a href="http://space.cnblogs.com/group.htm" target="_blank">小组</a>&nbsp;<a href="http://space.cnblogs.com/q" target="_blank">博问</a>&nbsp;<a href="http://wz.cnblogs.com/" target="_blank">网摘</a>&nbsp;<a href="http://space.cnblogs.com/ing" target="_blank">闪存</a>]]></description></item><item><title>Lesson 1 A puma at large</title><link>http://www.cnblogs.com/Wind-Snail/archive/2008/02/09/1066409.html</link><dc:creator>Wind Snail</dc:creator><author>Wind Snail</author><pubDate>Sat, 09 Feb 2008 14:32:00 GMT</pubDate><guid>http://www.cnblogs.com/Wind-Snail/archive/2008/02/09/1066409.html</guid><wfw:comment>http://www.cnblogs.com/Wind-Snail/comments/1066409.html</wfw:comment><comments>http://www.cnblogs.com/Wind-Snail/archive/2008/02/09/1066409.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnblogs.com/Wind-Snail/comments/commentRss/1066409.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/Wind-Snail/services/trackbacks/1066409.html</trackback:ping><description><![CDATA[<p><font face="Verdana"><strong>Lesson 1 A Puma at large 逃遁的美洲狮</strong> </font></p>
<p><font face="Verdana">Pumas are large, cat-like animals which are found in America. When reports came into London Zoo that a wild puma had been spotted forty-five miles south of London, they were not taken seriously. However, as the evidence began to accumulate,&nbsp;&nbsp; experts from the Zoo felt obliged to investigate, for the descriptions given by people who claimed to have seen the puma were extraordinarily similar. The hunt for the puma began in a small village<br />
&nbsp;&nbsp;&nbsp; where a woman picking blackberries&nbsp; saw 'a large cat' only five yards away from her. It immediately&nbsp; ran away&nbsp; when she saw it, and experts confirmed that a puma will not attack a human being unless it is cornered. The search proved difficult, for the puma was often observed at one place in the morning and at another place twenty miles away in the evening. Wherever it went, it left behind it a trail of dead deer and small animals like rabbits. Paw prints were seen in a number of places&nbsp; and puma fur&nbsp; was found clinging to bushes. Several people complained of "cat-like noises' at night and a businessman on a fishing trip<br />
&nbsp;&nbsp;&nbsp; saw the puma up a tree. The experts were now fully convinced that the animal was a puma, but where had it come from? As no pumas had been reported missing from any zoo in the country, this one must have been in the possession of a private collector and somehow managed to escape. The hunt went on for several weeks, but the puma was not caught. It is disturbing to think that a dangerous wild animal is still at large in the quiet countryside. </font></p>
<p><font face="Verdana"><strong>Langue points:</strong><br />
be at large -- 潜逃<br />
The escaped prisoners are still at large.<br />
<br />
看见<br />
spotted -- to notice something very difficulty to see.看见了不太容易看见的，或者发现了正在寻找的。I spotted someone coming out of the building.<br />
seen -- 比较常用的<br />
observed -- 比较书面化<br />
<br />
accumulate -- 逐渐增加或积累<br />
<br />
feel obliged to do -- must, have to<br />
I felt obliged to invite him.<br />
经常用作书面语，有责任或义务做某事。<br />
<br />
hunt -- 捕猎，搜寻，search<br />
go on a deer/fox hunt<br />
the hunt for the remains of the Titanic<br />
hunt for second-hand books<br />
job-hunting<br />
<br />
pick -- 采摘,挑选<br />
pick cotton<br />
We need to pick someone reliable.<br />
pick and choose -- 挑挑拣拣<br />
<br />
escape<br />
<font face="Verdana">[is'keip]<br />
n.<br />
逃, 逃亡, 溢出设备, 出口, 逃跑, [植]野生<br />
vi.<br />
逃脱, 避开, 溜走<br />
vt.<br />
逃避, 避免, 被忘掉<br />
</font><br />
cornered -- 陷入困境，被逼得走投无路<br />
<br />
proved -- 证明是，原来是，turn out to be<br />
They proved her innocence<br />
The rumour proved false.<br />
<br />
cling to -- 粘在，固守，坚持，固执的相信<br />
cling-clung-clung<br />
His wet shirt clung to his body.<br />
She clings to the belief that her husband will come back.<br />
<br />
complain -- 抱怨，诉说<br />
complain about the weather<br />
complain of a headache<br />
<br />
disturb -- 打搅，worry，令人担忧，令人不安<br />
Sorry to disturb you.<br />
Do not disturb.<br />
His strange behaviour disturbed me.<br />
<br />
link words<br />
<br />
常用被动语态表达一种事实<br />
had been spotted<br />
was observed<br />
found clinging<br />
had beed reported<br />
</font></p>
<p><font face="Verdana"></font>&nbsp;</p>
 <img src ="http://www.cnblogs.com/Wind-Snail/aggbug/1066409.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/43620/" target="_blank">[新闻]Google拟年底前关闭"lively" 因不敌"第二人生"</a><br/><a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻频道</a>&nbsp;<a href="http://space.cnblogs.com/group.htm" target="_blank">小组</a>&nbsp;<a href="http://space.cnblogs.com/q" target="_blank">博问</a>&nbsp;<a href="http://wz.cnblogs.com/" target="_blank">网摘</a>&nbsp;<a href="http://space.cnblogs.com/ing" target="_blank">闪存</a>]]></description></item><item><title>Exceptions vs Error Codes (异常还是错误代码）</title><link>http://www.cnblogs.com/Wind-Snail/archive/2008/01/16/1041230.html</link><dc:creator>Wind Snail</dc:creator><author>Wind Snail</author><pubDate>Wed, 16 Jan 2008 05:44:00 GMT</pubDate><guid>http://www.cnblogs.com/Wind-Snail/archive/2008/01/16/1041230.html</guid><wfw:comment>http://www.cnblogs.com/Wind-Snail/comments/1041230.html</wfw:comment><comments>http://www.cnblogs.com/Wind-Snail/archive/2008/01/16/1041230.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cnblogs.com/Wind-Snail/comments/commentRss/1041230.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/Wind-Snail/services/trackbacks/1041230.html</trackback:ping><description><![CDATA[摘要: &nbsp;&nbsp;<a href='http://www.cnblogs.com/Wind-Snail/archive/2008/01/16/1041230.html'>阅读全文</a><img src ="http://www.cnblogs.com/Wind-Snail/aggbug/1041230.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/43619/" target="_blank">[新闻]微软证实已雇佣前雅虎搜索官员Suchter</a><br/><a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&nbsp;<a href="http://news.cnblogs.com" target="_blank">新闻频道</a>&nbsp;<a href="http://space.cnblogs.com/group.htm" target="_blank">小组</a>&nbsp;<a href="http://space.cnblogs.com/q" target="_blank">博问</a>&nbsp;<a href="http://wz.cnblogs.com/" target="_blank">网摘</a>&nbsp;<a href="http://space.cnblogs.com/ing" target="_blank">闪存</a>]]></description></item><item><title>SQL Server SQL语句调优技巧</title><link>http://www.cnblogs.com/Wind-Snail/archive/2008/01/10/1033031.html</link><dc:creator>Wind Snail</dc:creator><author>Wind Snail</author><pubDate>Thu, 10 Jan 2008 01:54:00 GMT</pubDate><guid>http://www.cnblogs.com/Wind-Snail/archive/2008/01/10/1033031.html</guid><wfw:comment>http://www.cnblogs.com/Wind-Snail/comments/1033031.html</wfw:comment><comments>http://www.cnblogs.com/Wind-Snail/archive/2008/01/10/1033031.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cnblogs.com/Wind-Snail/comments/commentRss/1033031.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/Wind-Snail/services/trackbacks/1033031.html</trackback:ping><description><![CDATA[子查询优化<br />
<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 一条好的值得称赞的规则是尽量用连接代替所有的子查询。优化器有时可以自动将子查询&#8220;扁平化&#8221;，并且用常规或外连接代替。但那样也不总是有效。明确的连接对选择表的顺序和找到最可能的计划给出了更多的选项。当你优化一个特殊查询时，了解一下是否去掉自查询可产生很大的差异。<br />
<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 示例<br />
<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 下面查询选择了pubs数据库中所有表的名字，以及每个表的聚集索引（如果存在）。如果没有聚集索引，表名仍然显示在列表中，在聚集索引列中显示为虚线。两个查询返回同样的结果集，但第一个使用了一个子查询，而第二个使用一个外连接时。比较Microsoft SQL Server产生的查询计划 <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SUBQUERY SOLUTION<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ---------------------- <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SELECT st.stor_name AS 'Store', <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (SELECT SUM(bs.qty) <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; FROM big_sales AS bs <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; WHERE bs.stor_id = st.stor_id), 0) <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; AS 'Books Sold' <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; FROM stores AS st <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; WHERE st.stor_id IN <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (SELECT DISTINCT stor_id <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; FROM big_sales) <br />
JOIN SOLUTION<br />
<br />
---------------------- <br />
<br />
SELECT st.stor_name AS 'Store', <br />
<br />
SUM(bs.qty) AS 'Books Sold' <br />
<br />
FROM stores AS st <br />
<br />
JOIN big_sales AS bs <br />
<br />
ON bs.stor_id = st.stor_id <br />
<br />
WHERE st.stor_id IN <br />
<br />
(SELECT DISTINCT stor_id <br />
<br />
FROM big_sales) <br />
<br />
GROUP BY st.stor_name <br />
<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SUBQUERY SOLUTION<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ---------------------- <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SQL Server parse and compile time:<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CPU time = 28 ms <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; elapsed time = 28 ms <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SQL Server Execution Times: <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CPU time = 145 ms <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; elapsed time = 145 ms <br />
<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Table 'big_sales'. Scan count 14, logical reads <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1884, physical reads 0, read-ahead reads 0. <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Table 'stores'. Scan count 12, logical reads 24, <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; physical reads 0, read-ahead reads 0. <br />
<br />
JOIN SOLUTION<br />
<br />
---------------------- <br />
<br />
SQL Server parse and compile time: <br />
<br />
&nbsp;&nbsp;&nbsp; CPU time = 50 ms <br />
<br />
&nbsp;&nbsp;&nbsp; elapsed time = 54 ms <br />
<br />
SQL Server Execution Times: <br />
<br />
&nbsp;&nbsp;&nbsp; CPU time = 109 ms <br />
<br />
&nbsp;&nbsp;&nbsp; elapsed time = 109 ms <br />
<br />
<br />
Table 'big_sales'. Scan count 14, logical reads <br />
<br />
966, physical reads 0, read-ahead reads 0. <br />
<br />
Table 'stores'. Scan count 12, logical reads 24, <br />
physical reads 0, read-ahead reads 0. <br />
<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 不必更深探索，我们可以看到在CPU和总的实耗时间方面连接更快，仅需要子查询方案逻辑读的一半。此外，这两种情况伴随着相同的结果集，虽然排序的顺序不同，这是因为连接查询（由于它的GROUP BY子句）有一个隐含的ORDER BY:<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Store Books Sold <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ------------------------------------------------- <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Barnum's 154125 <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Bookbeat 518080 <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Doc-U-Mat: Quality Laundry and Books 581130 <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Eric the Read Books 76931 <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Fricative Bookshop 259060 <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; News &amp; Brews 161090 <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (6 row(s) affected) <br />
<br />
<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Store Books Sold <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ------------------------------------------------- <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Eric the Read Books 76931 <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Barnum's 154125 <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; News &amp; Brews 161090 <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Doc-U-Mat: Quality Laundry and Books 581130 <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Fricative Bookshop 259060 <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Bookbeat 518080 <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (6 row(s) affected) <br />
<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 查看这个子查询方法展示的查询计划:<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |--Compute Scalar(DEFINE:([Expr1006]=isnull([Expr1004], 0))) <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |--Nested Loops(Left Outer Join, OUTER REFERENCES:([st].[stor_id])) <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |--Nested Loops(Inner Join, OUTER REFERENCES:([big_sales].[stor_id]))<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; | |--Stream Aggregate(GROUP BY:([big_sales].[stor_id])) <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; | | |--Clustered Index Scan(OBJECT:([pubs].[dbo].[big_sales].<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [UPKCL_big_sales]), ORDERED FORWARD) <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; | |--Clustered Index Seek(OBJECT:([pubs].[dbo].[stores].[UPK_storeid] <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; AS [st]), <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SEEK:([st].[stor_id]=[big_sales].[stor_id]) ORDERED FORWARD) <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |--Stream Aggregate(DEFINE:([Expr1004]=SUM([bs].[qty]))) <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |--Clustered Index Seek(OBJECT:([pubs].[dbo].[big_sales]. <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [UPKCL_big_sales] AS [bs]), <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SEEK:([bs].[stor_id]=[st].[stor_id]) ORDERED FORWARD) <br />
<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 反之，求和查询操作我们可以得到：<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |--Stream Aggregate(GROUP BY:([st].[stor_name]) <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DEFINE:([Expr1004]=SUM([partialagg1005]))) <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |--Sort(ORDER BY:([st].[stor_name] ASC)) <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |--Nested Loops(Left Semi Join, OUTER REFERENCES:([st].[stor_id]))<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |--Nested Loops(Inner Join, OUTER REFERENCES:([bs].[stor_id])) <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; | |--Stream Aggregate(GROUP BY:([bs].[stor_id]) <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DEFINE:([partialagg1005]=SUM([bs].[qty])))<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; | | |--Clustered Index Scan(OBJECT:([pubs].[dbo].[big_sales]. <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [UPKCL_big_sales] AS [bs]), ORDERED FORWARD) <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; | |--Clustered Index Seek(OBJECT:([pubs].[dbo].[stores]. <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [UPK_storeid] AS [st]), <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SEEK:([st].[stor_id]=[bs].[stor_id]) ORDERED FORWARD) <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |--Clustered Index Seek(OBJECT:([pubs].[dbo].[big_sales]. <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [UPKCL_big_sales]), <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SEEK:([big_sales].[stor_id]=[st].[stor_id]) ORDERED FORWARD) <br />
<br />
<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 使用连接是更有效的方案。它不需要额外的流聚合（stream aggregate），即子查询所需在big_sales.qty列的求和。<br />
<br />
<br />
<br />
<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; UNION vs UNION ALL<br />
<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 无论何时尽可能用UNION ALL 代替UNION。其中的差异是因为UNION有排除重复行并且对结果进行排序的副作用，而UNION ALL不会做这些工作。选择无重复行的结果需要建立临时工作表，用它排序所有行并且在输出之前排序。（在一个select distinct 查询中显示查询计划将发现存在一个流聚合，消耗百分之三十多的资源处理查询）。当你确切知道你得需要时，可以使用UNION。但如果你估计在结果集中没有重复的行，就使用UNION ALL吧。它只是从一个表或一个连接中选择，然后从另一个表中选择，附加在第一条结果集的底部。UNION ALL不需要工作表和排序（除非其它条件引起的）。在大部分情况下UNION ALL更具效率。一个有潜在危险的问题是使用UNION会在数据库中产生巨大的泛滥的临时工作表。如果你期望从UNION查询中获得大量的结果集时，这就可能发生。<br />
<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 示例<br />
<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 下面的查询是选择pubs数据库中的表sales的所有商店的ID，也选择表big_sales中的所有商店的ID，这个表中我们加入了70，000多行数据。在这两个方案间不同之处仅仅是UNION 与UNION ALL的使用比较。但在这个计划中加入ALL关键字产生了三大不同。第一个方案中，在返回结果集给客户端之前需要流聚合并且排序结果。第二个查询更有效率，特别是对大表。在这个例子中两个查询返回同样的结果集，虽然顺序不同。在我们的测试中有两个临时表。你的结果可能会稍有差异。<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; UNION SOLUTION <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ----------------------- <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; UNION ALL SOLUTION <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -----------------------<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SELECT stor_id FROM big_sales <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; UNION <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SELECT stor_id FROM sales <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ----------------------------<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SELECT stor_id FROM big_sales <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; UNION ALL <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SELECT stor_id FROM sales <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ----------------------------<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |--Merge Join(Union) <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |--Stream Aggregate(GROUP BY:<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ([big_sales].[stor_id])) <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; | |--Clustered Index Scan <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (OBJECT:([pubs].[dbo].<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [big_sales]. <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [UPKCL_big_sales]), <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ORDERED FORWARD) <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |--Stream Aggregate(GROUP BY:<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ([sales].[stor_id])) <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |--Clustered Index Scan <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (OBJECT:([pubs].[dbo]. <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [sales].[UPKCL_sales]),<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ORDERED FORWARD) <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |--Concatenation <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |--Index Scan <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (OBJECT:([pubs].[dbo]. <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [big_sales].[ndx_sales_ttlID])) <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |--Index Scan <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (OBJECT:([pubs].[dbo]. <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [sales].[titleidind])) <br />
<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; UNION SOLUTION<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ----------------------- <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Table 'sales'. Scan count 1, logical<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; reads 2, physical reads 0, <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; read-ahead reads 0. <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Table 'big_sales'. Scan count 1,<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; logical <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; reads 463, physical reads 0, <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; read-ahead reads 0. <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; UNION ALL SOLUTION<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ----------------------- <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Table 'sales'. Scan count 1, logical<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; reads 1, physical reads 0, <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; read-ahead reads 0.<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Table 'big_sales'. Scan count 1, <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; logical <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; reads 224, physical reads 0, <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; read-ahead reads 0. <br />
<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 虽然在这个例子的结果集是可互换的，你可以看到UNION ALL语句比UNION语句少消耗一半的资源。所以应当预料你的结果集并且确定已经没有重复时，使用UNION ALL子句。<br />
<br />
<br />
<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 函数和表达式约束索引<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 当你在索引列上使用内置的函数或表达式时，优化器不能使用这些列的索引。尽量重写这些条件，在表达式中不要包含索引列。<br />
<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 示例<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 你应该帮助SQL Server移除任何在索引数值列周围的表达式。下面的查询是从表jobs通过唯一的聚集索引的唯一键值选择出的一行。如果你在这个列上使用表达式，这个索引就不起作用了。但一旦你将条件&#8217;job_id-2=0&#8217; 该成&#8216;job_id=2&#8217;，优化器将在聚集索引上执行seek操作。<br />
<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; QUERY WITH SUPPRESSED INDEX <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ----------------------- <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; OPTIMIZED QUERY USING INDEX <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ----------------------- <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SELECT * <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; FROM jobs<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; WHERE (job_id-2) = 0 <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SELECT * <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; FROM jobs <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; WHERE job_id = 2 <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |--Clustered Index Scan(OBJECT:<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ([pubs].[dbo].[jobs]. <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [PK__jobs__117F9D94]), <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; WHERE:(Convert([jobs].[job_id])- <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2=0)) <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; |--Clustered Index Seek(OBJECT: <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ([pubs].[dbo].[jobs]. <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [PK__jobs__117F9D94]), <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SEEK:([jobs].[job_id]=Convert([@1])) <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ORDERED FORWARD) <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Note that a SEEK is much better than a SCAN, <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; as in the previous query. <br />
<br />
<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 下面表中列出了多种不同类型查询示例，其被禁止使用列索引，同时给出改写的方法，以获得更优的性能。<br />
<br />
<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; QUERY WITH SUPPRESSED INDEX <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; --------------------------------------- <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; OPTIMIZED QUERY USING INDEX <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -------------------------------------- <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DECLARE @job_id VARCHAR(5) <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SELECT @job_id = &#8216;2&#8217; <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SELECT * <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; FROM jobs <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; WHERE CONVERT( VARCHAR(5), <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; job_id ) = @job_id <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ------------------------------- <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DECLARE @job_id VARCHAR(5) <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SELECT @job_id = &#8216;2&#8217; <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SELECT * <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; FROM jobs <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; WHERE job_id = CONVERT( <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SMALLINT, @job_id ) <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ------------------------------- <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SELECT * <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; FROM authors <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; WHERE au_fname + ' ' + au_lname <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; = 'Johnson White' <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -------------------------------<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SELECT * <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; FROM authors <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; WHERE au_fname = 'Johnson'<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; AND au_lname = 'White' <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ------------------------------- <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SELECT * <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; FROM authors <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; WHERE SUBSTRING( au_lname, 1, 2 ) = 'Wh' <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ------------------------------- <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SELECT * <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; FROM authors <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; WHERE au_lname LIKE 'Wh%' <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ------------------------------- <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CREATE INDEX employee_hire_date <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ON employee ( hire_date ) <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; GO <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -- Get all employees hired <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -- in the 1st quarter of 1990: <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SELECT * <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; FROM employee <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; WHERE DATEPART( year, hire_date ) = 1990 <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; AND DATEPART( quarter, hire_date ) = 1 <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ------------------------------- <br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CREATE INDEX employee_hire_date <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ON employee ( hire_date )<br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; GO <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -- Get all employees hired <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; -- in the 1st quarter of 1990: <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SELECT * <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; FROM employee <br />
<br />
&nbsp;&nbsp;&nbsp;&nbsp;