﻿<?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>博客园--------來自寒冷的國度</title><link>http://www.cnblogs.com/Harlan/</link><description>跳舞吧，像没有人欣赏一样；唱歌吧，像没有人聆听一样;生活吧，像今天是末日一样；去爱吧，像不曾受伤一样 ......</description><language>zh-cn</language><lastBuildDate>Sat, 11 Oct 2008 02:37:54 GMT</lastBuildDate><pubDate>Sat, 11 Oct 2008 02:37:54 GMT</pubDate><ttl>60</ttl><item><title>自己寫的一個流量分析（用存儲過程實現）</title><link>http://www.cnblogs.com/Harlan/archive/2008/05/20/1203218.html</link><dc:creator>Harlan---</dc:creator><author>Harlan---</author><pubDate>Tue, 20 May 2008 03:23:00 GMT</pubDate><guid>http://www.cnblogs.com/Harlan/archive/2008/05/20/1203218.html</guid><wfw:comment>http://www.cnblogs.com/Harlan/comments/1203218.html</wfw:comment><comments>http://www.cnblogs.com/Harlan/archive/2008/05/20/1203218.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cnblogs.com/Harlan/comments/commentRss/1203218.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/Harlan/services/trackbacks/1203218.html</trackback:ping><description><![CDATA[<p><font face="Verdana">set ANSI_NULLS ON<br />
set QUOTED_IDENTIFIER ON<br />
go</font></p>
<p><font face="Verdana">/*<br />
後端流量統計<br />
*/<br />
Create&nbsp;procedure [dbo].[P_SiteVisitCount]<br />
as<br />
begin<br />
&nbsp;set nocount on<br />
&nbsp;declare @FirstDate varchar(10),@Today varchar(10)<br />
&nbsp;declare @TempFirstDate datetime,@TempToday datetime<br />
&nbsp;declare @ThisDayVisit int ,&nbsp; @MaxVisitDay varchar(20)<br />
&nbsp;declare @ThisMonthVisit int ,&nbsp; @MaxVisitMonth varchar(20)<br />
&nbsp;declare @ThisYearVisit int ,&nbsp; @MaxVisitYear varchar(20)<br />
&nbsp;declare @VisitCount int<br />
&nbsp;declare @AvgDayVisit int , @AvgMonthVisit int, @AvgYearVisit int<br />
&nbsp;declare @Days int , @Months int , @Years int<br />
&nbsp;<br />
&nbsp;select @TempFirstDate = min(VisitDate) from T_SiteVisit <br />
&nbsp;set @TempToday = getdate() </font></p>
<p><font face="Verdana">&nbsp;set @FirstDate = convert(varchar,@TempFirstDate,111) --啟用日<br />
&nbsp;set @Today = convert(varchar,@TempToday,111)&nbsp;&nbsp; --本日<br />
&nbsp;select @VisitCount = sum(VisitCount) from T_SiteVisit --總訪問數<br />
&nbsp;</font></p>
<p><font face="Verdana">&nbsp;set @Days = datediff(day,@FirstDate,@Today) + 1<br />
&nbsp;set @Months = datediff(month,@FirstDate,@Today) + 1<br />
&nbsp;set @Years = datediff(year,@FirstDate,@Today) + 1<br />
&nbsp;<br />
&nbsp; <br />
&nbsp;set @AvgDayVisit = @VisitCount/@Days&nbsp;&nbsp;--平均日訪數<br />
&nbsp;set @AvgMonthVisit = @VisitCount/@Months&nbsp;--平均月訪數<br />
&nbsp;set @AvgYearVisit = @VisitCount/@Years&nbsp;&nbsp;--平均年訪數</font></p>
<p><font face="Verdana">&nbsp;--本日訪問數<br />
&nbsp;select @ThisDayVisit = sum(VisitCount) from T_SiteVisit <br />
&nbsp;where convert(varchar,VisitDate,111) = convert(varchar,getdate(),111)</font></p>
<p><font face="Verdana">&nbsp;--本月訪問數<br />
&nbsp;select @ThisMonthVisit = sum(VisitCount) from T_SiteVisit <br />
&nbsp;where datepart(year,VisitDate) = datepart(year,getdate()) and <br />
&nbsp;datepart(month,VisitDate) = datepart(month,getdate()) </font></p>
<p><font face="Verdana">&nbsp;--本年訪問數<br />
&nbsp;select @ThisYearVisit = sum(VisitCount) from T_SiteVisit <br />
&nbsp;where datepart(year,VisitDate) = datepart(year,getdate())</font></p>
<font face="Verdana">
<p><br />
&nbsp;--最大日訪問數<br />
&nbsp;select top 1 @MaxVisitDay = convert(varchar,VisitCount) + '(' + <br />
&nbsp;convert(varchar,VisitDate,111) + ')' from T_SiteVisit order by VisitCount desc <br />
&nbsp;</p>
<p>&nbsp;--最大月訪數<br />
&nbsp;select top 1 @MaxVisitMonth = convert(varchar,MonthVisit) + '(' + Date + ')'<br />
&nbsp;from (<br />
&nbsp;select&nbsp; MonthVisit = sum(VisitCount),<br />
&nbsp;Date = convert(varchar,datepart(year,VisitDate)) + '/' + convert(varchar,datepart(month,VisitDate))<br />
&nbsp;&nbsp;&nbsp; from T_SiteVisit <br />
&nbsp;group by&nbsp; convert(varchar,datepart(year,VisitDate)) + '/' + convert(varchar,datepart(month,VisitDate))<br />
&nbsp;) T order by&nbsp; MonthVisit desc </p>
<p>&nbsp;--最大年訪數<br />
&nbsp;select top 1 @MaxVisitYear = convert(varchar,YearVisit) + '(' + Date + ')' <br />
&nbsp;from (<br />
&nbsp;select&nbsp; YearVisit = sum(VisitCount),<br />
&nbsp;Date = convert(varchar,datepart(year,VisitDate)) from T_SiteVisit <br />
&nbsp;group by&nbsp; datepart(year,VisitDate)<br />
&nbsp;) T order by YearVisit desc </p>
<p>&nbsp;select <br />
&nbsp;FirstDate = @FirstDate, <br />
&nbsp;Today = @Today,<br />
&nbsp;ThisDayVisit = @ThisDayVisit,<br />
&nbsp;ThisMonthVisit = @ThisMonthVisit,<br />
&nbsp;ThisYearVisit = @ThisYearVisit,<br />
&nbsp;AvgDayVisit = @AvgDayVisit,<br />
&nbsp;AvgMonthVisit = @AvgMonthVisit,<br />
&nbsp;AvgYearVisit = @AvgYearVisit,&nbsp;<br />
&nbsp;MaxVisitDay = @MaxVisitDay,<br />
&nbsp;MaxVisitMonth = @MaxVisitMonth,<br />
&nbsp;MaxVisitYear = @MaxVisitYear,<br />
&nbsp;VisitCount = @VisitCount</p>
<p>&nbsp;select&nbsp; No = row_number()over(order by T.MenuID),T.*&nbsp; from (<br />
&nbsp;select distinct T1.MenuID,<br />
&nbsp;SitePathName = dbo.F_GetSiteNameByMenuID(T1.MenuID),<br />
&nbsp;ThisMonthVisit = T3.VisitCount,<br />
&nbsp;VisitCount = T2.VisitCount from T_UnitVisit<br />
&nbsp;T1 inner join <br />
&nbsp;(<br />
&nbsp;&nbsp;select MenuID,VisitCount=sum(VisitCount) from T_UnitVisit group by MenuID <br />
&nbsp;) T2 on T1.MenuID = T2.MenuID<br />
&nbsp;inner join <br />
&nbsp;(<br />
&nbsp;&nbsp;select MenuID,VisitCount=sum(VisitCount) from T_UnitVisit <br />
&nbsp;&nbsp;where datepart(year,VisitDate) = datepart(year,getdate()) and <br />
&nbsp;&nbsp;datepart(month,VisitDate) = datepart(month,getdate())<br />
&nbsp;&nbsp;group by&nbsp; MenuID,<br />
&nbsp;&nbsp;datepart(year,VisitDate),<br />
&nbsp;&nbsp;datepart(month,VisitDate)<br />
&nbsp;) T3 on T1.MenuID = T3.MenuID<br />
&nbsp;)T<br />
&nbsp;order by T.MenuID<br />
&nbsp;<br />
end<br />
<br />
表結构如下：<font face="Verdana"><br />
/****** 物件:&nbsp; Table [dbo].[T_SiteVisit]&nbsp;&nbsp;&nbsp; 指令碼日期: 05/20/2008 11:17:59 ******/<br />
SET ANSI_NULLS ON<br />
GO<br />
SET QUOTED_IDENTIFIER ON<br />
GO<br />
CREATE TABLE [dbo].[T_SiteVisit](<br />
&nbsp;[VisitId] [int] IDENTITY(1,1) NOT NULL,<br />
&nbsp;[VisitDate] [datetime] NOT NULL,<br />
&nbsp;[VisitCount] [int] NOT NULL CONSTRAINT [DF_T_SiteVisit_VisitCount]&nbsp; DEFAULT ((0)),<br />
&nbsp;CONSTRAINT [PK_T_SiteVisit] PRIMARY KEY CLUSTERED <br />
(<br />
&nbsp;[VisitId] ASC<br />
)WITH (PAD_INDEX&nbsp; = OFF, STATISTICS_NORECOMPUTE&nbsp; = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS&nbsp; = ON, ALLOW_PAGE_LOCKS&nbsp; = ON) ON [PRIMARY]<br />
) ON [PRIMARY]<br />
</font></font></p>
<img src ="http://www.cnblogs.com/Harlan/aggbug/1203218.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/42933/" 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>如何讓 Lynx 純文字瀏覽器讀取 UTF-8 的 ASP.NET 網頁 </title><link>http://www.cnblogs.com/Harlan/archive/2008/05/19/1202317.html</link><dc:creator>Harlan---</dc:creator><author>Harlan---</author><pubDate>Mon, 19 May 2008 01:00:00 GMT</pubDate><guid>http://www.cnblogs.com/Harlan/archive/2008/05/19/1202317.html</guid><wfw:comment>http://www.cnblogs.com/Harlan/comments/1202317.html</wfw:comment><comments>http://www.cnblogs.com/Harlan/archive/2008/05/19/1202317.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnblogs.com/Harlan/comments/commentRss/1202317.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/Harlan/services/trackbacks/1202317.html</trackback:ping><description><![CDATA[<p><strong>需求 for 身心障礙同胞</strong> </p>
<blockquote>
<p>在國內卻有許多身心障礙同胞使用 Lynx 這套軟體，最近因為我們公司正在積極建置一個無障礙的網站，光是想到 UTF-8 編碼的網頁無法讓這些身心障礙同胞使用到我們製作的網站服務，就覺得內心實在有股衝動想趕快解決這個問題！ </p>
</blockquote>
<p><strong>需求 for 製作無障礙網站的 ASP.NET 2.0 開發人員</strong> </p>
<blockquote>
<p>我想大多數 ASP.NET 開發人員不懂 Linux 作業系統，唯一能使用 Lynx 軟體測試的方式，就是在 Windows 主機上使用 <a title="Cygwin (另開視窗)" href="http://www.cygwin.com/" target="_blank">Cygwin<img class="snap_preview_icon" id="snap_com_shot_link_icon" style="border-top-width: 0px; padding-right: 0px; background-position: -799px 0px; display: inline; padding-left: 0px; font-weight: normal; border-left-width: 0px; min-height: 0px; left: auto; float: none; background-image: url(http://i.ixnp.com/images/v3.30/theme/green/palette.gif); visibility: visible; border-bottom-width: 0px; padding-bottom: 0px; margin: 0px; vertical-align: top; width: 14px; line-height: normal; padding-top: 1px; background-repeat: no-repeat; font-style: normal; font-family: 'trebuchet ms', arial, helvetica, sans-serif; position: static; top: auto; height: 12px; background-color: transparent; border-right-width: 0px; text-decoration: none; maxheight: 2000px; maxwidth: 2000px; minwidth: 0px; cssfloat: none" src="http://i.ixnp.com/images/v3.30/t.gif"  alt="" /></a> + <a title="Lynx Information (另開視窗)" href="http://lynx.browser.org/" target="_blank">Lynx<img class="snap_preview_icon" id="snap_com_shot_link_icon" style="border-top-width: 0px; padding-right: 0px; background-position: -799px 0px; display: inline; padding-left: 0px; font-weight: normal; border-left-width: 0px; min-height: 0px; left: auto; float: none; background-image: url(http://i.ixnp.com/images/v3.30/theme/green/palette.gif); visibility: visible; border-bottom-width: 0px; padding-bottom: 0px; margin: 0px; vertical-align: top; width: 14px; line-height: normal; padding-top: 1px; background-repeat: no-repeat; font-style: normal; font-family: 'trebuchet ms', arial, helvetica, sans-serif; position: static; top: auto; height: 12px; background-color: transparent; border-right-width: 0px; text-decoration: none; maxheight: 2000px; maxwidth: 2000px; minwidth: 0px; cssfloat: none" src="http://i.ixnp.com/images/v3.30/t.gif"  alt="" /></a> 軟體進行測試，不過我今天研究出來一個最簡單、最容易、最省時省力的方式，讓你的 ASP.NET 網站伺服器看到使用 Lynx 上網的瀏覽者，就改以 BIG5 的方式回應輸出編碼字集！ </p>
</blockquote>
<p><strong>解決方案</strong> </p>
<blockquote>
<p>在 ASP.NET 2.0 新增了一個特殊的資料夾，叫做 App_Browsers，ASP.NET 會使用這些檔案來辨識個別瀏覽器並判斷它們的功能與應該回應的方式。 </p>
<p>你只要在你的 Web Application 根目錄建立這個目錄，並建立一個 Lynx.browser 檔案，檔案裡面的內容如下： </p>
<p>
<div class="code">[code:html]<br />
<span class="rem">&lt;!--</span> <span class="rem">&nbsp;&nbsp;&nbsp; You can find existing browser definitions at</span> <span class="rem">&nbsp;&nbsp;&nbsp; &lt;windir&gt;\Microsoft.NET\Framework\&lt;ver&gt;\CONFIG\Browsers</span> <span class="rem">--&gt;</span><br />
<span class="kwrd">&lt;</span><span class="html">browsers</span><span class="kwrd">&gt;</span><br />
&nbsp; <span class="kwrd">&lt;</span><span class="html">browser</span> <span class="attr">id</span><span class="kwrd">="Lynx"</span> <span class="attr">parentID</span><span class="kwrd">="Default"</span><span class="kwrd">&gt;</span><br />
&nbsp;&nbsp;&nbsp; <span class="kwrd">&lt;</span><span class="html">identification</span><span class="kwrd">&gt;</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="kwrd">&lt;</span><span class="html">userAgent</span> <span class="attr">match</span><span class="kwrd">="Lynx/\d+\.\d+"</span> <span class="kwrd">/&gt;</span><br />
&nbsp;&nbsp;&nbsp; <span class="kwrd">&lt;/</span><span class="html">identification</span><span class="kwrd">&gt;</span><br />
&nbsp;&nbsp;&nbsp; <span class="kwrd">&lt;</span><span class="html">capture</span><span class="kwrd">&gt;</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="kwrd">&lt;</span><span class="html">userAgent</span> <span class="attr">match</span><span class="kwrd">="Lynx/(?'version'(?'browserMajorVersion'\d+)\.(?'browserMinorVersion'\d+))"</span> <span class="kwrd">/&gt;</span><br />
&nbsp;&nbsp;&nbsp; <span class="kwrd">&lt;/</span><span class="html">capture</span><span class="kwrd">&gt;</span><br />
&nbsp;&nbsp;&nbsp; <span class="kwrd">&lt;</span><span class="html">capabilities</span><span class="kwrd">&gt;</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="kwrd">&lt;</span><span class="html">capability</span> <span class="attr">name</span><span class="kwrd">="browser"</span> <span class="attr">value</span><span class="kwrd">="Lynx"</span> <span class="kwrd">/&gt;</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="kwrd">&lt;</span><span class="html">capability</span> <span class="attr">name</span><span class="kwrd">="version"</span> <span class="attr">value</span><span class="kwrd">="${version}"</span> <span class="kwrd">/&gt;</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="kwrd">&lt;</span><span class="html">capability</span> <span class="attr">name</span><span class="kwrd">="majorVersion"</span> <span class="attr">value</span><span class="kwrd">="${browserMajorVersion}"</span> <span class="kwrd">/&gt;</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="kwrd">&lt;</span><span class="html">capability</span> <span class="attr">name</span><span class="kwrd">="minorVersion"</span> <span class="attr">value</span><span class="kwrd">="${browserMinorVersion}"</span> <span class="kwrd">/&gt;</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="kwrd">&lt;</span><span class="html">capability</span> <span class="attr">name</span><span class="kwrd">="preferredRequestencoding"</span> <span class="attr">value</span><span class="kwrd">="big5"</span> <span class="kwrd">/&gt;</span><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="kwrd">&lt;</span><span class="html">capability</span> <span class="attr">name</span><span class="kwrd">="preferredResponseencoding"</span> <span class="attr">value</span><span class="kwrd">="big5"</span> <span class="kwrd">/&gt;</span><br />
&nbsp;&nbsp;&nbsp; <span class="kwrd">&lt;/</span><span class="html">capabilities</span><span class="kwrd">&gt;</span><br />
&nbsp; <span class="kwrd">&lt;/</span><span class="html">browser</span><span class="kwrd">&gt;</span><br />
<span class="kwrd">&lt;/</span><span class="html">browsers</span><span class="kwrd">&gt;</span><br />
[/code]</div>
<p>&nbsp;</p>
<p><br />
<strong>夠簡單吧！</strong>這要照這樣子做，你的網站只要遇到 Lynx Browser 上網，馬上就可以「自動」變成 Big5 編碼摟！ <strong>真心感謝 ASP.NET 這個漂亮的 Web 開發架構！</strong> </p>
</blockquote>
<p><strong>注意事項</strong> </p>
<ul>
    <li>
    <div>如果在你的網頁中有使用到以下這個 meta 標籤，請將他移除：<br />
    <br />
    <div class="code">[code:html]<br />
    <span class="kwrd">&lt;</span><span class="html">meta</span> <span class="attr">http-equiv</span><span class="kwrd">="Content-Type"</span> <span class="attr">content</span><span class="kwrd">="text/html; charset=utf-8"</span><span class="kwrd">&gt;</span><br />
    [/code]</div>
    <br />
    </div>
    <li>
    <div>並將以下的程式碼加到你的 MasterPage 或 Page 的 Code Behind 的 Page_Load 事件中：<br />
    <br />
    <div class="code">[code:c#]<br />
    <span class="kwrd">public</span> <span class="kwrd">partial</span> <span class="kwrd">class</span> MasterPage : System.Web.UI.MasterPage<br />
    {<br />
    &nbsp;&nbsp;&nbsp; <span class="kwrd">protected</span> <span class="kwrd">void</span> Page_Load(<span class="kwrd">object</span> sender, EventArgs e)<br />
    &nbsp;&nbsp;&nbsp; {<br />
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; HtmlMeta metaContentType = <span class="kwrd">new</span> HtmlMeta();<br />
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; metaContentType.HttpEquiv = "Content-Type";<br />
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="kwrd">if</span> (Request.Browser.Browser == "Lynx")<br />
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; metaContentType.Content = "text/html; charset=big5";<br />
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span class="kwrd">else</span><br />
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; metaContentType.Content = "text/html; charset=utf-8";<br />
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />
    &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Page.Header.Controls.AddAt(0, metaContentType);<br />
    &nbsp;&nbsp;&nbsp; }<br />
    }<br />
    [/code]</div>
    <br />
    </div>
    <li>
    <div>另外說明一下，如果你的網頁中的外部載入檔案 ( *.css 或 *.js ) 的話，如果檔案是用 UTF-8 編碼且內容中有非 ASCII 的字元，也有可能在使用 big5 瀏覽時造成網頁發生問題！但 Lynx 本來就不支援 CSS 與 JavaScript，所以也沒這個問題啦！但誰知道以後的 Lynx 版本會不會支援這些功能！</div>
    </li>
</ul>
<img src ="http://www.cnblogs.com/Harlan/aggbug/1202317.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/42932/" 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>WCF开发入门的六个步骤</title><link>http://www.cnblogs.com/Harlan/archive/2008/05/17/1200920.html</link><dc:creator>Harlan---</dc:creator><author>Harlan---</author><pubDate>Sat, 17 May 2008 11:39:00 GMT</pubDate><guid>http://www.cnblogs.com/Harlan/archive/2008/05/17/1200920.html</guid><wfw:comment>http://www.cnblogs.com/Harlan/comments/1200920.html</wfw:comment><comments>http://www.cnblogs.com/Harlan/archive/2008/05/17/1200920.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnblogs.com/Harlan/comments/commentRss/1200920.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/Harlan/services/trackbacks/1200920.html</trackback:ping><description><![CDATA[在这里我就用一个据于一个简单的场景：服务端为客服端提供获取客户信息的一个接口读取客户信息，来完成WCF开发入门的六个步骤。 <br />
1.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 定义WCF服务契约
<p>A.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 项目引用节点右键添加System.ServiceModel引用。</p>
<p>B.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 在代码文件里，添加以下命名空间的引用</p>
<p>using System.ServiceModel;</p>
<p>using System;</p>
<p>C.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 新建一个命为ICustomerService 接口，并添加一个获取客户信息的方法定义名为CustomerInfomation,返回字符串类型的客户信息。</p>
<p>D.&nbsp;&nbsp;&nbsp;&nbsp; 为接口ICustomerService添加ServiceContract的属性修饰使它成为WCF服务中公开的接口。 </p>
<p>E.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 为方法CustomerInfomation添加OperationContract的属性修饰使它成为WCF服务公开接口中公开的成员。</p>
<p>F.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 代码：</p>
<p><br />
&nbsp;1 using System;<br />
&nbsp;2 <br />
&nbsp;3 using System.ServiceModel;<br />
&nbsp;4 <br />
&nbsp;5 namespace ConWCF<br />
&nbsp;6 <br />
&nbsp;7 {&nbsp;&nbsp; [ServiceContract(Namespace = "<a href="http://microsoft.servicemodel.samples/">http://microsoft.servicemodel.samples/</a>")]<br />
&nbsp;8 <br />
&nbsp;9&nbsp;&nbsp;&nbsp;&nbsp; public interface CustomerService<br />
10 <br />
11&nbsp;&nbsp;&nbsp;&nbsp; { <br />
12 <br />
13&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [OperationContract]<br />
14 <br />
15&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String CustomerInformation();<br />
16 <br />
17&nbsp;&nbsp;&nbsp;&nbsp; }<br />
18 <br />
19 }<br />
20 </p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>2.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 实现WCF服务契约 <br />
&nbsp;</p>
<p>实现WCF服务契约很简单，就是实现上一步聚定义的WCF服务契约定义的接口就可以。下面看代码</p>
<p><br />
&nbsp;1 using System;<br />
&nbsp;2 <br />
&nbsp;3 using System.ServiceModel;<br />
&nbsp;4 <br />
&nbsp;5 namespace ConWCF<br />
&nbsp;6 <br />
&nbsp;7 {&nbsp;&nbsp; [ServiceContract(Namespace = "<a href="http://microsoft.servicemodel.samples/">http://microsoft.servicemodel.samples/</a>")]<br />
&nbsp;8 <br />
&nbsp;9&nbsp;&nbsp;&nbsp;&nbsp; public interface ICustomerService<br />
10 <br />
11&nbsp;&nbsp;&nbsp;&nbsp; { <br />
12 <br />
13&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; [OperationContract]<br />
14 <br />
15&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; String CustomerInformation();<br />
16 <br />
17&nbsp;&nbsp;&nbsp;&nbsp; }<br />
18 <br />
19&nbsp;&nbsp;&nbsp;&nbsp; public class CustomerService:ICustomerService<br />
20 <br />
21&nbsp;&nbsp;&nbsp;&nbsp; {<br />
22 <br />
23&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #region ICustomerService 成员<br />
24 <br />
25&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; public string CustomerInformation()<br />
26 <br />
27&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; {<br />
28 <br />
29&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return "这是客户的信息!";<br />
30 <br />
31&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
32 <br />
33&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; #endregion<br />
34 <br />
35&nbsp;&nbsp;&nbsp;&nbsp; }<br />
36 <br />
37 }<br />
38 <br />
39 </p>
<p>&nbsp;</p>
<p>3.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 启动WCF服务</p>
<p>A．添加一个应用程序配置文件，文件件名为App.config。</p>
<p>B．配置WCF服务的基本地址,如下所示</p>
<p>&lt;host&gt;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;baseAddresses&gt;</p>
<p>&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;&nbsp; &lt;addbaseAddress="<a href='http://localhost:8000/conwcfr"/'>http://localhost:8000/conwcfr"/</a>&gt;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/baseAddresses&gt;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/host&gt;</p>
<p>C．配置WCF服务的端口。Address=&#8220;&#8221;，意思就是使用上面配置的基本地址，当然也可以在这里指定。Bingding=&#8220;wsHttpBinding&#8221;,意思是WCF服务使用的是HTTP协议。再接下来就是配置WCF服务契约了（命名空间.服务契约接口名），如下所示:</p>
<p>&lt;endpointaddress=""</p>
<p>&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;&nbsp;&nbsp; binding="wsHttpBinding"</p>
<p>&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;&nbsp;&nbsp; contract="ConWCF.ICustomerService" /&gt;</p>
<p>D．配置文件</p>
<p>E．启动服服就简单了</p>
<p>ServiceHost host = new ServiceHost(typeof(CustomerService));</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; host.Open();</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Console.WriteLine("客户信息服务已启动");</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Console.WriteLine("按任意键结束服务！");</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Console.Read();</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; host.Close();</p>
<p>F．当服务启动时，在IE栏中输入: <a href="http://localhost:8000/conwcfr">http://localhost:8000/conwcfr</a>,将会收到一些帮助的提示信息。</p>
<p><br />
G．异常：配置文件中的服务名称一定是：命名空间.实现WCF服务契约类的名称，否则将会发生找到不配置的异常。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;service</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; name="ConWCF.CustomerService"</p>
<p>&nbsp;&nbsp;&nbsp; 异常信息: Service 'ConWCF.CustomerService' has zero application (non-infrastructure) endpoints. This might be because no configuration file was found for your application, or because no service element matching the service name could be found in the configuration file, or because no endpoints were defined in the service element.</p>
<p>这个异常搞得我昏了半天，害得我以为从IIS、端口到配置环境排除错误,就是搞不明白为什么会跟类的命称联系起来。不过，最终也解决了。</p>
<p>4.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 创建一个基本的WCF客服端</p>
<p>WCF服务端创建好啊，创建客户端就容易多了，直接用SVCUTIL 命令行工具去完成代码的生成。我安装了WINDOWS SDK，其带了一个CMDShell 命令行工具，打开后就可以运行SVCUTIL命令，这个命令是运行于 framework 3.0以上环境。查看详细帮助信息可以输入:svcutil /?,回车。</p>
<p>1． 启动上几步骤创建好的WCF服务端。</p>
<p>2． 在CMDShell工具中用CD 转到你要存放客户端代码的目录下，输入以下命令生成代码和配置文件。</p>
<p>D:"client&gt;svcutil /language:c# /out:CustomerClient.cs /config:app.config http:/</p>
<p>/localhost:8000/conwcfr</p>
<p>上面命令指定了要生成代码的语言，代码文件和配置文件名，WCF服务端地址，注意运行命令时必须确定WCF服务端正在运行中。</p>
<p>5.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; WCF客服端基本配置</p>
<p>WCF客户端配置就是配置调用WCF服务端的协议，输传宽带，服务地址，安全等等信息。下面就上一步骤命令自动生成的配置文件。</p>
<p><br />
&nbsp;1 &lt;?xml version="1.0" encoding="utf-8"?&gt;<br />
&nbsp;2 &lt;configuration&gt;<br />
&nbsp;3&nbsp;&nbsp;&nbsp;&nbsp; &lt;system.serviceModel&gt;<br />
&nbsp;4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;bindings&gt;<br />
&nbsp;5&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;wsHttpBinding&gt;<br />
&nbsp;6&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;binding name="WSHttpBinding_ICustomerService" closeTimeout="00:01:00"<br />
&nbsp;7&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"<br />
&nbsp;8&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bypassProxyOnLocal="false" transactionFlow="false" hostNameComparisonMode="StrongWildcard"<br />
&nbsp;9&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; maxBufferPoolSize="524288" maxReceivedMessageSize="65536"<br />
10&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; messageEncoding="Text" textEncoding="utf-8" useDefaultWebProxy="true"<br />
11&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; allowCookies="false"&gt;<br />
12&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"<br />
13&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; maxBytesPerRead="4096" maxNameTableCharCount="16384" /&gt;<br />
14&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;reliableSession ordered="true" inactivityTimeout="00:10:00"<br />
15&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; enabled="false" /&gt;<br />
16&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;security mode="Message"&gt;<br />
17&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;transport clientCredentialType="Windows" proxyCredentialType="None"<br />
18&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;&nbsp;&nbsp; realm="" /&gt;<br />
19&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;message clientCredentialType="Windows" negotiateServiceCredential="true"<br />
20&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;&nbsp;&nbsp; algorithmSuite="Default" establishSecurityContext="true" /&gt;<br />
21&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/security&gt;<br />
22&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/binding&gt;<br />
23&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/wsHttpBinding&gt;<br />
24&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/bindings&gt;<br />
25&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;client&gt;<br />
26&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;endpoint address="<a href="http://localhost:8000/conwcfr">http://localhost:8000/conwcfr</a>" binding="wsHttpBinding"<br />
27&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; bindingConfiguration="WSHttpBinding_ICustomerService" contract="ICustomerService"<br />
28&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; name="WSHttpBinding_ICustomerService"&gt;<br />
29&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;identity&gt;<br />
30&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;userPrincipalName value="30DA1D0B1D1E4D2\Administrator" /&gt;<br />
31&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/identity&gt;<br />
32&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/endpoint&gt;<br />
33&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;/client&gt;<br />
34&nbsp;&nbsp;&nbsp;&nbsp; &lt;/system.serviceModel&gt;<br />
35 &lt;/configuration&gt;</p>
<p>&nbsp;</p>
<p>6.&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 使用WCF客户端</p>
<p>在客户端项目中项目引用节点右键添加System.ServiceModel引用. <br />
添加第四部中创建的客户端代码文件和配置文件。 <br />
客户端调用服务端的服务，只要创建生成客户端类的实例就可调用了，但要确认服务端正在起用状态，如下 <br />
&nbsp;</p>
<p>&nbsp;1using System;<br />
&nbsp;2<br />
&nbsp;3namespace ConWCFCustomerClient<br />
&nbsp;4<br />
&nbsp;5{<br />
&nbsp;6<br />
&nbsp;7&nbsp;&nbsp;&nbsp; class Program<br />
&nbsp;8<br />
&nbsp;9&nbsp;&nbsp;&nbsp; {<br />
10<br />
11&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; static void Main(string[] args)<br />
12<br />
13&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; { <br />
14<br />
15&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; CustomerServiceClient client = new CustomerServiceClient();<br />
16<br />
17&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; string message=client.CustomerInformation();<br />
18<br />
19&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Console.WriteLine(message);<br />
20<br />
21&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Console.Read();<br />
22<br />
23&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />
24<br />
25&nbsp;&nbsp;&nbsp; }<br />
26<br />
27}<br />
28//來自：<font face="Verdana">http://blog.csdn.net/mych/archive/2008/05/15/2448809.aspx</font></p>
 <img src ="http://www.cnblogs.com/Harlan/aggbug/1200920.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/42931/" target="_blank">[新闻]百度C2C电子商务平台“有啊”youa.com上线</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/Harlan/archive/2008/05/16/1200653.html</link><dc:creator>Harlan---</dc:creator><author>Harlan---</author><pubDate>Fri, 16 May 2008 06:59:00 GMT</pubDate><guid>http://www.cnblogs.com/Harlan/archive/2008/05/16/1200653.html</guid><wfw:comment>http://www.cnblogs.com/Harlan/comments/1200653.html</wfw:comment><comments>http://www.cnblogs.com/Harlan/archive/2008/05/16/1200653.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cnblogs.com/Harlan/comments/commentRss/1200653.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/Harlan/services/trackbacks/1200653.html</trackback:ping><description><![CDATA[<h3>4.1.2&nbsp; SQL查询技术</h3>
<p>最常用的关系数据库系统通过称为SQL的语言对数据库进行查询和更新。SQL的含义是&#8220;结构化查询语言（Structured Query Language）&#8221;。SQL中最简单的查询就是从某个关系中查找满足某种条件的一些元组。这种查询类似于关系代数中的选择。这种简单的查询，同几乎所有的SQL查询一样，使用了具有SQL特性的三个关键字：SELECT、FROM以及WHERE。</p>
<h4>1．SELECT检索数据</h4>
<p>在许多方面，查询都是SQL语言的中心内容，而用于表示SQL查询的SELECT语句，是SQL语句中功能最强大也是最复杂的。</p>
<p>SELECT语句的作用是让数据库服务器根据客户的要求搜索出所需要的信息，并按规定的格式进行整理，再返回给客户端，SELECT语句的完整结构如下：</p>
<p>SELECT statement ::=</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&lt; query_expression &gt;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;[ ORDER BY { order_by_expression | column_position [ ASC | DESC ] }</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[ ,...n ]&nbsp;&nbsp;&nbsp;&nbsp;]</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;[ COMPUTE</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;{ { AVG | COUNT | MAX | MIN | SUM } ( expression ) } [ ,...n ]</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[ BY expression [ ,...n ] ]</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;]</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;[ FOR { BROWSE | XML { RAW | AUTO | EXPLICIT }</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[ , XMLDATA ]</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[ , ELEMENTS ]</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[ , BINARY base64 ]</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp; ]</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;[ OPTION ( &lt; query_hint &gt; [ ,...n ]) ] </p>
<p>&lt; query expression &gt; ::=</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;{ &lt; query specification &gt; | ( a&lt; query expression &gt; ) }</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;[ UNION [ ALL ] &lt; query specification | ( &lt; query expression &gt; ) [...n ] ]</p>
<p>&lt; query specification &gt; ::=</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;SELECT [ ALL | DISTINCT ]</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[ { TOP integer | TOP integer PERCENT } [ WITH TIES ] ]</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&lt; select_list &gt;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;[ INTO new_table ]</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;[ FROM { &lt; table_source &gt; } [ ,...n ] ]</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;[ WHERE &lt; search_condition &gt; ]</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;[ GROUP BY [ ALL ] group_by_expression [ ,...n ]</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[ WITH { CUBE | ROLLUP } ]</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;]</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;[HAVING &lt;search_condition&gt;]</p>
<p>上述语法较复杂，这里只须掌握SELECT语句的一部分，就可以完成对数据库的查询操作，SELECT语句中的主要子句归纳如下：</p>
<p>SELECT select_list</p>
<p>[ INTO new_table ]</p>
<p>FROM table_source</p>
<p>[ WHERE search_condition ]</p>
<p>[ GROUP BY group_by_expression ]</p>
<p>[ HAVING search_condition ]</p>
<p>[ ORDER BY order_expression [ASC| DESC ]]</p>
<p>参数：</p>
<p>select_list：指定由查询返回的列。它是一个逗号分隔的表达式列表。每个表达式同时定义格式（数据类型和大小）和结果集列的数据来源。每个选择列表表达式通常是对从中获取数据的源表或视图的列的引用，但也可能是其它表达式，例如常量或T-SQL函数。在选择列表中使用 * 表达式指定返回源表中的所有列。</p>
<p>INTO new_table_name：创建新表并将查询行从查询插入新表中。new_table_name 指定新表的名称。</p>
<p>FROM&nbsp; table_list：指定从其中检索行的表。这些来源可能包括：基表、视图和链接表。FROM子句还可包含联接说明，该说明定义了 SQL Server用来在表之间进行导航的特定路径。FROM子句还用在DELETE和UPDATE 语句中以定义要修改的表。</p>
<p>WHERE &nbsp;search_conditions：WHERE子句指定用于限制返回的行的搜索条件。WHERE 子句还用在 DELETE 和 UPDATE 语句中以定义目标表中要修改的行。</p>
<p>GROUP BY group_by_list：GROUP BY子句根据 group_by_list 列中的值将结果集分成组。例如，student 表在 &#8220;性别&#8221; 中有两个值。GROUP BY ShipVia 子句将结果集分成两组，每组对应于ShipVia 的一个值。</p>
<p>HAVING search_conditions：HAVING子句是指定组或聚合的搜索条件。逻辑上讲，HAVING 子句从中间结果集对行进行筛选，这些中间结果集是用 SELECT 语句中的 FROM、WHERE 或 GROUP BY 子句创建的。HAVING 子句通常与 GROUP BY 子句一起使用，尽管HAVING 子句前面不必有 GROUP BY 子句。</p>
<p>ORDER BY order_list [ ASC | DESC ]：ORDER BY 子句定义结果集中的行排列的顺序。order_list 指定组成排序列表的结果集的列。ASC 和 DESC 关键字用于指定行是按升序还是按降序排序。ORDER BY 之所以重要，是因为关系理论规定除非已经指定 ORDER BY，否则不能假设结果集中的行带有任何序列。如果结果集行的顺序对于SELECT 语句来说很重要，那么在该语句中就必须使用ORDER BY子句。</p>
<p>例如显示course表的所有记录。在查询分析器中输入SQL语句如下：</p>
<p>use student</p>
<p>select&nbsp; *&nbsp; </p>
<p>from&nbsp; course</p>
<p>SELECT子句指定要查询的列。这些列通常被一个选择列表指定，选择列表是中间用逗号分开的选择项列表。选择项可以是字段名、常量、SQL表达式。下面是SELECT子句的语法：</p>
<p>SELECT [ ALL | DISTINCT ]</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;[ TOP n [ PERCENT ] [ WITH TIES ] ]</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&lt; select_list &gt;</p>
<p>&lt; select_list &gt; ::=</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;*</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;| { table_name | view_name | table_alias }.*</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;| &nbsp;&nbsp;&nbsp;&nbsp;{ column_name | expression | IDENTITYCOL | ROWGUIDCOL }</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[ [ AS ] column_alias ]</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;| column_alias = expression</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;</p>
<p>&nbsp;[ ,...n ]</p>
<p>参数：</p>
<p>ALL：指定在结果集中可以显示重复行。ALL是默认设置。</p>
<p>DISTINCT：去掉重复记录。</p>
<p>TOP n [PERCENT]：指定只从查询结果集中输出前n行。n是介于0和4294967295之间的整数。如果还指定了PERCENT，则只从结果集中输出前百分之n行。当指定时带PERCENT时，n必须是介于0~00之间的整数。如果查询包含ORDER BY子句，将输出由ORDER BY子句排序的前n行（或前百分之n行）。如果查询没有ORDER BY子句，行的顺序任意。</p>
<p>WITH TIES：指定从基本结果集中返回附加的行，这些行包含与出现在TOP n (PERCENT)行最后的ORDER BY列中的值相同的值。如果指定了ORDER BY子句，则只能指定TOP ...WITH TIES。</p>
<p>select_list ：为结果集选择的列。选择列表是以逗号分隔的一系列表达式。</p>
<p>* 指定在FROM子句内返回表和视图内的所有列。列按FROM子句所指定的表或视图，按他们在表或视图中的顺序返回，table_name | view_name | table_alias.*将*的作用域限制为指定的表或视图。</p>
<p>column_name：是要返回的列名。限定column_name以避免二义性引用，当FROM子句中的两个表内有包含重复名的列时会出现这种情况。</p>
<p>expression：是列名、常量、函数以及由运算符连接的列名、常量和函数的任意组合，或者是子查询。</p>
<p>IDENTITYCOL：返回标识列。</p>
<p>ROWGUIDCOL：返回行全局惟一标识列。如果在FROM子句中有多个表具有ROWGUIDCOL属性，则必须用特定的表名（如T1.ROWGUIDCOL）限定 ROWGUIDCOL。</p>
<p>column_alias：是查询结果集内替换列名的可选名。别名还可用于为表达式结果指定名称。</p>
<h4>2．FROM子句</h4>
<p>对于每个SELECT子句，FROM子句是强制性的。FROM子句主要用来指定检索数据的来源，数据的来源可以是若干个表或视图，数据表之间或视图名之间用逗号分隔。下面是FROM子句的语法：</p>
<p>[ FROM { &lt; table_source &gt; } [ ,...n ] ]</p>
<p>&lt; table_source &gt; ::=</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;table_name [ [ AS ] table_alias ] [ WITH ( &lt; table_hint &gt; [ ,...n ] ) ]</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;| view_name [ [ AS ] table_alias ] [ WITH ( &lt; view_hint &gt; [ ,...n ] ) ]</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;| rowset_function [ [ AS ] table_alias ]</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;| user_defined_function [ [ AS ] table_alias ]</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;| derived_table [ AS ] table_alias [ ( column_alias [ ,...n ] ) ]</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;| &lt; joined_table &gt;</p>
<p>&lt; joined_table &gt; ::=</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&lt; table_source &gt; &lt; join_type &gt; &lt; table_source &gt; ON &lt; search_condition &gt;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;| &lt; table_source &gt; CROSS JOIN &lt; table_source &gt;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;| [ ( ] &lt; joined_table &gt; [ ) ]</p>
<p>&lt; join_type &gt; ::=</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;[ INNER | { { LEFT | RIGHT | FULL } [OUTER] } ]</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;[ &lt; join_hint &gt; ]</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;JOIN&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </p>
<p>参数说明：</p>
<p>table_source ：指定要在 Transact-SQL语句中使用的表或视图（带或不带别名均可）。可在语句中使用多达 256 个表。可将table 变量指定为表源。如果表或视图存在于同一台运行Microsoft&#174; SQL Server&#8482;的计算机的其它数据库中，应按格式 database.owner.object_name 使用完全合法的名称。如果表或视图存在于本地服务器之外的一台链接的服务器上，应按以下格式使用由四部分组成的名称：linked_server.catalog.schema.object。如果由四部分构造的表（或视图）名称使用OPENDATASOURCE 函数作为名称中的服务器部分，则该名称也可用于指定表源。</p>
<p>table_name：表名。FROM 关键字之后的表和视图的顺序并不影响返回的结果集。当 FROM子句中出现重复名称时将报告错误。</p>
<p>&nbsp;[AS] table_alias：table_name、view_name 或 rowset_function 的别名，为方便起见而使用，或用于区分自联接或子查询中的表或视图。别名通常是一个缩短了的表名，用于在联接中引用表中的特定列。如果联接中的多个表中有相同名称的列存在，SQL Server 要求必须使用表名或别名来限定列名。（如果定义了别名则不能使用表名）。</p>
<p>WITH ( &lt; table_hint &gt; )：指定表扫描、查询优化器要使用的一个或多个索引或查询优化器要对此表、此语句使用的锁定方法。</p>
<p>view_name：是视图名称。视图是一个"虚拟表"，通常创建为一个或多个表中列的子集。</p>
<p>WITH ( &lt; view_hint &gt; )：指定索引视图扫描。默认情况下，视图在查询优化器处理查询之前展开。视图提示只能用在 SELECT 语句中，而不能用于 UPDATE、DELETE 或 INSERT 语句。</p>
<p>rowset_function：指定一个行集函数，该函数返回可替代表引用的对象。</p>
<p>user_defined_function：指定用户定义的函数，该函数返回一个表。如果用户定义的函数是一个内置的用户定义函数，则前面必须加两个冒号，如：FROM&nbsp; fn_listextendedproperty：derived_table是从数据库中检索行的子查询。derived_table 用作对外部查询的输入。</p>
<p>column_alias：替换结果集内列名的可选别名。在选择列表中放入每个列的一个别名，并将整个列别名列表用圆括号括起来。</p>
<p>joined_table：由两个或更多表的积组成的结果集。对于多个 CROSS 联接，请使用圆括号来更改联接的自然顺序。</p>
<p>join_type：指定联接操作的类型。</p>
<p>INNER：指定返回每对匹配的行。废弃两个表中不匹配的行。如果未指定联接类型，则这是默认设置。</p>
<p>FULL [OUTER]：指定在结果集中包含左表或右表中不满足联接条件的行，并将对应于另一个表的输出列设为NULL。这是对通常由 INNER JOIN 返回的所有行的补充。说明按此处指定的方法指定外联接或在 WHERE 子句中使用旧式非标准的 *= 和 =* 运算符都是可行的。不能在同一语句中同时使用这两种方法。</p>
<p>LEFT [OUTER]：指定在结果集中包含左表中所有不满足联接条件的行，且在由内联接返回所有的行之外，将另外一个表的输出列设为NULL。</p>
<p>RIGHT [OUTER]：指定在结果集中包含右表中所有不满足联接条件的行，且在由内联接返回的所有行之外，将与另外一个表对应的输出列设为NULL。</p>
<p>join_hint：指定SQL Server查询优化器为在查询的FROM子句中指定的每个联接使用一个联接提示或执行算法。</p>
<p>JOIN：指明所指定的联接操作应在给定的表或视图之间执行。</p>
<p>ON &lt;search_condition&gt;：指定联接所基于的条件。尽管经常使用列和比较运算符，但此条件可指定任何谓词。</p>
<p>（1）从表和视图中选择</p>
<p>例如：查询course表的信息，在查询分析器中输入SQL语句如下：</p>
<p>use student</p>
<p>select&nbsp; *&nbsp; from&nbsp; course&nbsp; </p>
<p>例如：查询用户建的视图newview的信息，在查询分析器中输入SQL语句如下：</p>
<p>select&nbsp; *&nbsp; from&nbsp; newview&nbsp; </p>
<p>其中，course是表的名称；newview是视图的名称。</p>
<p>（2）列以表的名称作为前缀</p>
<p>由于FROM子句指定的数据源可以是多个表，列名可能会有重复的，所以对不同的子句中的列以表的名称作为前缀也使它变得更为直观。这样就可以帮助消除当两个或更多个表有相同的列名时所引起的混乱。</p>
<p>例如：查询显示student表和grade表中的几个列，在查询分析器中输入SQL语句如下：</p>
<p>use student</p>
<p>select&nbsp; students.学号,</p>
<p>studnet.姓名,grade.学号,grade.课程成绩&nbsp;&nbsp; </p>
<p>from&nbsp; students,grade</p>
<p>列以表的名称作为前缀主要用于多个表连接。为了直观，即使有一个表，其中的列也可以用表的名称作为前缀。</p>
<p>例如：查询course表中所有列的信息，在查询分析器中输入SQL语句如下：</p>
<p>use&nbsp; student </p>
<p>select&nbsp; course.*&nbsp; from&nbsp; course </p>
<p>（3）在一个FROM子句中使用子查询</p>
<p>在FROM子句中使用一个子查询的结果作为查询的源表，同时也可以给源表起一个别名。</p>
<p>例如：在students数据库中，查询course表作为子查询并起别名为a，然后再查询别名是a的表中某些列。在查询分析器中输入SQL语句如下：</p>
<p>use student </p>
<p>select a.课程代号,a.课程内容&nbsp; from &nbsp;(select * &nbsp;from&nbsp; course&nbsp; ) &nbsp;a </p>
<h4>3．WHERE子句</h4>
<p style="text-indent: 20pt">WHERE子句是用来选取需要检索的记录。因为一个表通常会有数千条记录，在查询结果中，用户仅需其中的一部分记录，这时需要使用WHERE子句指定一系列的查询条件。下面是WHERE子句最简单的语法：</p>
<p>SELECT&lt;字段列表&gt;</p>
<p>FROM&lt;表名&gt;</p>
<p>WHERE&lt;条件表达式&gt;</p>
<p style="text-indent: 20pt">例如：在students表中，查询年龄&gt;20的学生，在查询分析器中输入SQL语句如下：</p>
<p>use student</p>
<p>select * </p>
<p>from&nbsp; students </p>
<p>where&nbsp; 年龄&gt;20</p>
<p style="text-indent: 20pt">为了实现许多不同种类的查询，WHERE子句提供了丰富的搜索条件，下面总结了5个基本的搜索条件。</p>
<p style="margin-left: 21.25pt; text-indent: 0cm">① 比较运算符（如=、&lt;&gt;、&lt;和&gt;）。</p>
<p style="margin-left: 21.25pt; text-indent: 0cm">② 范围说明（BETWEEN 和 NOT BETWEEN）。</p>
<p style="margin-left: 21.25pt; text-indent: 0cm">③ 可选值列表（IN和NOT&nbsp; IN）。</p>
<p style="margin-left: 21.25pt; text-indent: 0cm">④ 模式匹配（LIKE和NOT LIKE）。</p>
<p style="margin-left: 21.25pt; text-indent: 0cm">⑤ 上述条件的逻辑组合（AND、OR、NOT）。</p>
<p style="text-indent: 20pt">（1）比较查询条件</p>
<p>比较查询条件由比较运算符连接表达式组成，系统将根据该查询条件的真假来决定某一条记录是否满足该查询条件，只有满足该查询条件的记录才会出现在最终的结果集中。SQL Server比较运算符如表4.1所示 。</p>
<p>表4.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;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 比较运算符及其说明</p>
<div align="center">
<table style="width: 419.6pt; border-top-style: none; border-right-style: none; border-left-style: none; border-collapse: collapse; border-bottom-style: none" cellspacing="0" cellpadding="0" width="559" border="1">
    <tbody>
        <tr style="height: 16.75pt">
            <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: windowtext 1pt solid; padding-left: 5.4pt; border-left-width: 1pt; border-left-color: windowtext; padding-bottom: 0cm; width: 68pt; padding-top: 0cm; border-bottom: windowtext 1pt solid; height: 16.75pt" width="91">
            <p>运算符</p>
            </td>
            <td style="padding-right: 5.4pt; border-top: windowtext 1pt solid; padding-left: 5.4pt; padding-bottom: 0cm; width: 351.6pt; padding-top: 0cm; border-bottom: windowtext 1pt solid; border-right-style: none; border-left-style: none; height: 16.75pt" width="469">
            <p>说明</p>
            </td>
        </tr>
        <tr style="height: 16.75pt">
            <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; padding-left: 5.4pt; padding-bottom: 0cm; width: 68pt; border-top-style: none; padding-top: 0cm; border-bottom: windowtext 1pt solid; border-left-style: none; height: 16.75pt" width="91">
            <p>=</p>
            </td>
            <td style="padding-right: 5.4pt; padding-left: 5.4pt; padding-bottom: 0cm; width: 351.6pt; border-top-style: none; padding-top: 0cm; border-bottom: windowtext 1pt solid; border-right-style: none; border-left-style: none; height: 16.75pt" width="469">
            <p>等于</p>
            </td>
        </tr>
        <tr style="height: 16.75pt">
            <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; padding-left: 5.4pt; padding-bottom: 0cm; width: 68pt; border-top-style: none; padding-top: 0cm; border-bottom: windowtext 1pt solid; border-left-style: none; height: 16.75pt" width="91">
            <p>&gt;&nbsp;</p>
            </td>
            <td style="padding-right: 5.4pt; padding-left: 5.4pt; padding-bottom: 0cm; width: 351.6pt; border-top-style: none; padding-top: 0cm; border-bottom: windowtext 1pt solid; border-right-style: none; border-left-style: none; height: 16.75pt" width="469">
            <p>大于</p>
            </td>
        </tr>
        <tr style="height: 16.75pt">
            <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; padding-left: 5.4pt; padding-bottom: 0cm; width: 68pt; border-top-style: none; padding-top: 0cm; border-bottom: windowtext 1pt solid; border-left-style: none; height: 16.75pt" width="91">
            <p>&lt;&nbsp;</p>
            </td>
            <td style="padding-right: 5.4pt; padding-left: 5.4pt; padding-bottom: 0cm; width: 351.6pt; border-top-style: none; padding-top: 0cm; border-bottom: windowtext 1pt solid; border-right-style: none; border-left-style: none; height: 16.75pt" width="469">
            <p>小于</p>
            </td>
        </tr>
        <tr style="height: 16.75pt">
            <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; padding-left: 5.4pt; padding-bottom: 0cm; width: 68pt; border-top-style: none; padding-top: 0cm; border-bottom: windowtext 1pt solid; border-left-style: none; height: 16.75pt" width="91">
            <p>&gt;=</p>
            </td>
            <td style="padding-right: 5.4pt; padding-left: 5.4pt; padding-bottom: 0cm; width: 351.6pt; border-top-style: none; padding-top: 0cm; border-bottom: windowtext 1pt solid; border-right-style: none; border-left-style: none; height: 16.75pt" width="469">
            <p>大于等于</p>
            </td>
        </tr>
        <tr style="height: 16.75pt">
            <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; padding-left: 5.4pt; padding-bottom: 0cm; width: 68pt; border-top-style: none; padding-top: 0cm; border-bottom: windowtext 1pt solid; border-left-style: none; height: 16.75pt" width="91">
            <p>&lt;=</p>
            </td>
            <td style="padding-right: 5.4pt; padding-left: 5.4pt; padding-bottom: 0cm; width: 351.6pt; border-top-style: none; padding-top: 0cm; border-bottom: windowtext 1pt solid; border-right-style: none; border-left-style: none; height: 16.75pt" width="469">
            <p>小于等于</p>
            </td>
        </tr>
        <tr style="height: 16.75pt">
            <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; padding-left: 5.4pt; padding-bottom: 0cm; width: 68pt; border-top-style: none; padding-top: 0cm; border-bottom: windowtext 1pt solid; border-left-style: none; height: 16.75pt" width="91">
            <p>!&gt;</p>
            </td>
            <td style="padding-right: 5.4pt; padding-left: 5.4pt; padding-bottom: 0cm; width: 351.6pt; border-top-style: none; padding-top: 0cm; border-bottom: windowtext 1pt solid; border-right-style: none; border-left-style: none; height: 16.75pt" width="469">
            <p>不大于</p>
            </td>
        </tr>
        <tr style="height: 16.75pt">
            <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; padding-left: 5.4pt; padding-bottom: 0cm; width: 68pt; border-top-style: none; padding-top: 0cm; border-bottom: windowtext 1pt solid; border-left-style: none; height: 16.75pt" width="91">
            <p>!&lt;</p>
            </td>
            <td style="padding-right: 5.4pt; padding-left: 5.4pt; padding-bottom: 0cm; width: 351.6pt; border-top-style: none; padding-top: 0cm; border-bottom: windowtext 1pt solid; border-right-style: none; border-left-style: none; height: 16.75pt" width="469">
            <p>不小于</p>
            </td>
        </tr>
        <tr style="height: 16.75pt">
            <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; padding-left: 5.4pt; padding-bottom: 0cm; width: 68pt; border-top-style: none; padding-top: 0cm; border-bottom: windowtext 1pt solid; border-left-style: none; height: 16.75pt" width="91">
            <p>&lt;&gt;或!=</p>
            </td>
            <td style="padding-right: 5.4pt; padding-left: 5.4pt; padding-bottom: 0cm; width: 351.6pt; border-top-style: none; padding-top: 0cm; border-bottom: windowtext 1pt solid; border-right-style: none; border-left-style: none; height: 16.75pt" width="469">
            <p>不等于</p>
            </td>
        </tr>
    </tbody>
</table>
</div>
<p>例如：在grage表中，查询&#8220;课程成绩&#8221;大于90分的，在查询分析器中输入SQL语句如下：</p>
<p>use student</p>
<p>select&nbsp; *&nbsp; </p>
<p>from&nbsp; grade&nbsp;&nbsp; </p>
<p>where&nbsp; 课程成绩&gt;90</p>
<p>例如：在grade表中，查询&#8220;课程成绩&#8221;小于等于90分的，SQL语句如下：</p>
<p>use&nbsp; student</p>
<p>select&nbsp; *&nbsp; from&nbsp; grade </p>
<p>where&nbsp; 课程成绩&lt;=90</p>
<p>例如：在students表中，查询&#8220;年龄&#8221;在20~22之间（包括20和22）的所有学生。</p>
<p>use&nbsp; student</p>
<p>select&nbsp; *&nbsp; from&nbsp; students </p>
<p style="text-indent: 16pt">&nbsp;where 年龄&gt;=20 and 年龄&lt;=22</p>
<p>例如：在students表中，查询&#8220;年龄&#8221;不大于20~22之间的所有学生。SQL语句如下：</p>
<p>use&nbsp; student</p>
<p>select&nbsp; *&nbsp; from&nbsp; students&nbsp; where&nbsp; 年龄&lt;20 or 年龄&gt;22</p>
<p>例如：在students表中，查询&#8220;年龄&#8221;不小于20的所有学生。SQL语句如下：</p>
<p>use&nbsp; student </p>
<p>select&nbsp; *&nbsp; from students&nbsp; where 年龄 !&lt;20</p>
<p>换一种写法。查询年龄不小于20的所有学生。SQL语句如下：</p>
<p>use&nbsp; student&nbsp; </p>
<p>select&nbsp; *&nbsp; from&nbsp; students&nbsp; where&nbsp; 年龄&gt;=20&nbsp; </p>
<p>例如：在students表中，查询年龄不等于20的所有学生。SQL语句如下：</p>
<p>use&nbsp; student&nbsp; </p>
<p>select&nbsp; *&nbsp; from&nbsp; students&nbsp; where&nbsp; 年龄!=20&nbsp; </p>
<p style="text-indent: 20pt">注意：搜索满足条件的记录行，要比消除所有不满足条件的记录行快得多，所以，将否定的WHERE条件改写为肯定的条件将会提高性能，这是一个必须记住的准则。</p>
<p>（2）范围查询条件</p>
<p>需要返回某一个数据值是否位于两个给定的值之间，读者可以使用范围条件进行检索。通常使用BETWEEN&#8230;AND和NOT&#8230;BETWEEN&#8230;AND来指定范围条件。</p>
<p>使用 BETWEEN&nbsp; AND查询条件时，指定的第一个值必须小于第二个值。因为BETWEEN&#8230;AND实质是查询条件&#8220;大于等于第一个值，并且小于等于第二个值&#8221;的简写形式。即BETWEEN&#8230;AND要包括两端的值，等价于比较运算符（&gt;=...&lt;=）。</p>
<p>例如：在students表中，查询年龄在20~22之间的所有学生。</p>
<p>在查询分析器中输入的SQL语句如下：</p>
<p>use student </p>
<p>select&nbsp; *&nbsp; </p>
<p>from&nbsp; students </p>
<p>where&nbsp; 年龄&nbsp;&nbsp; between 20&nbsp;&nbsp; and&nbsp; 22</p>
<p>而NOT&nbsp; BETWEEN&nbsp; AND语句返回某个数据值在两个指定值的范围以外的，但并不包括两个指定的值。</p>
<p>例如：在students表中，查询年龄不在20~22之间的所有学生。</p>
<p>在查询分析中输入的SQL语句如下：</p>
<p>use student</p>
<p>select *&nbsp; </p>
<p>from students&nbsp; </p>
<p>where&nbsp; 年龄&nbsp; not&nbsp; between 20&nbsp;&nbsp; and&nbsp; 22&nbsp; </p>
<p>（3）列表查询条件</p>
<p>当测试一个数据值是否匹配一组目标值中的一个时，通常使用IN关键字来指定列表搜索条件。IN关键字的格式是IN（目标值1，目标值2，目标值3，&#8230;），目标值的项目之间必须使用逗号分隔,并且括在括号中。</p>
<p>例如：在course表中，查询&#8220;课程编号&#8221;为k01,k03和k04的课程信息。</p>
<p>在查询分析器中输入SQL语句如下：</p>
<p>use student</p>
<p>select&nbsp; *&nbsp; </p>
<p>from&nbsp; course&nbsp;&nbsp; </p>
<p>where&nbsp; 课程代号 in ('MR01','MR03', 'MR04')</p>
<p>IN运算符可以与NOT配合使用排除特定的行。测试一个数据值是否不匹配任何目标值。</p>
<p>例如：在course表中，课程代号不是k01、k03和k04的。</p>
<p>在查询分器中输入的SQL语句如下：</p>
<p>use student</p>
<p>select *&nbsp; </p>
<p>from&nbsp; course&nbsp;&nbsp; </p>
<p>where&nbsp; 课程代号&nbsp; not in ('MR01','MR03', 'MR04')</p>
<p>（4）模式查询条件</p>
<p style="text-indent: 20pt">模式查询条件是用来返回符合某种匹配格式的所有记录，通常使用LIKE或NOT LIKE关键字来指定模式查询条件。LIKE查询条件需要使用通配符在字符串内查找指定的模式，所以读者需要了解通配符及其含义。通配符的含义如表4.2所示。</p>
<p>表4.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; LIKE关键字中的通配符及其含义 </p>
<div align="center">
<table style="margin-left: -84.6pt; width: 417.55pt; border-top-style: none; border-right-style: none; border-left-style: none; border-collapse: collapse; border-bottom-style: none" cellspacing="0" cellpadding="0" width="557" border="1">
    <tbody>
        <tr style="height: 16.75pt">
            <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: windowtext 1pt solid; padding-left: 5.4pt; border-left-width: 1pt; border-left-color: windowtext; padding-bottom: 0cm; width: 81.55pt; padding-top: 0cm; border-bottom: windowtext 1pt solid; height: 16.75pt" width="109">
            <p>通配符</p>
            </td>
            <td style="padding-right: 5.4pt; border-top: windowtext 1pt solid; padding-left: 5.4pt; padding-bottom: 0cm; width: 336pt; padding-top: 0cm; border-bottom: windowtext 1pt solid; border-right-style: none; border-left-style: none; height: 16.75pt" width="448">
            <p>说明</p>
            </td>
        </tr>
        <tr style="height: 16.75pt">
            <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; padding-left: 5.4pt; padding-bottom: 0cm; width: 81.55pt; border-top-style: none; padding-top: 0cm; border-bottom: windowtext 1pt solid; border-left-style: none; height: 16.75pt" width="109">
            <p>%</p>
            </td>
            <td style="padding-right: 5.4pt; padding-left: 5.4pt; padding-bottom: 0cm; width: 336pt; border-top-style: none; padding-top: 0cm; border-bottom: windowtext 1pt solid; border-right-style: none; border-left-style: none; height: 16.75pt" width="448">
            <p>由零个或更多字符组成的任意字符串</p>
            </td>
        </tr>
        <tr style="height: 16.75pt">
            <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; padding-left: 5.4pt; padding-bottom: 0cm; width: 81.55pt; border-top-style: none; padding-top: 0cm; border-bottom: windowtext 1pt solid; border-left-style: none; height: 16.75pt" width="109">
            <p>_</p>
            </td>
            <td style="padding-right: 5.4pt; padding-left: 5.4pt; padding-bottom: 0cm; width: 336pt; border-top-style: none; padding-top: 0cm; border-bottom: windowtext 1pt solid; border-right-style: none; border-left-style: none; height: 16.75pt" width="448">
            <p>任意单个字符</p>
            </td>
        </tr>
        <tr style="height: 16.75pt">
            <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; padding-left: 5.4pt; padding-bottom: 0cm; width: 81.55pt; border-top-style: none; padding-top: 0cm; border-bottom: windowtext 1pt solid; border-left-style: none; height: 16.75pt" width="109">
            <p>[ ]</p>
            </td>
            <td style="padding-right: 5.4pt; padding-left: 5.4pt; padding-bottom: 0cm; width: 336pt; border-top-style: none; padding-top: 0cm; border-bottom: windowtext 1pt solid; border-right-style: none; border-left-style: none; height: 16.75pt" width="448">
            <p>用于指定范围，例如[A~F]，表示A到F范围内的任何单个字符</p>
            </td>
        </tr>
        <tr style="height: 16.75pt">
            <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; padding-left: 5.4pt; padding-bottom: 0cm; width: 81.55pt; border-top-style: none; padding-top: 0cm; border-bottom: windowtext 1pt solid; border-left-style: none; height: 16.75pt" width="109">
            <p>[^ ]</p>
            </td>
            <td style="padding-right: 5.4pt; padding-left: 5.4pt; padding-bottom: 0cm; width: 336pt; border-top-style: none; padding-top: 0cm; border-bottom: windowtext 1pt solid; border-right-style: none; border-left-style: none; height: 16.75pt" width="448">
            <p>表示指定范围之外的，例如[ ^ A~F]范围以外的任何单个字符</p>
            </td>
        </tr>
    </tbody>
</table>
</div>
<p>（1）&#8220;%&#8221;通配符</p>
<p>&#8220;%&#8221;通配符能匹配0个或更多个字符的任意长度的字符串。 </p>
<p>在SQL Server语句中，可以在查询条件的任意位置放置一个&#8220;%&#8221;符号来代表任意长度的字符串。在设置查询条件时，也可以放置两个&#8220;%&#8221;，当最好不要连续出现两个&#8220;%&#8221;符号。</p>
<p>（2）&#8220;_&#8221;通配符</p>
<p>&#8220;_&#8221;号表示任意单个字符，该符号只能匹配一个字符，利用&#8220;_&#8221;号可以作为通配符组成匹配模式进行查询。 </p>
<p>&#8220;_&#8221;符号可以放在查询条件的任意位置，且只能代表一个字符。</p>
<p>（3）&#8220;[ ]&#8221;通配符</p>
<p>在模式查询中可以使用&#8220;[ ]&#8221;符号来查询一定范围内的数据。&#8220;[ ]&#8221;符号用于表示一定范围内的任意单个字符，它包括两端数据。</p>
<p>例如：在students表中，查询电话号码以'3451'结尾并且开头数字位于1~5之间的学生信息。</p>
<p>（4）&#8220;[^ ]&#8221;通配符</p>
<p>在模式查询中可以使用&#8220;[^ ]&#8221;符号来查询不在指定范围内的数据。&#8220;[^ ]&#8221;符号用于表示不在某范围内的任意单个字符，它包括两端数据。</p>
<p>例如：在students表中，查询电话号码以'3451'结尾，但不以2开头的学生信息。</p>
<p>在查询分析器中输入的SQL语句如下：</p>
<p>use student</p>
<p>select * </p>
<p>from&nbsp; students&nbsp; </p>
<p>where&nbsp;&nbsp; 联系方式&nbsp;&nbsp; like&nbsp; '[^2]3451'</p>
<p>NOT&nbsp; LIKE的含义与LIKE关键字正好相反，查询结果将返回不符合匹配模式查询。</p>
<p>例如：查询不姓&#8220;李&#8221;的学生信息。SQL语句如下：</p>
<p>use student</p>
<p>select&nbsp; *&nbsp; from&nbsp; students&nbsp; where&nbsp;&nbsp; 姓名&nbsp;&nbsp; not like&nbsp; '李%'</p>
<p>例如：查询除了名字是两个字的姓&#8220;李&#8221;的其他同学信息。SQL语句如下：</p>
<p>use student</p>
<p>select&nbsp; *&nbsp; from&nbsp; students&nbsp; where 姓名&nbsp; not like '李_'&nbsp; </p>
<p>例如：查询除了电话号码以'3451'结尾并且开头数字位于1~5之间的其他的学生信息。SQL语句如下：</p>
<p>use student</p>
<p>select * from&nbsp; students&nbsp; where 联系方式&nbsp; not&nbsp; like&nbsp; '[1-5]3451'</p>
<p style="margin-left: 21.2pt; text-indent: 0cm">例如：查询电话号码不符合如下条件的学生信息，这些条件是电话号码是以'3451'结尾，但不以2开头的。SQL语句如下：</p>
<p>use student</p>
<p>select * from&nbsp; students&nbsp; where&nbsp;&nbsp; 联系方式&nbsp; not&nbsp; like&nbsp; '[^2]3451'</p>
<p>（5）复合搜索条件（AND、OR 和NOT）</p>
<p>如果读者想把前面讲过的几个单一条件组合成一个复合条件，这就需要使用逻辑运算符AND、OR 和NOT，才能完成复合条件查询。使用逻辑运算符时，遵循的指导原则</p>
<p style="margin-left: 21.2pt; text-indent: 10pt">① 使用AND返回满足所有条件的行。</p>
<p style="margin-left: 21.2pt; text-indent: 10pt">② 使用OR返回满足任一条件的行。</p>
<p style="margin-left: 31.2pt; text-indent: 0cm">③ 用NOT返回不满足表达式的行。</p>
<p style="text-align: left" align="left">就像数据运算符乘和除一样，它们之间是具有优先级顺序的：NOT优先级最高，AND次之，OR的优先级最低。</p>
<p>例如：用OR进行查询。查询学号是&#8220;B001&#8221;或者是"B002"的学生信息。SQL语句如下：</p>
<p>use student</p>
<p>select&nbsp; *&nbsp; from&nbsp; students&nbsp; where&nbsp; 学号='B001' or&nbsp; 学号='B002'</p>
<p>例如：用AND进行查询。查询性别是女并且年龄大于21岁的学生信息。SQL语句如下：</p>
<p>use student</p>
<p>select&nbsp; *&nbsp; from&nbsp; students&nbsp; where 性别='女'&nbsp; and&nbsp; 年龄&gt;21</p>
<p>下面用AND和OR结合进行查询。</p>
<p>例如：在students表中，要查询年龄大于20的女生或者年龄大于22的男生的信息。</p>
<p>在查询分析器中输入SQL语句如下：</p>
<p>use&nbsp; student&nbsp; </p>
<p>select * </p>
<p>from students&nbsp; </p>
<p>where 年龄 &gt; 20 and 性别='女' or 年龄&gt;22 and 性别='男'&nbsp;&nbsp; </p>
<p>使用逻辑关键字AND、OR、NOT和括号把搜索条件分组，可以构建非常复杂的搜索条件。</p>
<p style="text-indent: 20pt">例如：在student表中，查询年龄大于20的女生或者年龄大于22的男生，并且电话号码都是以&#8216;1~3&#8217;打头、以&#8216;3451&#8217;结尾的学生信息。</p>
<p style="text-indent: 20pt">在查询分析器中输入的SQL语句如下：</p>
<p style="text-indent: 24pt">use student</p>
<p style="text-indent: 24pt">select * </p>
<p style="text-indent: 24pt">from students&nbsp; </p>
<p style="text-indent: 24pt">where (年龄&gt;20 and 性别='女' or 年龄&gt;22 and 性别='男') and 联系方式&nbsp; like&nbsp; '[1-3]3451'</p>
<h4>4．其他子句</h4>
<p>① ORDER&nbsp; BY子句</p>
<p>对于表格比较小，不用ORDER&nbsp; BY子句，查询结果会按照在表格中的顺序排列的。但对于表格比较大的，则必须使用ORDER&nbsp; BY子句，方便查看查询结果。</p>
<p>ORDER&nbsp; BY子句由关键字ORDER BY&nbsp; 后跟一个用逗号分开的排序列表组成。</p>
<p>语法：</p>
<p>[ ORDER BY { order_by_expression [ ASC | DESC ] }&nbsp; [ ,...n ] ]</p>
<p>参数：</p>
<p>order_by_expression：指定要排序的列。可以将排序列指定为列名或列的别名（可由表名或视图名限定）和表达式，或者指定为代表选择列表内的名称、别名或表达式的位置的负整数。可指定多个排序列。ORDER BY 子句中的排序列序列定义排序结果集的结构。</p>
<p>ORDER BY：子句可包括未出现在此选择列表中的项目。然而，如果指定SELECT DISTINCT，或者如果 SELECT 语句包含 UNION 运算符，则排序列必定出现在选择列表中。此外，当 SELECT 语句包含 UNION 运算符时，列名或列的别名必须是在第一选择列表内指定的列名或列的别名。</p>
<p>ASC：指定按递增顺序，从低到高对指定列中的值进行排序。默认就是递增顺序。</p>
<p>DESC：指定按递减顺序，从高到低对指定列中的值进行排序。</p>
<p>例如：在grade表中，按照学生的&#8220;课程成绩&#8221;升序显示。</p>
<p>SQL语句如下所示：</p>
<p>use&nbsp; student</p>
<p>select&nbsp; *&nbsp; from grade&nbsp; </p>
<p>order&nbsp; by&nbsp; 课程成绩</p>
<p>查询结果若以降序排序，必须在列名后指定关键字的DESC。默认是升序排序。</p>
<p>例如在students表中，按照学生的&#8220;年龄&#8221;降序显示。SQL语句如下：</p>
<p>use&nbsp; student</p>
<p>select * from students </p>
<p style="text-indent: 16pt">&nbsp;order by 年龄&nbsp; desc</p>
<p>ORDER&nbsp; BY子句会根据查询结果中的一个列或多个列对查询结果进行排序。第一个排序项是主要的排序依据，其次那些是次要的排序依据。</p>
<p>例如：在grade表中，按照学生的&#8220;课程成绩&#8221;升序排列，然后再按照&#8220;学期&#8221;降序排序。SQL语句如下：</p>
<p>use&nbsp; student</p>
<p>select&nbsp; *&nbsp; from&nbsp; grade&nbsp; order&nbsp; by&nbsp; 课程成绩,学期&nbsp; desc</p>
<p>在ORDER BY 列表中不允许使用子查询、聚合表达式或常量表达式。但是，用户可以在选择列表为聚合表达式指定的一个名称，然后在ORDER&nbsp; BY 子句中引用这个指定的名称。</p>
<p>例如：在grade表中，按照学生的平均成绩排序。SQL语句如下：</p>
<p style="text-indent: 24pt">use&nbsp; student</p>
<p style="text-indent: 24pt">select&nbsp; 课程代号,avg(课程成绩) as&nbsp; 平均成绩&nbsp; from grade </p>
<p style="text-indent: 24pt">group by 课程代号 order&nbsp; by&nbsp; 平均成绩</p>
<p style="text-indent: 20pt"><img height="14" src="http://book.csdn.net/BookFiles/659/img/image066.jpg" width="18"  alt="" />&nbsp;&nbsp;&nbsp; 说明：在ORDER&nbsp; BY 子句中不能使用数据类型是ntext、text和image列。</p>
<p>② GROUP BY子句</p>
<p>GROUP BY子句可以将表的行划分为不同的组。分别总结每个组，这样就可以控制想要看见的详细信息的级别。</p>
<p>语法：</p>
<p>[ GROUP BY [ ALL ] group_by_expression[ ,...n ]</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;[ WITH { CUBE | ROLLUP } &nbsp;]&nbsp; ]</p>
<p>参数：</p>
<p>ALL：包含所有组和结果集，甚至包含那些任何行都不满足 WHERE 子句指定的搜索条件的组和结果集。如果指定了 ALL，将对组中不满足搜索条件的汇总列返回空值。不能用 CUBE 或 ROLLUP 运算符指定 ALL。如果访问远程表的查询中有 WHERE 子句，则不支持GROUP BY ALL操作。</p>
<p>group_by_expression：是对其执行分组的表达式。group_by_expression也称为分组列。group_by_expression 可以是列或引用列的非聚合表达式。在选择列表内定义的列的别名不能用于指定分组列。对于不包含 CUBE 或 ROLLUP 的 GROUP BY 子句，group_by_expression 的项数受查询所涉及的 GROUP BY 列的大小、聚合列和聚合值的限制。该限制从 8,060 字节的限制开始，对保存中间查询结果所需的中间级工作表有 8,060 字节的限制。如果指定了 CUBE 或 ROLLUP，则最多只能有10个分组表达式。</p>
<p>CUBE：指定在结果集内不仅包含由 GROUP BY 提供的正常行，还包含汇总行。在结果集内返回每个可能的组和子组组合的 GROUP BY 汇总行。GROUP BY 汇总行在结果中显示为 NULL ，但可用来表示所有值。使用 GROUPING 函数确定结果集内的空值是否是 GROUP BY 汇总值。结果集内的汇总行数取决于GROUP BY 子句内包含的列数。GROUP BY 子句中的每个操作数（列）绑定在分组 NULL 下，并且分组适用于所有其它操作数（列）。由于 CUBE 返回每个可能的组和子组组合，因此不论指定分组列时所使用的是什么顺序，行数都相同。</p>
<p>ROLLUP：指定在结果集内不仅包含由 GROUP BY 提供的正常行，还包含汇总行。按层次结构顺序，从组内的最低级别到最高级别汇总组。组的层次结构取决于指定分组列时所使用的顺序。更改分组列的顺序会影响在结果集内生成的行数。</p>
<p style="text-indent: 20pt"><img height="14" alt="*" src="http://book.csdn.net/BookFiles/659/img/image066.jpg" width="18" />&nbsp;&nbsp;&nbsp; 注意：</p>
<p style="text-indent: 20pt">◎ 在SELECT子句的字段列表中，除了聚集函数外，其他所出现的字段一定要GROUP BY子句中有定义才行。例如&#8220;GROUP BY A，B&#8221;，那么&#8220;SELECT SUM（A），C&#8221;就有问题，因为C不在GROUP BY中，但是SUM（A）还是可以的。</p>
<p style="text-indent: 20pt">◎ SELECT子句的字段列表中不一定要有聚集函数，但至少要用到GROUP BY子句列表中的一个项目。例如&#8220;GROUP BY A，B，C&#8221;，则&#8220;SELECT A&#8221;是可以的。</p>
<p style="text-indent: 20pt">◎ 在SQL Server中text、ntext和image数据类型的字段不能作为GROUP BY子句的分组依据。</p>
<p style="text-indent: 20pt">◎ GROUP BY子句不能使用字段别名。</p>
<p>GROUP&nbsp; BY子句可以基于指定某一列的值将数据集合划分为多个分组，同一组内所有记录在分组属性上具有相同值。</p>
<p style="margin-left: 21.25pt; text-indent: 0cm">例如：把students表按照&#8220;性别&#8221;这个单列进行分组。</p>
<p style="margin-left: 21.25pt; text-indent: 0cm">SQL语句如下所示：</p>
<p>Use student</p>
<p>select&nbsp; 性别&nbsp; </p>
<p>from&nbsp; students&nbsp; </p>
<p>group&nbsp; by 性别&nbsp; </p>
<p style="text-indent: 20pt">但仍然要强调SELECT子句必须与GROUP BY后的子句或者是分组函数列相一致。</p>
<p style="text-indent: 20pt">例如：由于下列查询中&#8220;姓名&#8221;列即不包含在GROUP&nbsp; BY子句中，也不包含在分组函数中，所以是错误的。错误的SQL语句如下：</p>
<p>select&nbsp; 姓名,性别&nbsp; </p>
<p>from&nbsp; student&nbsp; group&nbsp; by 性别&nbsp; </p>
<p>例如：在grade表中，按学期分组查询。正确的SQL语句如下：</p>
<p>select 学期 </p>
<p>from grade&nbsp; group by 学期&nbsp; </p>
<p>GROUP BY子句可以基于指定多列的值将数据集合划分为多个分组。</p>
<p>例如：在students表中，按照&#8220;性别&#8221;和&#8220;年龄&#8221;列进行分组。</p>
<p>SQL语句如下所示：</p>
<p>Use student</p>
<p>select 性别,年龄&nbsp; </p>
<p>from student </p>
<p>group by 性别,年龄</p>
<p>在students表中，首先按照性别分组，然后再按照年龄分组，再举一个例子。</p>
<p>例如：在grade表中，按照&#8220;学号&#8221;和&#8220;课程代号&#8221;列进行分组。SQL语句如下：</p>
<p>use student</p>
<p>select 学号,课程代号 </p>
<p>from&nbsp; grade&nbsp; group by 学号,课程代号</p>
<p style="text-indent: 20pt">按多列进行分组时有NULL组的是如何处理的？当表按多列进行分组时有NULL组，这时NULL被作为一个特定值处理，就像其他任何值一样。也就是说，如果在某个分组列中存在两个NULL，则可以好像它们有相同的值那样处理它们并将它们放在相同的组中。</p>
<p style="text-indent: 20pt">例如：在grade表中，按&#8220;学期&#8221;和&#8220;课程代号&#8221;列进行分组。</p>
<p style="text-indent: 20pt">SQL语句如下所示：</p>
<p>Use student</p>
<p>select&nbsp; 学期,课程代号</p>
<p>from grade </p>
<p>group by 学期,课程代号</p>
<p>GROUP BY子句是经常与聚集函数一起使用。如果SELECT子句中包含聚集函数，则计算每组的汇总值，当用户指定GROUP BY时，选择列表中任一非聚集表达式内的所有列都应包含在GROUP BY列表中，或者GROUP BY表达式必须与选择列表表达式完全匹配</p>
<p>例如：在students表中，分别求男女生的平均年龄。</p>
<p>SQL语句如下所示：</p>
<p>Use student</p>
<p>select 性别,avg(年龄) as 平均年龄</p>
<p>from students</p>
<p>group by 性别</p>
<p>例如：在students表中，分别求有多少个男生和女生。SQL语句如下：</p>
<p>use student</p>
<p>select 性别,count(性别) as 人数&nbsp; </p>
<p>from students group by 性别</p>
<p>HAVING子句对GROUP&nbsp; BY子句选择出来的结果进行再次筛选，最后输出符合HAVING子句中条件的记录。HAVING子句的语法与WHERE子句的语法相类似，惟一不同的是HAVING子句中可以包含聚合函数。</p>
<p>语法：</p>
<p>[HAVING &lt;search_condition&gt;]</p>
<p>参数：</p>
<p>search_condition：指定组或聚合应满足的搜索条件。当 HAVING 与 GROUP BY ALL 一起使用时，HAVING 子句替代 ALL。</p>
<p>例如：在students表中，按性别分组求平均年龄，并且查询其平均年龄大于21的学生信息。</p>
<p>SQL语句如下所示：</p>
<p>Use student</p>
<p>select&nbsp; avg(年龄), 性别&nbsp; </p>
<p>from students&nbsp; </p>
<p>group&nbsp; by 性别&nbsp; </p>
<p>having avg(年龄)&gt;21&nbsp; </p>
<p>例如：在grade表中，按学期分组求平均成绩，并且查询平均成绩大于93的课程信息。</p>
<p>SQL语句如下所示：</p>
<p>Use student</p>
<p>select 学期,avg(课程成绩) as 平均成绩</p>
<p>from&nbsp;&nbsp; grade</p>
<p>group&nbsp; by 学期</p>
<p>having avg(课程成绩)&gt;93</p>
<p style="text-indent: 10pt"><img height="14" src="http://book.csdn.net/BookFiles/659/img/image066.jpg" width="18"  alt="" />说明：HAVING查询条件是在进行分组操作之后才应用的；在 HAVING 子句中不能使用 text、image 和 ntext 数据类型。</p>
<p>统计结果并不能保证结果集内记录按一定顺序排列，如果使用ORDER BY子句，就可以使结果集中的结果按一定的顺序（升序、降序）排序。</p>
<p>例如：在student表中，按&#8220;性别&#8221;和&#8220;年龄&#8221;列分组，并按&#8220;年龄&#8221;列降序排序。</p>
<p>SQL语句如下所示：</p>
<p>Use student</p>
<p>select 性别,年龄 </p>
<p>from&nbsp; students&nbsp; </p>
<p>group&nbsp; by 性别,年龄</p>
<p>order by 年龄 desc</p>
<p>例如：在grade表中，按&#8220;学号&#8221;分组，并按课程的平均成绩升序排序。SQL语句如下：</p>
<p>use student</p>
<p>select 学号,avg(课程成绩) as 平均成绩&nbsp; </p>
<p>from grade&nbsp; group by 学号&nbsp; order by 平均成绩</p>
<p>③ Compute 和Compute by子句主要用来汇总数据。</p>
<p>语法：</p>
<p>[ COMPUTE&nbsp;&nbsp;&nbsp;&nbsp; </p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;{ { AVG | COUNT | MAX | MIN | STDEV | STDEVP &nbsp;&nbsp; </p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;| VAR | VARP | SUM }&nbsp;&nbsp; </p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;( expression ) } [ ,...n ]&nbsp; </p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;[ BY expression [ ,...n ] ] </p>
<p>参数说明：</p>
<p>AVG | COUNT | MAX | MIN | STDEV | STDEVP | VAR | VARP | SUM</p>
<p>指定要执行的聚合。下面是COMPUTE 子句使用的行聚合函数：</p>
<p>AVG：数字表达式中所有值的平均值</p>
<p>COUNT：选定的行数</p>
<p>MAX：表达式中的最高值</p>
<p>MIN：表达式中的最低值</p>
<p>STDEV：表达式中所有值的统计标准偏差</p>
<p>STDEVP：表达式中所有值的填充统计标准偏差</p>
<p>SUM：数字表达式中所有值的和</p>
<p>VAR：表达式中所有值的统计方差</p>
<p>VARP：表达式中所有值的填充统计方差</p>
<p>Expression：表达式，如对其执行计算的列名。expression 必须出现在选择列表中，并且必须将其指定为与选择列表中的某个表达式完全一样。在 expression 内不能使用在选择列表中指定的列的别名。&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </p>
<p>BY expression：在结果集内生成控制中断和分类汇总。expression 是 order_by_expression 在相关 ORDER BY 子句中的精确复本。一般情况下，这是列名或列的别名。可指定多个表达式。在 BY 后列出多个表达式可将一个组分成子组并在每个分组级别上应用聚合函数。</p>
<p>例如：在studnet表中，求&#8220;年龄&#8221;字段的平均值。</p>
<p>SQL语句如下所示：</p>
<p>Use student</p>
<p>select *&nbsp; </p>
<p>from&nbsp; student&nbsp; </p>
<p>compute&nbsp; avg(年龄)</p>
<p style="text-indent: 20pt"><img height="14" src="http://book.csdn.net/BookFiles/659/img/image066.jpg" width="18"  alt="" />&nbsp;&nbsp;&nbsp; 说明：在 COMPUTE 或 COMPUTE BY 子句中，不能指定ntext、text和image数据类型。</p>
<p style="text-indent: 20pt">下面是COMPUTE和COMPUTE&nbsp; BY两个子句的区别。</p>
<p>◎ 没有BY时，查询结果将包含两个结果集。第一个结果集将是包含选择列表中所有字段的明细记录。第二个结果集只有一条记录，这条记录只包含COMPUTE子句中所指定的汇总函数的合计。</p>
<p>◎ 有BY时，查询结果将根据BY后的字段名称进行分组，并且为每个符合SELECT语句查询条件的组返回两个结果集。第一个结果集是明细记录集，包含结果集中将包含选择列表中所有的字段信息。第二个结果集是只包含一条记录，这条记录的内容只有该组的COMPUTE子句中所指定的汇总函数的小计。</p>
<p>例如：在students表中，分别求男生和女生的平均年龄。</p>
<p>SQL语句如下所示：</p>
<p>Use student</p>
<p>select *&nbsp; </p>
<p>from&nbsp; students </p>
<p>order by&nbsp; 性别&nbsp; </p>
<p>compute&nbsp; avg(年龄)&nbsp; by 性别</p>
<p><img height="16" alt="*" src="http://book.csdn.net/BookFiles/659/img/image072.gif" width="20" />&nbsp;注意：如果使用COMPUTE&nbsp; BY，则必须也使用ORDER&nbsp; BY子句。表达式必须与在 ORDER BY 后列出的子句相同或是其子集，并且必须按相同的序列。</p>
<p>④ OPTION子句</p>
<p>指定应在整个查询中使用所指定的查询提示。每个查询提示只能指定一次，但允许指定多个查询提示。用该语句只可能指定一个OPTION子句。查询提示影响语句中的所有运算符。如果主查询中涉及 UNION，则只有涉及 UNION 运算符的最后一个查询可以有 OPTION 子句。如果一个或多个查询提示导致查询优化器不生成有效计划，则产生8622号错误。</p>
<p>语法：</p>
<p>[ OPTION ( &lt; query_hint &gt; [ ,...n ) ]</p>
<p>&lt; query_hint &gt; ::=</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;{&nbsp;&nbsp;&nbsp;&nbsp;{ HASH | ORDER } GROUP</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;| { CONCAT | HASH | MERGE } UNION</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;| {LOOP | MERGE | HASH } JOIN</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;| FAST number_rows</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;| FORCE ORDER</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;| MAXDOP number</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;| ROBUST PLAN</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;| KEEP PLAN</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;| KEEPFIXED PLAN</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;| EXPAND VIEWS</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;} </p>
<p>参数说明：</p>
<p>{ HASH | ORDER }GROUP：指定在 GROUP BY、DISTINCT 或 COMPUTE 查询子句中所描述的聚合应使用哈希操作或排列。</p>
<p>{ MERGE | HASH | CONCAT } UNION：指定由合并、哈希或串联 UNION 集合执行所有 UNION 运算。如果指定了不止一个 UNION 提示，查询优化器就会从这些指定的提示中选择开销最少的策略。</p>
<p>{ LOOP | MERGE | HASH } JOIN：指定在整个查询中所有的联接操作由循环联接、合并联接或哈希联接来完成。如果指定了多个联接提示，则优化器从允许的联接策略中选择最便宜的联接策略。如果在同一个查询中，还为一对特定的表指定了联接提示，则虽然仍须遵守查询提示，但该联接提示将优先联接这两个表。因此，为这对表指定的联接提示可能只限制选择查询提示中允许的联接方法。</p>
<p>FAST number_rows：指定对查询进行优化，以便快速检索第一个 number_rows（非负整数）。在第一个 number_rows 返回后，查询继续进行并生成完整的结果集。</p>
<p>FORCE ORDER：指定在查询优化过程中保持由查询语法表示的联接顺序。</p>
<p>MAXDOP number：只对指定了 sp_configure 的 max degree of parallelism 配置选项的查询替代该选项。当使用 MAXDOP查询提示时，所有和 max degree of parallelism 配置选项一起使用的语义规则均适用。</p>
<p>ROBUST PLAN：强制查询优化器以性能为代价，使用对最大可能的行大小有效的计划。处理查询时，中间级表和运算符可能需要存储和处理比输入行宽的行。在有些情况下，行可能很宽，以致某个运算符无法处理行。如果发生这种情况，SQL Server 将在查询执行过程中生成错误。通过使用 ROBUST PLAN，可以指示查询优化器不考虑可能会遇到该问题的查询计划。</p>
<p>KEEP PLAN：强制查询优化器对查询放宽估计的重新编译阈值。估计的重新编译阈值是一个点，基于该点当对表的索引列更改（更新、删除或插入）达到估计的数字时自动重新编译查询。指定 KEEP PLAN 将确保当表有多个更新时不会频繁地对查询进行重新编译。</p>
<p>KEEPFIXED PLAN：强制查询优化器不因统计中的更改或索引列（更新、删除或插入）而重新编译查询。指定 KEEPFIXED PLAN 将确保仅当更改基础表的架构或在那些表上执行 sp_recompile 时才重新编译查询。</p>
<p>EXPAND VIEWS：指定展开索引视图，而且查询优化器不将任何索引视图看作是查询中任何部分的替代。（当视图名称由查询文本中的视图定义替换时，视图将展开。）实际上，该查询提示不允许在查询计划中直接使用索引视图和直接在索引视图上使用索引。只有在查询的 SELECT 部分中直接引用视图，而且指定 WITH (NOEXPAND)或 WITH（NOEXPAND、INDEX( index_val [ ,...n ] )），才会展开索引视图。</p>
<p>⑤ DISTINCT关键字</p>
<p>DISTINCT关键字主要用来从SELECT语句的结果集中去掉重复的记录。如果用户没有指定DISTINCT关键字，那么系统将返回所有符合条件的记录组成结果集，其中包括重复的记录。</p>
<p>DISTINCT关键字可以找出一个列中的所有值，并使每个值只显示一次。</p>
<p>例如：显示grade表中学号的不同值。</p>
<p>SQL语句如下所示：</p>
<p>Use student</p>
<p>select distinct 学号</p>
<p>from grade</p>
<p style="text-indent: 20pt"><img height="14" src="http://book.csdn.net/BookFiles/659/img/image066.jpg" width="18"  alt="" />说明：用SELECT DISTINCT关键字处理null值与其它数据一样。多个null值只显示一个。</p>
<p>对多个列使用DISTINCT关键字时，查询结果只显示每个有效组合的一个例子。即结果表中没有完全相同的两个行。</p>
<p>例如：显示grade表中学号和课程代号的不同值。</p>
<p>SQL语句如下所示：</p>
<p>Use student</p>
<p>select&nbsp; distinct 学号,课程代号&nbsp; </p>
<p>from grade&nbsp;&nbsp; </p>
<p>一个表由于没有主键可能在操作过程中有许多重复行，这样导致查询数据时不必要的麻烦，在SQL&nbsp; SERVER中还不允许修改重复行数据。下面使用SELECT DISTINCT创建一个没有重复行的新表，再删除旧表的方式来删除重复行。</p>
<p>例如：删除有重复行的grade表。首先创建一个没有重复值的表。SQL语句如下：</p>
<p>use student</p>
<p>select&nbsp; distinct *&nbsp; </p>
<p>into&nbsp; ls&nbsp; </p>
<p>from&nbsp; grade</p>
<p style="text-indent: 0cm">然后再删除旧表。SQL语句如下：</p>
<p>drop&nbsp; table&nbsp; grade</p>
<p style="text-indent: 0cm">最后把临时表的名称改成旧表的名称grade。SQL语句如下：</p>
<p style="text-indent: 22.1pt">EXEC &nbsp;sp_rename &nbsp;'ls', &nbsp;'grade'</p>
<p style="text-indent: 20pt">注意：</p>
<p style="text-indent: 20pt">在SELECT列表中只能使用一次DISTINCT关键字，不要将查询字段放在DISTINCT关键字前面，或在其后添加逗号。如下面的语句将提示出错信息。</p>
<p>Select state,distinct city from authors</p>
<p style="text-indent: 20pt">正确的语句应为：</p>
<p>select distinct state,city from authors</p>
<p style="text-indent: 20pt">如果省略了DISTINCT关键字，查询结果中不会消除重复纪录。也可以指定ALL关键字来明确指示要保留重复纪录，但是这是不必要的，因为这是默认的行为。</p>
<p style="text-indent: 20pt">DISTINCT关键字并不是指某一行，而是指不重复SELECT输出的所有列。这一点十分重要，其作用是防止相同的行出现在一个查询结果的输出中，而不是防止行中某一字段重复。</p>
<p style="text-indent: 20pt">DISTINCT是SUM、AVG和COUNT函数的可选关键字。如果使用DISTINCT关键字，那么在计算机总和、平均值或计数之前，先消除重复的值。</p>
<p>⑥ AS关键字</p>
<p>AS关键字可以为查询结果的列指定别名。下面讲解在什么情况下使用AS关键字。</p>
<p>列名如果是英文的，查询结果不易查看，可以为其起个中文别名。</p>
<p>例如：pubs数据库中的pub_info图书信息表列名都是英文的，为&#8220;pub_id&#8221;图书编号列起个中文名。</p>
<p>SQL语句如下所示：</p>
<p>Use pubs</p>
<p>select&nbsp; pub_id&nbsp; as&nbsp; 图书编号, logo as 图标 </p>
<p>from&nbsp; pub_info</p>
<p style="text-indent: 20pt"><img height="14" src="http://book.csdn.net/BookFiles/659/img/image066.jpg" width="18"  alt="" />&nbsp;&nbsp;&nbsp; 说明：pubs数据库是SQL SERVER自带的数据库。</p>
<p>如果同时对多个表进行查询，结果表中出现相同的列名，容易引起混淆或者不能引用这些列只能为这些列起个别名。</p>
<p>例如：同时查询grade和students表。把两个表相同的列&#8220;学号&#8221;分别起了别名。</p>
<p>SQL语句如下所示：</p>
<p>Use student</p>
<p>select students.学号 as 学生编号 ,姓名,年龄,grade.学号 as 考生编号 ,课程成绩 </p>
<p>from students,grade&nbsp; </p>
<p>当SELECT子句的选择列为表达式时，在查询结果中无法显示，只能为该表达式起个别名。</p>
<p>有的选择列的表达式是使用了聚集函数。</p>
<p>例如：求bookinfo表中&#8220;销售数量&#8221;列的平均值。</p>
<p>SQL语句如下所示：</p>
<p>Use student</p>
<p>select&nbsp; avg(销售数量) as 平均销售&nbsp; </p>
<p>from&nbsp; bookinfo</p>
<p style="text-indent: 20pt"><img height="16" alt="*" src="http://book.csdn.net/BookFiles/659/img/image072.gif" width="20" />&nbsp;&nbsp; 注意：字段别名可以使用在ORDER BY子句，但是不能用在WHERE、GROUP BY或HAVING子句中。</p>
<p>⑦ TOP关键字</p>
<p>在查询数据时，经常需要查询前若干条数据或最后若干条数据，这个时候就需要使用TOP关键字进行数据查询。</p>
<p>语法：</p>
<p>SELECT TOP n [PERCENT]</p>
<p>FROM table</p>
<p>WHERE&nbsp; </p>
<p>ORDER BY&#8230;</p>
<p>参数：</p>
<p>PERCENT：返回行的百分之n,而不是n行。</p>
<p>n：如果SELECT语句中没有ORDER BY子句，TOP n返回满足WHERE子句的前n条记录。如果子句中满足条件的记录少于n，那么仅返回这些记录。</p>
<p>例如：显示student表的前3条记录。</p>
<p>在查询分析器中输入SQL语句如下：</p>
<p>use student</p>
<p>select top 3 * from bookinfo</p>
<p style="text-indent: 20pt">注意：</p>
<p style="text-indent: 20pt">如果包含ORDER BY子句，TOP n返回满足查询的前n行，但不删除重复组，这样有可能输入大于n条的纪录。如果使用ORDER BY，TOP n返回前n条纪录，但是如果第n条后有与排序字段相同值的纪录，也将输出这些纪录。例如：如果有另外两条纪录有相同的值，得到的将不是n条纪录而是n+2条纪录。因为在使用ORDER BY时TOP并不删除重复的组。</p>
<p style="text-indent: 20pt">按升序排列一般在ORDER BY子句后添加ASC谓词，也可省略，默认按升序排列。</p>
<p>TOP关键字还可以按百分比返回记录的行数。</p>
<p>例如：显示bookinfo表中的前6%的记录。</p>
<p>在查询分析器中输入SQL语句如下：</p>
<p>use student</p>
<p>select &nbsp;top &nbsp;6 &nbsp;percent * </p>
<p>from&nbsp; bookinfo</p>
<p>TOP关键字可以显示结果记录的后几行，是用ORDER&nbsp; BY关键字降序排列实现的。</p>
<p>例如：显示bookinfo表中销售数量最多的书籍信息。</p>
<p>在查询分析器中输入SQL语句如下：</p>
<p>use student</p>
<p>select top 1 * </p>
<p>from&nbsp; bookinfo</p>
<p>order&nbsp; by&nbsp; 销售数量 desc&nbsp; </p>
<h3>4.1.3&nbsp; 解决查询过程中的问题</h3>
<h4>1．有空格的字符型数据</h4>
<p>当字符型列中有空格时，给查询该数据时带来了麻烦。有时不去掉空格，就查找不到该数据。</p>
<p>例如&#8220; 明日 &#8221;和&#8220;明日&#8221;就不是相等的两个字符串。SQL去空格用LTRIM（）和RTRIM（）函数。</p>
<p>（1）LTRIM函数</p>
<p>LTRIM函数用于删除字符或表达式左侧的空格。</p>
<p>语法：</p>
<p>LTRIM ( character_expression )</p>
<p>参数：</p>
<p>character_expression：是字符或二进制数据表达式。character_expression可以是常量、变量或列。character_expression必须是可以隐性转换为varchar的数据类型。否则，使用CAST显式转换 character_expression。</p>
<p>返回值：</p>
<p>数据类型为varchar的数据。</p>
<p>例如：使用LTRIM函数删除字符变量&#8220; ing is a song very much&#8220;中的起始空格。结果如图4.15所示。</p>
<p><img height="37" src="http://book.csdn.net/BookFiles/659/img/image087.jpg" width="225"  alt="" /></p>
<p>图4.15&nbsp; 删除起始空格之后得到的字符串</p>
<p>在查询分析器中输入SQL语句如下：</p>
<p>DECLARE @string&nbsp; varchar(50)</p>
<p>SET @string =' ing is a song very much'</p>
<p>SELECT 'lov' + LTRIM(@string)</p>
<p>（2）RTRIM（）函数</p>
<p>RTRIM函数用于截断所有尾随空格后返回一个字符串。</p>
<p>语法：</p>
<p>RTRIM ( character_expression ) </p>
<p>参数：</p>
<p>character_expression：由字符数据组成的表达式。character_expression可以是常量、变量，也可以是字符或二进制数据的列。character_expression必须为可隐性转换为varchar的数据类型。否则请使用CAST函数显式转换character_expression。</p>
<p>返回值：</p>
<p>数据类型为varchar数据。</p>
<p>例如：显示如何使用RTRIM删除字符变量&#8220;LOVING&nbsp; &#8220;中的尾随空格。结果如图4.16所示。</p>
<p><img height="36" src="http://book.csdn.net/BookFiles/659/img/image088.jpg" width="210"  alt="" /></p>
<p>图4.16&nbsp; 删除尾随空格之后得到的字符串</p>
<p>在查询分析器中输入SQL语句如下：</p>
<p>DECLARE @string&nbsp; varchar(60)</p>
<p>SET @string = 'LOVING&nbsp; '</p>
<p>SELECT&nbsp;&nbsp; RTRIM(@string)+'is a song very much'</p>
<p>例如：查询student1表的信息，同时把&#8220;姓名&#8221;列的空格去掉。下面是查询前和查询后的结果，如图4.17所示。</p>
<p><img height="280" src="http://book.csdn.net/BookFiles/659/img/image089.jpg" width="278"  alt="" /></p>
<p>图4.17&nbsp; 查询去掉空格的students表的信息</p>
<p>在查询分析器中输入SQL语句如下：</p>
<p>use student</p>
<p>SELECT 姓名,LTRIM(姓名) AS 去除左面空格, </p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; RTRIM(姓名) AS 去除右面空格,</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; LTRIM(RTRIM(姓名)) AS 去除左右空格 </p>
<p>FROM&nbsp; student1</p>
<h4>2．查询时间日期型的数据</h4>
<p>（1）查询指定日期的数据</p>
<p>在SQL Server中，日期型常量和字符型常量一样，使用时都用一对引号。例如'1990-01-01'、''2007-01-01'。</p>
<p>例如：在student1表中，查询出生日期是&#8220;1984-03-10&#8221;的学生。下面是查询前和查询后的结果，如图4.18所示。</p>
<p><img height="235" src="http://book.csdn.net/BookFiles/659/img/image090.jpg" width="277"  alt="" /></p>
<p>图4.18&nbsp; 查询出生日期是&#8220;1984-03-10&#8221;</p>
<p>在查询分析器中输入SQL语句如下：</p>
<p>use student</p>
<p>select * </p>
<p>from student1</p>
<p>where 出生日期='1984-03-10'</p>
<p style="text-indent: 20pt"><img height="16" alt="*" src="http://book.csdn.net/BookFiles/659/img/image072.gif" width="20" />&nbsp;&nbsp; 注意：在使用日期函数时，其日期值应在1753-9999年之间，这是SQL Server系统所能识别的日期范围，否则会出现错误。</p>
<p>（2）按月查询数据</p>
<p>当使用日期型数据进行查询时，经常按月份查询，用MONTH（）函数可以从日期型数据中提取月份数据。该函数的语法：</p>
<p>MONTH（date）</p>
<p>MONTH（）函数能够将日期时间表达式date中的月份返回，返回的月份是以数值１～12来表示，1代表一月、2代表二月&#8230;其余依此类推。</p>
<p style="text-indent: 20pt"><img height="16" alt="*" src="http://book.csdn.net/BookFiles/659/img/image072.gif" width="20" />&nbsp;&nbsp; 注意：日期时间表达式date必须是datetime或smalldatetime数据类型，值得注意的是，如果将date设置为0，SQL Server会将0视为1900年1月1日。</p>
<p>例如：在student1表中，查询3月份出生的学生信息。下面是查询前和查询后的结果，如图4.19所示。</p>
<p><img height="235" src="http://book.csdn.net/BookFiles/659/img/image091.jpg" width="277"  alt="" /></p>
<p>图4.19&nbsp; 查询3月份出生的学生</p>
<p>在查询分析器中输入SQL语句如下：</p>
<p>use student</p>
<p>select * </p>
<p>from student1</p>
<p>where month(出生日期)='3'</p>
<p>（3）查询指定时间段的数据</p>
<p>要实现对指定日期时间段数据的查询，须在SQL语句中使用BETWEEN...AND。</p>
<p>例如：在student1表中，查询出生日期在&#8220;1984-01-10&#8221;和&#8220;1986-01-01&#8221;之间的学生信息。下面是查询前和查询后的结果，如图4.20所示。</p>
<p><img height="235" src="http://book.csdn.net/BookFiles/659/img/image092.jpg" width="277"  alt="" /></p>
<p>图4.20&nbsp; 按时间段查询学生信息</p>
<p>在查询分析器中输入如下SQL语句。</p>
<p>use student</p>
<p>select * </p>
<p>from student1</p>
<p>where 出生日期&nbsp; between '1984-01-01' and '1986-01-01'</p>
<img src ="http://www.cnblogs.com/Harlan/aggbug/1200653.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/42930/" target="_blank">[新闻]Silverlight 2.0正式版下周发布</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/Harlan/archive/2008/05/16/1200589.html</link><dc:creator>Harlan---</dc:creator><author>Harlan---</author><pubDate>Fri, 16 May 2008 06:31:00 GMT</pubDate><guid>http://www.cnblogs.com/Harlan/archive/2008/05/16/1200589.html</guid><wfw:comment>http://www.cnblogs.com/Harlan/comments/1200589.html</wfw:comment><comments>http://www.cnblogs.com/Harlan/archive/2008/05/16/1200589.html#Feedback</comments><slash:comments>6</slash:comments><wfw:commentRss>http://www.cnblogs.com/Harlan/comments/commentRss/1200589.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/Harlan/services/trackbacks/1200589.html</trackback:ping><description><![CDATA[来分析这样一种实际情况，即，在HTTP处理程序处理请求之前对请求进行筛选，这有助于实现一个原本不可能的特征。回发机制有一个严重的缺陷——如果用户刷新当前显示页面，则服务器上所采取的最后一个动作将盲目地重复。例如，如果作为前一次发送的结果添加了一个新记录，则应用程序会在另一次回发时试图插入一个完全相同的记录。当然，这会导致插入完全相同的记录，因而应当产生一个异常。这一缺陷自Web编程最先出现时就已经存在了，ASP.NET无疑不会引入它。要实现非重复的动作，必须采取一些对策，本质上将任何关键的服务器端操作转换为一个幂等性。在代数中，如果一个操作不管对它执行多少次结果都不变，我们就说该操作是幂等的。例如，看一看如下SQL命令：
<p>DELETE FROM employees WHERE employeeid=9</p>
<p>我们可以对该命令连续执行1000次，但是最多只会删掉1个记录，即满足WHERE子句中设定的标准的记录。另请考虑如下命令：</p>
<p>INSERT INTO employees VALUES (...)</p>
<p>每次执行该命令，都有可能把一个新记录添加到employees表中。如果存在自动编码的键列或者非惟一的列，尤其会出现这种情况。如果表设计要求键是惟一的并且明确加以规定，则第2次运行该命令时会抛出一个SQL异常。</p>
<p>虽然刚才考虑的特殊情况通常在数据访问层(data access layer，简称DAL)解决，但是它的基本模式代表了大多数Web应用程序的一个常见方案。因此，待研究的问题是：怎样查明页面是因为一个显式的用户操作被回传，还是因为用户按下了F5键或页面刷新工具栏按钮呢？</p>
<p>1. 页面刷新操作的基本原理</p>
<p>页面刷新操作是一种内部浏览器操作，对此浏览器不会根据事件或回调提供任何外部通知。从技术上讲，页面刷新是由最新请求的&#8220;简单的&#8221;重复组成的。浏览器缓存它所服务的最新请求，并在用户按下页面刷新键或按钮时重新显示。我所知道的浏览器不会为页面刷新事件提供任何类型通知——即使有，无疑也不是一种公认标准。</p>
<p>据此可知，服务器端代码(例如，ASP.NET、经典ASP或ISAPI DLL)无法将刷新请求与一般的提交或回发请求相区分。为了帮助ASP.NET检测和处理页面刷新，我们需要创建外围机制，使两个在其他方面相同的请求看起来不同。所有已知的浏览器都是通过重新发送最后发送的HTTP请求来实现刷新；为了使该副本不同于原始请求，一个额外的服务必须添加其他参数，而ASP.NET页面必须能够捕获它们。</p>
<p>我考虑了一些附加需求。解决方案不应依赖会话状态，而且不应使服务器内存负荷太重。它应该是相对容易部署的，而且应尽量不引人注目。</p>
<p>2. 解决方案的概要描述</p>
<p>本解决方案基于如下思想：每个请求被分配一个标签号，而HTTP模块将跟踪它处理的每个不同页面里最后服务的标签。如果该页面持有的标签号小于该页面的最后服务的标签，则只能表明服务了相同的请求——即，页面刷新。该解决方案由两个构造块组成：一个HTTP模块和一个自定义的页面类，前者对标签号作初步检查，后者自动地将一个渐进的标签号码添加到每个服务过的页面。使该特征起作用涉及两个步骤：首先，注册该HTTP模块；其次，在相关的应用程序中改变每个页面的基本的代码隐藏类以检测浏览器刷新。</p>
<p>HTTP模块位于HTTP运行库环境的中间，登记应用程序中的一个资源的每个请求。页面第一次被请求时(不是回发时)，不分配任何标签。HTTP模块将生成一个新的标签号，并把它存储在HttpContext对象的Items集合中。此外，该模块将最后服务的标签的内部计数器初始化为0。随后该页面每次被请求时，该模块都将最后服务的标签与页面标签进行比较。如果页面标签更新一些，则该请求被认为是一次普通的回发；否则，它将被标记为一次页面刷新。表2.6总结了这两种场景及其相关的操作。</p>
<p align="center">表2.6&nbsp; 场景和动作</p>
<div align="center">
<div align="center">
<table style="width: 411.1pt; border-top-style: none; border-right-style: none; border-left-style: none; border-collapse: collapse; border-bottom-style: none" cellspacing="0" cellpadding="0" width="548" border="1">
    <tbody>
        <tr>
            <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; border-top: windowtext 1.5pt solid; padding-left: 5.4pt; background: #d9d9d9; padding-bottom: 0cm; width: 213.05pt; padding-top: 0cm; border-bottom: windowtext 1pt solid; border-left-style: none" valign="top" width="284">
            <p>场&nbsp;&nbsp;&nbsp; 景</p>
            </td>
            <td style="padding-right: 5.4pt; border-top: windowtext 1.5pt solid; padding-left: 5.4pt; background: #d9d9d9; padding-bottom: 0cm; width: 213.05pt; padding-top: 0cm; border-bottom: windowtext 1pt solid; border-right-style: none; border-left-style: none" valign="top" width="284">
            <p>动&nbsp;&nbsp;&nbsp; 作</p>
            </td>
        </tr>
        <tr>
            <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; padding-left: 5.4pt; padding-bottom: 0cm; width: 213.05pt; border-top-style: none; padding-top: 0cm; border-bottom: windowtext 1pt solid; border-left-style: none" valign="top" width="284">
            <p>页面没有相关的标签</p>
            <p>●非刷新</p>
            </td>
            <td style="padding-right: 5.4pt; padding-left: 5.4pt; padding-bottom: 0cm; width: 213.05pt; border-top-style: none; padding-top: 0cm; border-bottom: windowtext 1pt solid; border-right-style: none; border-left-style: none" valign="top" width="284">
            <p>最后服务的标签的计数器设置为0</p>
            <p>生成用于当前页面的下一个请求的标签，并存储在Items集合中</p>
            </td>
        </tr>
        <tr>
            <td style="border-right: windowtext 1pt solid; padding-right: 5.4pt; padding-left: 5.4pt; padding-bottom: 0cm; width: 213.05pt; border-top-style: none; padding-top: 0cm; border-bottom: windowtext 1.5pt solid; border-left-style: none" valign="top" width="284">
            <p>页面有一个关联的标签</p>
            <p style="margin-left: 6.5pt; text-indent: -6.5pt">●如果页面关联的标签小于最后服务的标签，则发生页面刷新</p>
            </td>
            <td style="padding-right: 5.4pt; padding-left: 5.4pt; padding-bottom: 0cm; width: 213.05pt; border-top-style: none; padding-top: 0cm; border-bottom: windowtext 1.5pt solid; border-right-style: none; border-left-style: none" valign="top" width="284">
            <p>最后服务的标签的计数器设置为页面关联的标签。</p>
            <p>生成用于当前页面的下一个请求的标签，并存储在Items集合中</p>
            </td>
        </tr>
    </tbody>
</table>
</div>
</div>
<p style="text-indent: 21.6pt">为了确保每个请求(除了第一次以外)都有一个合适的标签号，需要得到页面类的一些帮助。这就是为什么需要将每个打算支持该特征的页面的代码隐藏类设置为一个特定类——这是我们稍候将讨论的一个过程。该页面类将从HTTP模块接收两种不同的信息：要存储在随页面一起传送的一个隐藏字段中的下一个标签，以及该请求是否为页面刷新的信息。作为对开发人员的一项增值服务，代码隐藏类将提供一个额外的布尔属性：IsRefreshed，以允许开发人员了解请求是页面刷新还是常规回发。</p>
<p style="margin-left: 72pt; text-indent: -72pt"><img height="18" alt="*" src="http://book.csdn.net/bookfiles/172/02/image008.jpg" width="22" />重要提示 &nbsp;&nbsp; HttpContext类上的Items集合是一个载体集合，是为了让HTTP模块将信息向下传递给实际负责服务请求的页面和HTTP处理程序而特意建立的。我们这里采用的HTTP模块在Items集合中设置两个数据项。一个数据项让页面知道请求是否为页面刷新；另一个数据项让页面知道下一个标签号是什么。让HTTP模块将下一个标签号传递给页面，满足使页面类的行为尽可能地简单和线性的目的，从而将大部分实现和执行负担转移给HTTP模块。</p>
<p>3. 解决方案的实现</p>
<p>我刚刚概述的解决方案有几个问题有待研究。首先，状态是必需的，我们把它保存在哪里？其次，对每个输入请求都将调用一个HTTP模块。如何区分对相同页面的请求呢？如何把信息传递给页面呢？你希望页面有多大的智能呢？</p>
<p>显然，这里所列的每个问题，都可以用不同于此处所介绍的方法进行设计和实现。为了得到一个可行的解决方案，这里作出的所有设计选择应当被认为是任意的，如果需要对该代码进行重新加工以更好地满足自己的目的，可以用等效的策略替换它。下一个实例中给出的代码版本，融入了我一直以来所收集的最宝贵的建议。这些建议之一如前一个重要提示所述，尽量将代码移到HTTP模块中。</p>
<p>如下代码展示了该HTTP模块的实现：</p>
<p>public class RefreshModule : IHttpModule</p>
<p>{</p>
<p style="text-indent: 14.7pt">public void Init(HttpApplication app) {</p>
<p style="margin-left: 38.85pt; text-indent: 14.7pt">app.BeginRequest += new EventHandler(OnAcquireRequestState);</p>
<p style="text-indent: 14.7pt">}</p>
<p style="text-indent: 14.7pt">public void Dispose() {</p>
<p style="text-indent: 14.7pt">}</p>
<p style="text-indent: 14.7pt">void OnAcquireRequestState(object sender, EventArgs e) {</p>
<p style="margin-left: 38.85pt; text-indent: 14.7pt">HttpApplication app = (HttpApplication) sender;</p>
<p style="margin-left: 38.85pt; text-indent: 14.7pt">HttpContext ctx = app.Context;</p>
<p style="margin-left: 38.85pt; text-indent: 14.7pt">RefreshAction.Check(ctx);</p>
<p style="margin-left: 38.85pt; text-indent: 14.7pt">return;</p>
<p style="text-indent: 14.7pt">}</p>
<p>}</p>
<p>该模块监听BeginRequest事件，结束调用RefreshAction辅助类上的Check方法。</p>
<p>public class RefreshAction</p>
<p>{</p>
<p style="text-indent: 14.7pt">static Hashtable requestHistory = null;</p>
<p style="text-indent: 14.7pt">// Other string constants defined here</p>
<p style="text-indent: 14.7pt">M</p>
<p style="text-indent: 14.7pt">public static void Check(HttpContext ctx) {</p>
<p style="margin-left: 38.85pt; text-indent: 14.7pt">// Initialize the ticket slot</p>
<p style="margin-left: 38.85pt; text-indent: 14.7pt">EnsureRefreshTicket(ctx);</p>
<p style="margin-left: 38.85pt; text-indent: 14.7pt">// Read the last ticket served in the session (from Session)</p>
<p style="margin-left: 38.85pt; text-indent: 14.7pt">int lastTicket = GetLastRefreshTicket(ctx);</p>
<p style="margin-left: 38.85pt; text-indent: 14.7pt">// Read the ticket of the current request (from a hidden field)</p>
<p style="margin-left: 38.85pt; text-indent: 14.7pt">int thisTicket = GetCurrentRefreshTicket(ctx, lastTicket);</p>
<p style="margin-left: 38.85pt; text-indent: 14.7pt">// Compare tickets</p>
<p style="margin-left: 38.85pt; text-indent: 14.7pt">if (thisTicket &gt; lastTicket ||</p>
<p style="margin-left: 38.85pt; text-indent: 14.7pt">(thisTicket==lastTicket &amp;&amp; thisTicket==0)) {</p>
<p style="margin-left: 2cm; text-indent: 23.1pt">UpdateLastRefreshTicket(ctx, thisTicket);</p>
<p style="margin-left: 38.85pt; text-indent: 14.7pt">ctx.Items[PageRefreshEntry] = false;</p>
<p style="margin-left: 38.85pt; text-indent: 14.7pt">}</p>
<p style="margin-left: 38.85pt; text-indent: 14.7pt">else</p>
<p style="margin-left: 2cm; text-indent: 23.1pt">ctx.Items[PageRefreshEntry] = true;</p>
<p style="text-indent: 14.7pt">}</p>
<p style="text-indent: 14.7pt">// Initialize the internal data store</p>
<p style="text-indent: 14.7pt">static void EnsureRefreshTicket(HttpContext ctx)</p>
<p style="text-indent: 14.7pt">{</p>
<p style="margin-left: 38.85pt; text-indent: 14.7pt">if (requestHistory == null)</p>
<p style="margin-left: 24.15pt; text-indent: 48.3pt">requestHistory = new Hashtable();</p>
<p style="text-indent: 14.7pt">}</p>
<p style="text-indent: 14.7pt">// Return the last-served ticket for the URL</p>
<p style="text-indent: 14.7pt">static int GetLastRefreshTicket(HttpContext ctx)</p>
<p style="text-indent: 14.7pt">{</p>
<p style="margin-left: 38.85pt; text-indent: 14.7pt">// Extract and return the last ticket</p>
<p style="margin-left: 38.85pt; text-indent: 14.7pt">if (!requestHistory.ContainsKey(ctx.Request.Path))</p>
<p style="margin-left: 38.85pt; text-indent: 35.7pt">return 0;</p>
<p style="margin-left: 38.85pt; text-indent: 14.7pt">else</p>
<p style="margin-left: 2cm; text-indent: 18.9pt">return (int) requestHistory[ctx.Request.Path];</p>
<p style="text-indent: 14.7pt">}</p>
<p style="text-indent: 14.7pt">// Return the ticket associated with the page</p>
<p style="text-indent: 14.7pt">static int GetCurrentRefreshTicket(HttpContext ctx, int lastTicket)</p>
<p style="text-indent: 14.7pt">{</p>
<p style="margin-left: 38.85pt; text-indent: 14.7pt">int ticket;</p>
<p style="margin-left: 38.85pt; text-indent: 14.7pt">object o = ctx.Request[CurrentRefreshTicketEntry];</p>
<p style="margin-left: 38.85pt; text-indent: 14.7pt">if (o == null)</p>
<p style="text-indent: 50.4pt">ticket = lastTicket;</p>
<p style="margin-left: 38.85pt; text-indent: 14.7pt">else</p>
<p style="text-indent: 50.4pt">ticket = Convert.ToInt32(o);</p>
<p style="margin-left: 38.85pt; text-indent: 14.7pt">ctx.Items[RefreshAction.NextPageTicketEntry] = ticket + 1;</p>
<p style="margin-left: 38.85pt; text-indent: 14.7pt">return ticket;</p>
<p>}</p>
<p>// Store the last-served ticket for the URL</p>
<p>static void UpdateLastRefreshTicket(HttpContext ctx, int ticket)</p>
<p>{</p>
<p style="margin-left: 38.85pt; text-indent: 14.7pt">requestHistory[ctx.Request.Path] = ticket;</p>
<p style="text-indent: 14.7pt">}</p>
<p>}</p>
<p>Check方法操作如下：它将最后服务的标签(如果有)与页面提供的标签进行比较。该页面将标签号存储在一个通过Request对象接口读入的隐藏字段中。HTTP模块维护一个散列表，服务的每个不同的URL都有一个表项。该散列表中的值存储该URL的最后服务的标签。</p>
<p><sub><img height="27" src="http://book.csdn.net/bookfiles/172/02/image002.jpg" width="18"  alt="" /></sub>&nbsp;注意&nbsp;&nbsp;&nbsp; Item索引器属性，来设置最后服务的标签，因为Item重写已有的项。如果数据项已经存在，则Add方法只是返回。</p>
<p>除了创建HTTP模块，我们还需要安排一个页面类，以用作需要检测浏览器刷新的页面的基类。下面给出了这个页面类的代码：</p>
<p>// Assume to be in a custom namespace</p>
<p>public class Page : System.Web.UI.Page</p>
<p>{</p>
<p style="text-indent: 14.7pt">public bool IsRefreshed {</p>
<p style="text-indent: 23.1pt">get {</p>
<p style="margin-left: 38.85pt; text-indent: 14.7pt">HttpContext ctx = HttpContext.Current;</p>
<p style="margin-left: 38.85pt; text-indent: 14.7pt">object o = ctx.Items[RefreshAction.PageRefreshEntry];</p>
<p style="margin-left: 38.85pt; text-indent: 14.7pt">if (o == null)</p>
<p style="margin-left: 24.15pt; text-indent: 44.1pt">return false;</p>
<p style="margin-left: 38.85pt; text-indent: 14.7pt">return (bool) o;</p>
<p style="text-indent: 14.7pt">}</p>
<p>}</p>
<p>// Handle the PreRenderComplete event</p>
<p>protected override void OnPreRenderComplete(EventArgs e) {</p>
<p style="text-indent: 8.4pt">base.OnPreRenderComplete(e);</p>
<p style="text-indent: 8.4pt">SaveRefreshState();</p>
<p>}</p>
<p>// Create the hidden field to store the current request ticket</p>
<p>private void SaveRefreshState() {</p>
<p style="text-indent: 8.4pt">HttpContext ctx = HttpContext.Current;</p>
<p style="text-indent: 8.4pt">int ticket = (int) ctx.Items[RefreshAction.NextPageTicketEntry];</p>
<p style="text-indent: 8.4pt">ClientScript.RegisterHiddenField(</p>
<p style="text-indent: 16.8pt">RefreshAction.CurrentRefreshTicketEntry,</p>
<p style="text-indent: 16.8pt">ticket.ToString());</p>
<p style="text-indent: 4.2pt">}</p>
<p>}</p>
<p>该示例页面定义了一个新的公共布尔属性IsRefreshed。我们可以在代码中以使用IsPostBack或IsCallback那样的方法使用该属性。该实例页面重写了OnPreRenderComplete方法，用页面标签添加隐藏字段。如前所述，该页面标签是通过Items集合中的一个特别的(并且是任意命名的)项从HTTP模块中得到的。</p>
<p>图2.8展示了一个正在运行的示例页面。</p>
<p align="center"><img height="237" src="http://book.csdn.net/bookfiles/172/02/image013.jpg" width="418"  alt="" /></p>
<p align="center">图2.8&nbsp; 如果用户刷新浏览器的视图，页面没有重复一个敏感的动作</p>
<p style="text-indent: 21pt">下面是该页面的源代码。</p>
<p>public partial class TestRefresh : ProAspNet20.CS.Components.Page</p>
<p>{</p>
<p style="text-indent: 14.7pt">protected void AddContactButton_Click(object sender, EventArgs e)</p>
<p style="text-indent: 14.7pt">{</p>
<p style="margin-left: 38.85pt; text-indent: 14.7pt">Msg.InnerText = "Added";</p>
<p style="margin-left: 38.85pt; text-indent: 14.7pt">if (!this.IsRefreshed)</p>
<p style="margin-left: 2cm; text-indent: 14.7pt">AddRecord(FName.Text, LName.Text);</p>
<p style="margin-left: 38.85pt; text-indent: 14.7pt">else</p>
<p style="margin-left: 2cm; text-indent: 14.7pt">Msg.InnerText = "Page refreshed";</p>
<p style="margin-left: 38.85pt; text-indent: 14.7pt">BindData();</p>
<p style="text-indent: 14.7pt">}</p>
<p style="text-indent: 14.7pt">M</p>
<p>}</p>
<p>IsRefreshed属性允许我们决定在一个回发动作被请求时要做什么。在上述代码中，如果页面正在刷新，则不调用AddRecord方法。不用说，IsRefreshed仅适用于这里介绍的自定义页面类。自定义页面类并非只是添加该属性，它还要添加隐藏字段，这是该机制起作用所必不可少的。<br />
來自&nbsp; ：&nbsp;&nbsp;&nbsp; <iframe style="margin-top: 0px; float: left" border="0" marginwidth="0" framespacing="0" marginheight="0" src="http://wz.csdn.net/vote.aspx?t=2.3.3%20%u9875%u9762%u5237%u65B0%u7279%u5F81%20-%20%u300AASP.NET%202.0%u9AD8%u7EA7%u7F16%u7A0B%u300B%20-%20%u514D%u8D39%u8BD5%u8BFB%20-%20book.csdn.net&amp;u=http%3A//book.csdn.net/bookfiles/172/1001727755.shtml" frameborder="0" noResize width="54" scrolling="no" height="75"></iframe>ASP.NET 2.0高级编程 一書</p>
<img src ="http://www.cnblogs.com/Harlan/aggbug/1200589.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/42930/" target="_blank">[新闻]Silverlight 2.0正式版下周发布</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>利用js方法实现html静态页面间参数传递</title><link>http://www.cnblogs.com/Harlan/archive/2008/05/13/1194875.html</link><dc:creator>Harlan---</dc:creator><author>Harlan---</author><pubDate>Tue, 13 May 2008 03:23:00 GMT</pubDate><guid>http://www.cnblogs.com/Harlan/archive/2008/05/13/1194875.html</guid><wfw:comment>http://www.cnblogs.com/Harlan/comments/1194875.html</wfw:comment><comments>http://www.cnblogs.com/Harlan/archive/2008/05/13/1194875.html#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://www.cnblogs.com/Harlan/comments/commentRss/1194875.html</wfw:commentRss><trackback:ping>http://www.cnblogs.com/Harlan/services/trackbacks/1194875.html</trackback:ping><description><![CDATA[<h2>利用js方法实现html静态页面间参数传递<span class="f">&nbsp;</span></h2>
<div class="entry-body nerr" style="display: block">
<p>aa.htm是参数输入界面<br />
bb.htm是参数接收处理界面<br />
aa.htm<br />
&lt;html&gt;<br />
&lt;head&gt;<br />
&lt;/head&gt;<br />
&lt;body&gt;<br />
&lt;script&gt;<br />
function submit()<br />
{<br />
var input1 = document.getElementById("inputid");<br />
window.open("b.html?inputStr=" + input1.value);//传入参数<br />
}<br />
&lt;/script&gt;<br />
&lt;input type = "text" id = "inputid"&gt;<br />
&lt;input type = "button" onclick = "submit()" value = "提交"&gt;<br />
&lt;/body&gt;<br />
&lt;/html&gt;</p>
<p>bb.htm:<br />
&lt;html&gt;<br />
&lt;head&gt;<br />
&lt;script&gt;<br />
//获得参数的方法<br />
var request = <br />
{ <br />
QueryString : function(val) <br />
{ <br />
var uri = window.location.search; <br />
var re = new RegExp("" +val+ "=([^&amp;?]*)", "ig"); <br />
return ((uri.match(re))?(uri.match(re)[0].substr(val.length+1)):null); <br />
} <br />
} </p>
<p>&lt;/script&gt;</p>
<p>&lt;/head&gt;<br />
&lt;body&gt;<br />
&lt;script&gt;<br />
//调用方法获得参数<br />
var rt = request.QueryString("inputStr");<br />
alert(rt);<br />
&lt;/script&gt;<br />
&lt;/body&gt;<br />
&lt;/html&gt; </p>
</div>
<p id="trackback">你可以通过这个链接引用该篇文章:http://ranjunliu.bokee.com/viewdiary.13398085.html </p>
<img src ="http://www.cnblogs.com/Harlan/aggbug/1194875.html?type=1" width = "1" height = "1" /><br><br><a href="http://news.cnblogs.com/n/42925/" target="_blank">[新闻]Wikipedia“变心”，力挺Ubuntu</a><br/><a href="http://www.cnblogs.com" target="_blank">博客园首页</a>&nbsp;<a href="http://space.cnblogs.com" target="_blank">社区</a>&