2006-10-05

中国古代军规

十七禁律、五十四斩

其一:闻鼓不进,闻金不止,旗举不起,旗按不伏,此谓悖军,犯者斩之。
其二:呼名不应,点时不到,违期不至,动改师律,此谓慢军,犯者斩之。
其三:夜传刁斗,怠而不报,更筹违慢,声号不明,此谓懈军,犯者斩之。
其四:多出怨言,怒其主将,不听约束,更教难制,此谓构军,犯者斩之。
其五:扬声笑语,蔑视禁约,驰突军门,此谓轻军,犯者斩之。

其六:所用兵器,弓弩绝弦,箭无羽镞,剑戟不利,旗帜凋弊,此谓欺军,犯者斩之。
其七:谣言诡语,捏造鬼神,假托梦寐,大肆邪说,蛊惑军士,此谓淫军,犯者斩之。
其八:好舌利齿,妄为是非,调拨军士,令其不和,此谓谤军,犯者斩之。
其九:所到之地,凌虐其民,如有逼淫妇女,此谓奸军,犯者斩之。
其十:窃人财物,以为己利,夺人首级,以为己功,此谓盗军,犯者斩之。

其十一:军民聚众议事,私进帐下,探听军机,此谓探军,犯者斩之。
其十二:或闻所谋,及闻号令,漏泄於外,使敌人知之,此谓背军,犯者斩之。
其十三:调用之际,结舌不应,低眉俯首,面有难色,此谓狠军,犯者斩之。
其十四:出越行伍,搀前越后,言语喧哗,不遵禁训,此谓乱军,犯者斩之。
其十五:托伤作病,以避征伐,捏伤假死,因而逃避,此谓诈军,犯者斩之。

其十六:主掌钱粮,给赏之时阿私所亲,使士卒结怨,此谓弊军,犯者斩之。
其十七:观寇不审,探贼不详,到不言到,多则言少,少则言多,此谓误军,犯者斩之。

2006-09-29

在 MS SQL Server 中限制返回记录数量的 3 种方法

在使用海量数据的时候,限制返回记录的数量是必须的,将所有记录返回很容易使数据库陷入死状态。

对于 Microsoft SQL Server 来说,提供了3种方法来完成这个功能:

1. 使用 TOP 选项。TOP 选项提供了最简单的方式限制返回记录数量,语法如下:

SELECT [ TOP (expression) [ PERCENT ] [ WITH TIES ]] select_list [ other_select_command ]

参数

1. expression. 指定返回行数量的数值,可以是常量或者变量。如果指定了 PERCENT ,则 expression 将转换为 float 类型;如果没有指定 PERCENT ,则 expression 将转换为 bigint 类型。如果查询中包含 ORDER BY 子句,则返回的记录集为排序后的前项记录;如果没有包含 ORDER BY 子句,则返回行的顺序是随意的。

2. PERCENT. 指示限定记录数量的类型。如果指定了 PERCENT ,则按照总数量的百分比计算返回数量;如果没有指定 PERCENT , 则按照返回记录集的行数量来计算。

3. WITH TIES. 指示返回额外的行,只能与 ORDER BY 一起使用。使用此选项时,排序后返回指定数量的记录行,与这些记录集最后一行排序字段相同的行也会返回。所以,返回记录的数量可能会比指定数量要大。

示例代码

SELECT TOP (10) * FROM table1 ORDER BY column1

2. 使用 SET ROWCOUNT 选项。 SET ROWCOUNT 改变了当前环境下返回记录数量的值,语法如下:

SET ROWCOUNT expression

参数

1. expression. 在停止特定查询之前要处理的行数,可以是常量或变量,类型为整形。

执行此命令后, SQL Server 将在执行 SELECT 语句时,返回指定的行数后停止查询。如果需要关闭此选项,执行 SET ROWCOUNT 0 即可。

示例代码

SET ROWCOUNT 10
SELECT * FROM table1 ORDER BY column1
SET ROWCOUNT 0

3. 使用 ROW_NUMBER 函数。 ROW_NUMBER 函数返回当前行对应的行号,每个分区的第一行从 1 开始,语法如下:

ROW_NUMBER ( ) OVER ( [ PARTITION BY partition_name [ , partition_name ] ] ORDER BY order_name [ , order_name ] )

参数

1. partition_name. 根据此列名确认 ROW_NUMBER 函数结果集分区范围。如果此字段未填,则所有计算行号;如果此字段填写,则根据相同结果集分区的记录计算行号,结果集分区不同的记录重新从1开始计算行号。

2. order_name. 根据此列名确定返回行的顺序,计算出行号。

示例代码

SELECT * FROM ( SELECT *, ROW_NUMBER ( ) OVER ( ORDER BY column1 ) AS rowNumber FROM table1 ) AS T WHERE rowNumber < 10

上面列出了 SQL Server 限制返回记录数量的 3 种方法,这 3 种方法均支持常量和变量。 TOP 的使用方法最简单,如果仅仅是限制返回数量,建议使用这种方式;如果要进行分页和结果集分区计算,那么就要使用 ROW_NUMBER 函数了。

2006-09-27

侠客行

作者:李白

赵客缦胡缨,吴钩霜雪明。
银鞍照白马,疯沓如流星。

十步杀一人,千里不留行。
事了拂衣去,深藏身与名。

闲过信陵饮,脱剑膝前横。
将炙啖朱亥,持觞劝侯嬴。

三杯吐然诺,五岳倒为轻。
眼花耳热后,意气素霓生。

救赵挥金锤,邯郸先震惊。
千秋二壮士,烜赫大梁城。

纵死侠骨香,不惭世上英。
谁能书阁下,白首太玄经?

2006-09-26

Beautiful Life

Artist: Ace of Base

You can do what you want
Just seize the day
What you're doing tomorrow's
Gonna come your way
Don't you ever consider giving up
You will find, oooh

It's a beautiful life, oooh
It's a beautiful life, oooh
It's a beautiful life, oooh
I wanna be here beside you
And stay until the break of dawn

Take a walk in the park when you feel down
There're so many things there
That's gonna lift you up
See the nature in bloom a laughing child
Such a dream, oooh

I wanna be here beside you
I wanna be here beside you
And stay until the break of dawn
You're looking for somewhere to belong
You're standing all alone
For someone to guide you on your way
Now and forever, oooh

I just wanna be anybody
We're living in different ways
It's a beautiful life

I'm gonna take you to a place
I've never been before
Oh, yeah
It's a beautiful life

I'm gonna take you in my arms
And fly away with you tonight
Oh, yeah, alright
It's a beautiful life
Yeah, alright
It's a beautiful life

It's a beautiful life

It's a beautiful life

2006-09-25

使用 HttpWebRequest 向网站提交数据

HttpWebRequest 是 .net 基类库中的一个类,在命名空间 System.Net 下面,用来使用户通过 HTTP 协议和服务器交互。

HttpWebRequest 对 HTTP 协议进行了完整的封装,对 HTTP 协议中的 Header, Content, Cookie 都做了属性和方法的支持,很容易就能编写出一个模拟浏览器自动登录的程序。

程序使用 HTTP 协议和服务器交互主要是进行数据的提交,通常数据的提交是通过 GET 和 POST 两种方式来完成,下面对这两种方式进行一下说明:

1. GET 方式。 GET 方式通过在网络地址附加参数来完成数据的提交,比如在地址 http://www.google.com/webhp?hl=zh-CN 中,前面部分 http://www.google.com/webhp 表示数据提交的网址,后面部分 hl=zh-CN 表示附加的参数,其中 hl 表示一个键(key), zh-CN 表示这个键对应的值(value)。程序代码如下:

HttpWebRequest req = (HttpWebRequest) HttpWebRequest.Create( "http://www.google.com/webhp?hl=zh-CN" );
req.Method = "GET";
using (WebResponse wr = req.GetResponse())
{
   //在这里对接收到的页面内容进行处理
}

2. POST 方式。 POST 方式通过在页面内容中填写参数的方法来完成数据的提交,参数的格式和 GET 方式一样,是类似于 hl=zh-CN&newwindow=1 这样的结构。程序代码如下:

string param = "hl=zh-CN&newwindow=1";
byte[] bs = Encoding.ASCII.GetBytes(param);

HttpWebRequest req = (HttpWebRequest) HttpWebRequest.Create( "http://www.google.com/intl/zh-CN/" );
req.Method = "POST";
req.ContentType = "application/x-www-form-urlencoded";
req.ContentLength = bs.Length;

using (Stream reqStream = req.GetRequestStream())
{
   reqStream.Write(bs, 0, bs.Length);
}
using (WebResponse wr = req.GetResponse())
{
   //在这里对接收到的页面内容进行处理
}

在上面的代码中,我们访问了 www.google.com 的网址,分别以 GET 和 POST 方式提交了数据,并接收了返回的页面内容。然而,如果提交的参数中含有中文,那么这样的处理是不够的,需要对其进行编码,让对方网站能够识别。

3. 使用 GET 方式提交中文数据。 GET 方式通过在网络地址中附加参数来完成数据提交,对于中文的编码,常用的有 gb2312 和 utf8 两种,用 gb2312 方式编码访问的程序代码如下:

Encoding myEncoding = Encoding.GetEncoding("gb2312");
string address = "http://www.baidu.com/s?" + HttpUtility.UrlEncode("参数一", myEncoding) + "=" + HttpUtility.UrlEncode("值一", myEncoding);
HttpWebRequest req = (HttpWebRequest)HttpWebRequest.Create(address);
req.Method = "GET";
using (WebResponse wr = req.GetResponse())
{
   //在这里对接收到的页面内容进行处理
}

在上面的程序代码中,我们以 GET 方式访问了网址 http://www.baidu.com/s ,传递了参数“参数一=值一”,由于无法告知对方提交数据的编码类型,所以编码方式要以对方的网站为标准。常见的网站中, www.baidu.com (百度)的编码方式是 gb2312, www.google.com (谷歌)的编码方式是 utf8。

4. 使用 POST 方式提交中文数据。 POST 方式通过在页面内容中填写参数的方法来完成数据的提交,由于提交的参数中可以说明使用的编码方式,所以理论上能获得更大的兼容性。用 gb2312 方式编码访问的程序代码如下:

Encoding myEncoding = Encoding.GetEncoding("gb2312");
string param = HttpUtility.UrlEncode("参数一", myEncoding) + "=" + HttpUtility.UrlEncode("值一", myEncoding) + "&" + HttpUtility.UrlEncode("参数二", myEncoding) + "=" + HttpUtility.UrlEncode("值二", myEncoding);

byte[] postBytes = Encoding.ASCII.GetBytes(param);

HttpWebRequest req = (HttpWebRequest) HttpWebRequest.Create( "http://www.baidu.com/s" );
req.Method = "POST";
req.ContentType = "application/x-www-form-urlencoded;charset=gb2312";
req.ContentLength = postBytes.Length;

using (Stream reqStream = req.GetRequestStream())
{
   reqStream.Write(bs, 0, bs.Length);
}
using (WebResponse wr = req.GetResponse())
{
   //在这里对接收到的页面内容进行处理
}

从上面的代码可以看出, POST 中文数据的时候,先使用 UrlEncode 方法将中文字符转换为编码后的 ASCII 码,然后提交到服务器,提交的时候可以说明编码的方式,用来使对方服务器能够正确的解析。

以上列出了客户端程序使用 HTTP 协议与服务器交互的情况,常用的是 GET 和 POST 方式。现在流行的 WebService 也是通过 HTTP 协议来交互的,使用的是 POST 方法。与以上稍有所不同的是, WebService 提交的数据内容和接收到的数据内容都是使用了 XML 方式编码。所以, HttpWebRequest 也可以使用在调用 WebService 的情况下。

2006-09-21

ASP.NET 1.1 基于Forms的身份验证

ASP.NET 1.1 中已包含 Windows, Forms, Passport 三种身份验证功能,其中 Windows 是基于 Windows 操作系统的用户验证,Passport 是基于 Microsoft Passport 的用户验证,这两种的适用范围都太窄,而 Forms 验证则可以手动控制用户登录过程,比较适合使用。
构建基于 Forms 的身份验证过程如下:
1. 设置 IIS 为可匿名访问,在 asp.net 配置文件 web.config 中设置验证模式为 Forms 验证,并设置登录页面。
<configuration>
  <system.web>
    <authentication mode="Forms">
      <forms name="name" loginUrl="/login.aspx" protection="None" timeout="30" path="/" requireSSL="false" slidingExpiration="false" />
    </authentication>
  </system.web>
</configuration>
2. 处理用户登录逻辑,查询出用户所属于的角色。
3. 构造 FormsAuthenticationTicket 对象,将其加密后保存到 cookie 中。
FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(
     1,
     userName,
     DateTime.Now,
     DateTime.Now.AddMinutes(30),
     isPersistent,
     "roleA,roleB,roleC",  //角色列表,用逗号区分,可以自定义
     FormsAuthentication.FormsCookiePath);

string encTicket = FormsAuthentication.Encrypt(ticket);
Response.Cookies.Add(new HttpCookie(FormsAuthentication.FormsCookieName, encTicket));
4. 在 AuthenticateRequest 事件中( Global.asax 中包含一个对应的默认函数 Application_AuthenticateRequest ),恢复出 FormsAuthenticationTicket 对象,创建对应的 IPrincipal 对象并保存在 HttpContext.User 中。
HttpCookie authCookie = Context.Request.Cookies[FormsAuthentication.FormsCookieName];
if (authCookie!=null)
{
    FormsAuthenticationTicket authTicket = FormsAuthentication.Decrypt(authCookie.Value);
    string[] roles = authTicket.UserData.Split(new char[]{','});
    Context.User = new GenericPrincipal(Context.User.Identity, roles);
}
5. 对指定页面设定角色控制。
1. 在子目录中添加 web.config 配置文件,修改对整个子目录的访问权限。
<configuration>
  <system.web>
    <authorization>
      <allow roles="RoleName" />
      <deny users="*" />
    </authorization>
  </system.web>
</configuration>
2. 修改当前目录的 web.config 配置文件,为单独的页面修改访问权限。
<configuration>
  <system.web>
    <location path="EditPost.aspx">
      <system.web>
        <authorization>
          <allow roles="RoleName" />
          <deny users="*" />
        </authorization>
      </system.web>
    </location>
  </system.web>
</configuration>
3. 直接在页面中判断用户对应的角色。
if (User.IsInRole("RoleA"))
{
    //用户属于角色 RoleA ,处理...
}
4. 以上步骤均可以达到需要的效果,优先级为1>2>3。

2006-09-20

登广武古战场怀古

作者:李白

秦鹿奔野草,逐之若飞蓬。
项王气盖世,紫电明双瞳。
呼吸八千人,横行起江东。
赤精斩白帝,叱咤入关中。

两龙不并跃,五纬与天同。
楚灭无英图,汉兴有来功。
按剑清八极,归酣歌大风。
伊昔临广武,连兵决雌雄。

分我一杯羹,太皇乃汝翁。
战争有古迹,壁垒颓层穹。
猛虎啸洞壑,饥鹰鸣秋空。
翔云列晓阵,杀气赫长虹。

拨乱属豪杰,俗儒安可通。
沈湎呼竖子,狂言非至公。
抚掌黄河曲,嗤嗤阮嗣宗。