Main

它它它它 Archives

手把手教你在ASP中使用SQL语句

[idea] [idea]
五花八门的SQL产品多得要命,或许你早顾不得其它甩开袖子就动手干了。但你要同时采用ASP和SQL的话就可能会头晕。MySQL、SQL Server和mSQL都是绝佳的SQL工具,可惜,在ASP的环境下你却用不着它们来创建实用的SQL语句。不过,你可以利用自己掌握的Access知识以及相应的Access技能,再加上我们的提示和技巧,相信一定能成功地在你的ASP网页中加入SQL。

1. SELECT 语句

在SQL的世界里,最最基础的操作就是SELECT 语句了。在数据库工具下直接采用SQL的时候很多人都会熟悉下面的操作:
SELECT what
FROM whichTable
WHERE criteria

执行以上语句就会创建一个存放其结果的查询。

而在ASP页面文件上,你也可以采用以上的一般语法,不过情况稍微不同,ASP编程的时候,SELECT 语句的内容要作为字符串赋给一个变量:
SQL = "SELECT what FROM whichTable WHERE criteria"

好了,明白了ASP下SQL“说话”的方式,接下来如法炮制即可,只要满足你的需要,传统的SQL查询模式和条件查询都能派用场。

举例说明,不妨假设你的数据库内有个数据表,名字是Products ,现在你想取出这个表里的全部记录。然后你就编写了下面的代码:
SQL ="SELECT * FROM Products"

以上代码——SQL语句的作用就是取出表内的全部数据——执行后将会选出数据表内的全部记录。不过,要是只想从表内取出某个特定列,比如p_name。那就不能用 * 通配符了,这里得键入具体某列的名字,代码如下:
SQL ="SELECT p_name FROM Products"

执行以上查询之后Products 表内、p_name 列的内容就会全被选取出来。

2. 用WHERE子句设置查询条件

有的时候取出全部数据库记录也许正好满足你的要求,不过,在大多数情况下我们通常只需得到部分记录。这样一来该如何设计查询呢?当然会更费点脑筋了,何况本文也存心不想让你去用那个什么劳什子的recordset。

举个例子,假如你只打算取出p_name 记录,而且这些记录的名字必须以字母w打头,那么你就要用到下面的WHERE 子句了:
SQL ="SELECT p_name FROM Products WHERE p_name LIKE 'W%'"

WHERE 关键词的后面跟着用来过滤数据的条件,有了这些条件的帮助,只有满足一定标准的数据才会被查询出来。在以上的例子里,查询的结果只会得到名字以w 打头的p_name 记录。

以上例子中,百分比符号(%)的含义是指示查询返回所有w 字母打头而且后面是任何数据甚至没有数据的记录条目。所以,在执行以上查询的时候, west 和 willow 就会从Products 表内被选取出来并存放在查询里。

就像你看到的那样,只要仔细地设计SELECT 语句,你就可以限制recordset 中返回的信息量,多琢磨琢磨总能满足你的要求。

这些啊还不过是掌握SQL用途刚起步。为了帮助你逐步掌握复杂的SELECT 语句用法,下面就让我们再来看一下关键的标准术语:比较运算符,这些玩意都是你在构筑自己的SELECT 字符串来获得特定数据时要经常用到的。

WHERE子句基础
在开始创建WHERE 子句的时候,最简单的方式是采用标准的比较符号,它们是 < 、 <= 、 > 、 >= 、<> 和 =。显然,你很快就能明白以下代码的含义和具体运行结果:
SELECT * FROM Products WHERE p_price >= 199.95
SELECT * FROM Products WHERE p_price <> 19.95
SELECT * FROM Products WHERE p_version = '4'

注意: 这里你会注意到,最后一个例句中的数字4周围加了单引号。原因是这样的,在这个例子中的 '4' 是文本类型而非数字类型。因为你会把 SELECT 语句放到引号中来把它作为一个值赋给变量,所以你也可以在语句中采用引号。

比较运算符

比较运算符指定从表内取出数据的内容范围。你可以用它们来创建过滤器以便缩小recordset的范围,促使其只保存给定任务下你关心的信息。

3. LIKE 、 NOT LIKE和 BETWEEN

你已经在上面取出w打头记录的例子中看到了LIKE的用法。LIKE判定词是一个非常有用的符号。不过,在很多情况下用了它可能会带给你太多的数据,所以在用到它之前最好先开动脑筋多想想自己到底想获得什么数据。假设你想取出5位数字的SKU号码,而且其开头是1结尾是5,那么你可以用下划符(_)代替%符号:
SQL = "SELECT * FROM Products WHERE p_sku LIKE '1___5'"

下划符表示任意一个字符。所以在输入“1 _ _ _ 5”的情况下,你的搜索就会限制在满足特定模式的5位数范围内了。

假如你想反其道而行之,要找出所有不匹配“1_ _ _ 5”模式的SKU条目。那么你只需要在刚才语句例子中的LIKE前面加上NOT就可以了。

BETWEEN
假设你想取出一定范围内的数据,而且你事先知道范围的起点和终点,那么你不妨采用BETWEEN 判断词。现在就让我们假设你想选取给定表内范围在 1和 10之间的记录。你可以如下使用BETWEEN:
…WHERE ID BETWEEN 1 AND 10

或者你也可以采用已经熟悉的数学判断字句:
…WHERE ID >= 1 AND ID >= 10

4. 联合语句

我们到目前为止所谈到的SQL语句相对较为简单,如果再能通过标准的recordset循环查询,那么这些语句也能满足一些更复杂的要求。不过,何必非要拘泥在浅尝则止的基础水准之上呢?你完全可以再增加其他一些符号,比如AND、 OR和NOT来完成更强大的功能。

以下面的SQL语句为例:
SQL ="SELECT c_firstname, c_lastname, c_email FROM customers WHERE c_email IS
NOT NULL AND c_purchase = '1' OR c_purchase = '2' AND c_lastname LIKE
'A%'"

就你目前所掌握的SQL知识,以上的例子也不难解释,不过上面的语句并没有很明白地让你看清条件字句是如何胶合在单一SQL语句中的。

多行语句
在SQL语句不好懂的情况下,你不妨把整个语句分解为多行代码,然后在现有变量基础上逐步增加查询语句的各个组成部分并把它存在同一变量内:
SQL = "SELECT c_firstname, c_lastname, c_emailaddress, c_phone"
SQL = SQL & " FROM customers"
SQL = SQL & " WHERE c_firstname LIKE 'A%' and c_emailaddress NOT NULL"
SQL = SQL & " ORDER BY c_lastname, c_firstname"
到了最后一句,SQL变量就包含了以下的完整SELECT 语句:
"SELECT c_firstname, c_lastname, c_emailaddress, c_phone FROM customers
WHERE c_firstname LIKE 'A%' and c_emailaddress NO NULL ORDER BY c_lastname,
c_firstname"

整句照上面分解之后显然好读多了!在进行调试的时候,你或许更乐于多敲几个字符把程序改得更好读些。不过你可要记住了,在封闭引号之前或者在打开引号之后你需要增加空格,这样才能保证字符串连接起来的时候你没有把几个词凑到了一块。
5. 开始执行

在学会了SELECT语句的构造和用途之后你就该学习如何使用它了。在你所掌握的数据库工具下,这可能意味着你得按下某个写着“执行”字样的按钮。在ASP网页上,可以立即执行SQL语句也可以当作存储过程调用。

一旦创建了SQL 语句,你还得设法访问其查询结果。显然,这里的关键就是ASP recordset。在使用非SQL的recordset时,创建recordset的代码通常如下所示:
Dim objRec
Set objRec = Server.CreateObject ("ADODB.Recordset")
objRec.Open "customers", objConn, 0, 1, 2

如果你对ASP比较熟悉以上的代码对你可就不陌生了,你应该知道“customers”表示你打开数据库内一个数据表的名字。

打开recordset
为了充分利用你更为熟悉的SQL技能,你需要调整常规ASP网页上最常采用的recordset:
Dim objRec
Set objRec = Server.CreateObject ("ADODB.Recordset")
objRec.Open SQL, objConn, 0, 1, 2

这里唯一的修改就是在objRec.Open,之后用包含SQL语句的变量代替了要查询的数据表的名称。

这种方法的优点之一是你可以指定游标类型(如以上0, 1 ,2 所示)。

执行SQL
你可以用紧凑的一行代码执行SQL语句来创建recordset。以下是语法:
Dim objRec
set objRec = objConn.Execute(SQL)

在上例中,你所看到的SQL是你存放自己SQL SELECT 语句的变量。该代码行“运行”SQL语句(或者说对数据库进行查询),选取数据并把数据存放在recordset 内,在上例中就是变量objRec。这种方法的主要缺点是你不能选择自己想采用的游标类型。相反,recordset总是用前向游标打开。

因为游标的缘故,你或许打算熟悉两种创建recordset的方法。直接执行查询节省了键入字符所消耗的时间,但那样的话你就得采用默认的游标了,这样有可能遭遇经常不能正常运行的毛病。不管你具体采用哪种办法,两者之间的最大的差别也不外乎代码精练与否。在不考虑你取得什么字段、你的标准是什么的前提下,也不管你如何存储数据,采用SQL式的recordset 在体积上会比ASP上打开的标准recordset 要小得多,更别提操作起来的简易性了。毕竟,通过过滤数据,你消除了耗费时间的if-then 测试和可能用到的循环。

编写测试用SQL
这里有个技巧,许多专业ASP程序员习惯在测试网页的时候“编写”自己的SQL语句。这样做可以帮助你调试代码,因为你可以从中看到传递给服务器执行的字符串。而你要做的无非是增加Response.WriteyourVariable 在屏幕上显示有关信息。在你把和SQL有关的问题提交给ASP讨论组的时候你就应该附上这些信息。

6. 存储查询

当你的查询相对简单的时候,每次从头开始创建SQL语句也不费什么工夫,不过,复杂的查询就不同了,每次都从头来会产生很多开发错误。因此,一旦让SQL顺利地运行起来,你最好把它们存起来,在需要时再调用它们。这样,哪怕是一个简单查询你都能随时用上存储的查询语句了。

假设你每周都要给团队做一次报告,指出目前存在的业务支持问题,这些数据需要从你的数据库中选取,而且要按照日期选择记录,同时根据你所在团队所采用的支持问题的类别排序。一旦你设计了这一查询,你何必以后每周都重新编写一次呢?不要在你的HTML页面上创建查询,你应该用你的数据库工具创建查询并且保存它。

然后你可以采用ActiveCommand 属性把查询插入到你的ASP网页。头一两回你可能会觉得没啥意思,其实也就几行代码而已:
Set objSQ = Server.CreateObject ("ADODB.Command")
objSQ.ActiveConnection = "databaseName"

objSQ.CommandText = "storedQueryName"
objSQ.CommandType = adCmdStoredProc

set objRec = objSQ.Execute

注意,采用adCmdStoredProc 表示你已经在页面上包含了adovbs.inc 文件。该文件定义了你可以按照名字而非数字进行访问的Access常数。只需要在页面上包含该文件即可(<!--#INCLUDE -->),然后你就可以用adCmdStoredProc 这类名字了。这样,将来你再看到的时候更容易理解以上被存储的查询到底是个什么意思。

7. ORDER BY

从Access数据库中选取记录有件最令人丧气的事情,它们是以怎样的顺序输入到数据库内就按照怎样的顺序出来。就算你在Access环境内采用Sort By来改变记录视图,数据表内的记录顺序也并没有发生改变。

如果你正在使用ASPrecordset在网页上写出记录,那么你或许知道乱纷纷的顺序是多令人痛苦的事。但是你可能不得不经常得面对这一问题,因为并不存在什么简单方便的解决方案。好在ORDER BY 可以简化这一难题。

为了对你的结果排序,只要在SELECT语句末尾加上ORDER BY,然后指定你需要排序的参照列即可。因此,如果你想要根据顾客的姓氏对Customers表排序,那么你可以编写如下的查询语句:
SQL = "SELECT c_lastname, c_firstname, c_email FROM Customers ORDER BY c_lastname"

这样,只要你建立了recordset而且开始把结果写到屏幕上,你就会看见数据按照字母顺序排列起来了。

多级排序
其实不仅仅可以在SQL语句中进行一级排序。实际上,在很多情况下,你可能会希望指定两到三级深度的数据排序。假设你有以下数据表,其内容如下所示:

先前采用的单级ORDER BY 排序是按下面的顺序取出数据的:
Absurdly Assured
absurd@assured.com

Absolutely Assured
absolutely@assured.com

Crazed Coder
crazy@coder.net

Loosely Fringe
loose@fringe.to

Lunatic Fringe
lune@fringe.to

Hands On
hands@yes.org

显然ORDER BY 起了应有的作用。在实际的表结构下,Absurdly Assured 是最后的条目,但它排在检索结果的最顶端。Hands On记录排最后因为 O 在以上列表中排在字母表最后。显然,Absolutely按照字母表最好排在Absurdly之前。为此,你需要采取第2级ORDER BY 排序标准,参照第2列进行排序:
SQL = "SELECT c_lastname, c_firstname, c_email FROM Customers ORDER BY
c_lastname, c_firstname"

其结果将首先按照c_lastname 列排序然后按照c_firstname 列排序。假如你的数据表包含的记录比较多,仔细设计排序会令输出结果编排更为合理。

投入使用
如果你同大多数程序员一样喜欢自己动手编代码,沉湎于掌握新技术的狂热之中。何不从ASP的冗长编码中转过头来尝试一下SQL编码呢?下面我们将就ASP编程时常见的问题以及如何在ASP中高效地利用SQL语句做一番探讨。

11. 记录统计

确定数据库内有多少记录,或者确定有多少记录达到了某些标准,这些用ASP完成并非难事。如果你采用了正确的游标类型,你可以用RecordCount 属性获得记录数当然也可以用recordset。但是,有个更简单的办法,这就是在自己的SELECT语句中采用count(*) ,代码如下所示:
SQL = "SELECT count(*) FROM Customers"

或者
SQL = "SELECT count(*) FROM Customers WHERE c_lastname LIKE 'A%'"

举例说明,以下代码将选出一些记录以及这些记录的总数:
SQL = "SELECT c_firstname, c_lastname, count(*) FROM Customers WHERE c_lastname LIKE 'A%'"

但是你不能实现自己的目的。这里采用的“count”函数其实是一种集合函数,意思是只返回单行信息:回答你提出的问题。对第1个SELECT 语句来说,问题是“在客户表内有多少条记录?”查询返回单一的值作为响应,因此它不能同你常规的查询相组合。假如你希望得到其他数据,你需要采用 RecordCount。

集合函数除了“count”之外还包括AVG、MIN、MAX和SUM等。

12. 连接

任何熟悉SQL和关系数据库的人都遇见过大量的连接类型。最简单的说,连接(join)会把两个表的内容组合到一个虚拟表或者recordset内。假如数据表有效地规一化,或许你会经常从某一个表中选出特定的信息再从另一个表中选出关联信息。这样做就需要简单的“同等连接(equijoin)”。

为了了解实际的连接操作,现在让我们假设在一个数据库内存放了某类软件的相关记录。某个表(Software)包含了软件产品的名称、软件的版本以及其他有关细节:

另一个表(Releases)则存储了软件发布历史的信息,其中包括发布日期和发布状态等(比如测试版、当前版、过时等):

上表中还包含了一个列,内容指向软件表中采用的ID号。所以,通过这种索引软件表的方式,你就知道发布表中software_ID 等于 2的软件是Rome。

你采用连接组合信息,这样就不需要在两个表之间来回折腾了。不过,除了组合信息之外还可以通过连接把有关信息合并。这样,只要发布表内的software_ID 匹配软件表内的ID,你就把匹配信息一起放到一个记录内。

代码如下:
SQL = "SELECT * FROM Software, Releases WHERE software.ID = releases.softwareID"

仔细分析以上的语句,首先注意到两个表名列在了FROM的后面。再根据所采用的连接,今后你可能还会发现语法会有所变化(或者连接类型有变),但是以上的语法是最基本的,显示了数据的联合选择方式。这里的WHERE 子句用来比较特定的ID值。在Software 表内,存在ID 列。同样的,Releases 表内则有个software_ID 列。为了明确你在WHERE 子句里要比较的值,你用表名作为前缀,后面还加上了一个点号(.)。

以下是连接选取数据之后的结果:

注意:在创建连接的时候要仔细考虑选出数据的列。以上代码采用 * 通配符是为了让读者关注于SELECT 代码行的其他部分。但是,正如你从上图看到的那样,你无法选出softwareID 列,因为这一列没有作为recordset部分的增加值。它的作用就是为WHERE 子句所用。

网站为什么时快时慢

决定网站的速度有很多因素,我们这里提出主要的四个,具体如下:

1。网络的传输质量
事实上除正常重启外服务器是很少当机的,一年也难得碰上一回。但由于目前国内宽带用户的急剧增长,和不断出现的网络病毒,目前国内的网络并不是很好(相信大家都有感觉),到处都面临着线路切割和扩容。所以会出现部分地区暂时访问很慢甚至不能访问的情况。遇到这样的情况请不要着急,因为你不能访问并不表示人家不能访问,你慢并不表示人家也慢。您可以问问外地的网友,他们如果都正常的话,我们建议您去安心睡一觉,起来以后说不定也就好了。至于睡多少时间,就只能看中国网络的改造效率了:)。如果都打不开,请去 看看有没有什么维护的公告,最后再联系我们解决。

2。服务器的繁忙程度
  服务器上运行的网站并不是只有一个,每个网站又有很多的人访问,就是说服务器工作的时候平均都连接着好几千个用户,任何用户对服务器发出请求的时候,服务器都会调用一定的资源来处理用户的请求,一般动网论坛的一次请求大约能占用3%的CPU和100KB的内存,可以想象,当某一瞬间正好有很多的用户同时发出请求,那么服务器自然会忙不过来,这个时候服务器就需要等待有空余资源再来运行用户的请求,用户端就会出现变慢的情况。
所以理论上,服务器上开设的网站越少,整体速度就越快,但不能保证出现暂时的停顿。对于超强型以上的网站,我们会定期转移到独立的服务器,同时控制单服务器的网站数量,超强型以下的网站,我们会根据服务器的负荷来决定单个服务器的网站数量。
当我们发现某个服务器负荷较大,就会采取转移分流的办法,来解决这个问题,一般一个星期左右就能解决。同时也会严格检查占用大量服务器资源的程序和网站,尽快联系站长进行处理。

3。页面本身的因素
用户打开一个页面,服务器处理完程序后会把页面上的内容传给用户。用户接收完所有的数据以后才能完全打开页面。很明显,当然服务器处理程序很慢或者页面上的内容很大的时候,都会影响用户打开页面的速度。
  服务器处理程序的时间,就是很多论坛下面显示的页面执行时间,由于这个是体现服务器的运算时间,所以这个时间和用户的上网速度是无关的,就是说用户用MODEM和ADSL上网,这个执行时间应该是一样的。
  一般服务器处理程序的时间在1000毫秒以下的时候,用户基本上没任何感觉,因为服务器已经在1000毫秒(1000毫秒=1秒)内处理完所有的内容,剩余的时间都是在传递数据。如果你的页面上涉及的文件很大,比如有1MB的图片在做背景,浏览者和服务器之间,就算能达到100KB/S的速度,他也至少需要10秒钟才能打开这个页面。
  所以我们建议页面上尽量不要放置过多、过大的内容。这也是插件版本的论坛速度慢的原因之一,因为插件版用了大量的图片、FLASH对页面进行了美化,同时在页面上增加了很多显示的内容。

4。ACCESS数据库的原因
  现在网上绝大多数网站都是ACCESS+ASP的形式,因为ACCESS结构简单容易处理,而且也能满足多数的网站程序要求。
  ACCESS是小型数据库,既然是小型就有他根本的局限性,以下几种情况下数据库基本上会吃不消:
  1。数据库过大,一般ACCESS数据库达到50M左右的时候性能会急剧下降!
  2。网站访问频繁,经常达到100人左右的在线。
  3。记录数过多,一般记录数达到10万条左右的时候性能就会急剧下降!
(注:以上3条只是我们多年以来的经验结果,并不只绝对值,具体视情况不同浮动较大)

  ACCESS论坛(如动网)大了以后就很容易出现数据库方面的问题,当你的论坛数据库在30M以上,帖子5万左右,在线也在100人左右的时候,你的论坛基本上都在处理数据库上花时间,这个时候很可能就会出现数据库吃不消的情况。
  一般症状是所有涉及数据库的页面,突然运行都慢的出奇(执行时间达到5秒以上甚至几十秒),涉及HTML和纯ASP运算的页面都正常,等过一段时间(约 10分钟或更长)以后又突然恢复。这个时候你可以用一般ASP探针测试一下,如果服务器的运算时间正常,而你的帖字量又比较大,就是数据库方面的问题了。

  解决方法:
由于这是ACCESS本身的局限性,所以解决的方法除了减少数据量和更换大型的数据库论坛以外也没什么好办法,也就是现在常说的论坛危机,也是大型的论坛都不是ACCESS的原因。我们推荐以下方法:
 1。临时解决办法:定期删除多余的数据、压缩数据库,限制论坛灌水,甚至限制论坛注册。如果是动网论坛,可以使用论坛自带的分表储存功能,会有较好的效果
 2。比较长远办法:更换论坛和数据库,一般都采用动网sql商业版本+MSSQL 的方案来解决,不过这个需要比较大的投资。因为mssql2000和 ACCESS相比需要更多的资源,光是占内存上,就可以达到每一个在线1M以上的程度,如果你的SQL论坛有100人在线就会吃掉服务器至少150M以上内存。

Google Web Accelerator重新开放

在关闭了四个月之后,Google的用于加速网页装载速度的Google Web Accelerator页面重新开放了。但是一些网站的管理人员说,这次的修订版仍然处于Beta阶段,并且没有大张旗鼓地发布。
为了加速网页浏览,这款工具自动从用户正在浏览的网页下载链接。这中新的技术叫做"预读取",在Mozillia Firefox的最新版本中也加入了这个功能。
Google Web Accelerator提前进行预读取并缓存网页内容,就像一个代理服务器一样,所以用户就不会遇到由于网站服务器响应慢和不好的网络环境带来的网速慢的问题。Google在北美和欧洲分别放置了服务器集群来确保在浏览时的快速响应。
然而,今年夏天,有用户报告说Google Web Accelerator可能会下载一些正在编辑和删除的内容的链接,更为严重的是,一些在网络论坛的成员在使用这个工具时发现,它们能够下载其他用户以前上网时缓存过的页面,这意味着他们能够看到其他用户的帐户信息和隐私。
网站管理人员被迫使用一个特殊的HTML标签来探测预读取,以阻挡Google Web Accelerator的进入。
接着,Google迅速关闭了Google Web Accelerate 的下载页面,并声称它已经达到了 它的最大用户数量。公司还说它将充分研究网站管理人员所关注的问题,并重申程序仍然处于Beta阶段。
现在,Google Web Accelerator以2.0版的面貌重新出现了,但是网站的管理人员大喊Google由一次违规了.37signals的David Heinemeier Hansson写道,“它(Google Web Accelerator)从最开始就十分邪恶,而这一次它彻底地引起了恐慌”。David Heinemeier Hansson曾经在使用Google Web Accelerator初始版本时遇到了很多问题,后来他自己写了一个网上的程序叫做"Backpack"。
在1.0版本中能够,网站管理人员至少有机会屏蔽Google Web Accelerator,因为Google Web Accelerator把它所接受的查询请求的内容以'X-moz: prefetch' 的标题头标记。但这次Google在发布Google Web Accelerator的2.0版本时有了一个新的变化:标题头已经不见了!也就再没有办法从一个普通的请求中分辨出是否是预读取了,这意味着以后不可能屏蔽掉Google Web Accelerator了。
在Google自己的FAQ页面上,Google说它不会预读取安全网站或URL预读取头并下载任何可能的潜在危险。Google Web Accelerator 只会预读取和缓存不会带来不良影响的链接。
Google Web Accelerator 产品部经理 Othman Laraki 把丢失的标题头归因于软件的一个bug,他还说会很快纠正这个bug,25日晚他们已经做出了一个稳定的版本,26日晚些时候就会向广大用户开放。
但Hansson仍然称这项服务是“邪恶的”,“现在Google Web Accelerator当然还不能证明自己免受责难”,但可以肯定的是,Google这次的举动是在向正确的方向发展。

October 27, 2005

AJAX基础教程

  这篇文章将带您浏览整个AJAX的基本概貌,并展示两个简单的例子让您轻松上路.

  什么是 AJAX?
  AJAX (异步 JavaScript 和 XML) 是个新产生的术语,专为描述JavaScript的两项强大性能.这两项性能在多年来一直被网络开发者所忽略,直到最近Gmail, Google suggest和google Maps的横空出世才使人们开始意识到其重要性.

  这两项被忽视的性能是:
  无需重新装载整个页面便能向服务器发送请求.
  对XML文档的解析和处理.

步骤 1 – "请!" --- 如何发送一个HTTP请求

  为了用JavaScript向服务器发送一个HTTP请求, 需要一个具备这种功能的类实例. 这样的类首先由Internet Explorer以ActiveX对象引入, 被称为XMLHTTP. 后来Mozilla, Safari 和其他浏览器纷纷仿效, 提供了XMLHttpRequest类,它支持微软的ActiveX对象所提供的方法和属性.

  因此, 为了创建一个跨浏览器的这样的类实例(对象), 可以应用如下代码:

引用自
if (window.XMLHttpRequest) { // Mozilla, Safari, ...
http_request = new XMLHttpRequest();
} else if (window.ActiveXObject) { // IE
http_request = new ActiveXObject("Microsoft.XMLHTTP");
}
  (上例对代码做了一定简化,这是为了解释如何创建XMLHTTP类实例. 实际的代码实例可参阅本篇步骤3.)

  如果服务器的响应没有XML mime-type header,某些Mozilla浏览器可能无法正常工作. 为了解决这个问题, 如果服务器响应的header不是text/xml,可以调用其它方法修改该header.

引用自
http_request = new XMLHttpRequest();
http_request.overrideMimeType('text/xml');
  接下来要决定当收到服务器的响应后,需要做什么.这需要告诉HTTP请求对象用哪一个JavaScript函数处理这个响应.可以将对象的onreadystatechange属性设置为要使用的JavaScript的函数名,如下所示:
引用自
http_request.onreadystatechange = nameOfTheFunction;
  注意:在函数名后没有括号,也无需传递参数.另外还有一种方法,可以在扉页(fly)中定义函数及其对响应要采取的行为,如下所示:
引用自
http_request.onreadystatechange = function(){
// do the thing
};
  在定义了如何处理响应后,就要发送请求了.可以调用HTTP请求类的open()和send()方法, 如下所示:
引用自
http_request.open('GET', 'http://www.example.org/some.file&#39;, true);
http_request.send(null);
  open()的第一个参数是HTTP请求方式 – GET, POST, HEAD 或任何服务器所支持的您想调用的方式. 按照HTTP规范,该参数要大写;否则,某些浏览器(如Firefox)可能无法处理请求.有关HTTP请求方法的详细信息可参考http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html W3C specs
  第二个参数是请求页面的URL.由于自身安全特性的限制,该页面不能为第三方域名的页面.同时一定要保证在所有的页面中都使用准确的域名,否则调用open()会得到"permission denied"的错误提示.一个常见的错误是访问站点时使用domain.tld,而当请求页面时,却使用www.domain.tld.
  第三个参数设置请求是否为异步模式.如果是TRUE, JavaScript函数将继续执行,而不等待服务器响应.这就是"AJAX"中的"A".
  如果第一个参数是"POST",send()方法的参数可以是任何想送给服务器的数据. 这时数据要以字符串的形式送给服务器,如下所示:
引用自
name=value&anothername=othervalue&so=on
步骤 2 – "收到!" --- 处理服务器的响应
  当发送请求时,要提供指定处理响应的JavaScript函数名.
引用自
http_request.onreadystatechange = nameOfTheFunction;
  我们来看看这个函数的功能是什么.首先函数会检查请求的状态.如果状态值是4,就意味着一个完整的服务器响应已经收到了,您将可以处理该响应.
引用自
if (http_request.readyState == 4) {
// everything is good, the response is received
} else {
// still not ready
}
  readyState的取值如下:
  0 (未初始化)
  1 (正在装载)
  2 (装载完毕)
  3 (交互中)
  4 (完成)

  接着,函数会检查HTTP服务器响应的状态值. 完整的状态取值可参见 W3C site. 我们着重看值为200 OK的响应.

引用自
if (http_request.status == 200) {
// perfect!
} else {
// there was a problem with the request,
// for example the response may be a 404 (Not Found)
// or 500 (Internal Server Error) response codes
}
  在检查完请求的状态值和响应的HTTP状态值后, 您就可以处理从服务器得到的数据了.有两种方式可以得到这些数据:
引用自
http_request.responseText – 以文本字符串的方式返回服务器的响应
http_request.responseXML – 以XMLDocument对象方式返回响应.处理XMLDocument对象可以用JavaScript DOM函数
步骤 3 – "万事俱备!" - 简单实例

  我们现在将整个过程完整地做一次,发送一个简单的HTTP请求. 我们用JavaScript请求一个HTML文件, test.html, 文件的文本内容为"I'm a test.".然后我们"alert()"test.html文件的内容.

引用自
<script type="text/javascript" language="javascript">
var http_request = false;
function makeRequest(url) {

http_request = false;

if (window.XMLHttpRequest) { // Mozilla, Safari,...
http_request = new XMLHttpRequest();
if (http_request.overrideMimeType) {
http_request.overrideMimeType('text/xml');
}
} else if (window.ActiveXObject) { // IE
try {
http_request = new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
try {
http_request = new ActiveXObject("Microsoft.XMLHTTP");
} catch (e) {}
}
}

if (!http_request) {
alert('Giving up :( Cannot create an XMLHTTP instance');
return false;
}
http_request.onreadystatechange = alertContents;
http_request.open('GET', url, true);
http_request.send(null);

}

function alertContents() {

if (http_request.readyState == 4) {
if (http_request.status == 200) {
alert(http_request.responseText);
} else {
alert('There was a problem with the request.');
}
}

}
</script>
<span
style="cursor: pointer; text-decoration: underline"
onclick="makeRequest('test.html')">
Make a request
</span>

  本例中:
  用户点击浏览器上的"请求"链接;
  接着函数makeRequest()将被调用.其参数 – HTML文件test.html在同一目录下;
  这样就发起了一个请求.onreadystatechange的执行结果会被传送给alertContents();
  alertContents()将检查服务器的响应是否成功地收到,如果是,就会"alert()"test.html文件的内容.

步骤 4 – "X-文档" --- 处理XML响应

  在前面的例子中,当服务器对HTTP请求的响应被收到后,我们会调用请求对象的reponseText属性.该属性包含了test.html文件的内容.现在我们来试试responseXML属性.

  首先,我们新建一个有效的XML文件,后面我们将使用这个文件.该文件(test.xml)源代码如下所示:

引用自
<?xml version="1.0" ?>
<root>
I'm a test.
</root>
  在该脚本中,我们只需修改请求部分:
引用自
...
onclick="makeRequest('test.xml')">
...
  接着,在alertContents()中,我们将alert()的代码alert(http_request.responseText);换成:
引用自
  var xmldoc = http_request.responseXML;
  var root_node = xmldoc.getElementsByTagName('root').item(0);
  alert(root_node.firstChild.data);
  这里,我们使用了responseXML提供的XMLDocument对象并用DOM方法获取存于XML文件中的内容.

MYSQL出错代码列表

又是kedy的好东西.嘿嘿~.
1005:创建表失败
1006:创建数据库失败
1007:数据库已存在,创建数据库失败
1008:数据库不存在,删除数据库失败
1009:不能删除数据库文件导致删除数据库失败
1010:不能删除数据目录导致删除数据库失败
1011:删除数据库文件失败
1012:不能读取系统表中的记录
1020:记录已被其他用户修改
1021:硬盘剩余空间不足,请加大硬盘可用空间
1022:关键字重复,更改记录失败
1023:关闭时发生错误
1024:读文件错误
1025:更改名字时发生错误
1026:写文件错误
1032:记录不存在
1036:数据表是只读的,不能对它进行修改
1037:系统内存不足,请重启数据库或重启服务器
1038:用于排序的内存不足,请增大排序缓冲区
1040:已到达数据库的最大连接数,请加大数据库可用连接数
1041:系统内存不足
1042:无效的主机名
1043:无效连接
1044:当前用户没有访问数据库的权限
1045:不能连接数据库,用户名或密码错误
1048:字段不能为空
1049:数据库不存在
1050:数据表已存在
1051:数据表不存在
1054:字段不存在
1065:无效的SQL语句,SQL语句为空
1081:不能建立Socket连接
1114:数据表已满,不能容纳任何记录
1116:打开的数据表太多
1129:数据库出现异常,请重启数据库
1130:连接数据库失败,没有连接数据库的权限
1133:数据库用户不存在
1141:当前用户无权访问数据库
1142:当前用户无权访问数据表
1143:当前用户无权访问数据表中的字段
1146:数据表不存在
1147:未定义用户对数据表的访问权限
1149:SQL语句语法错误
1158:网络错误,出现读错误,请检查网络连接状况
1159:网络错误,读超时,请检查网络连接状况
1160:网络错误,出现写错误,请检查网络连接状况
1161:网络错误,写超时,请检查网络连接状况
1062:字段值重复,入库失败
1169:字段值重复,更新记录失败
1177:打开数据表失败
1180:提交事务失败
1181:回滚事务失败
1203:当前用户和数据库建立的连接已到达数据库的最大连接数,请增大可用的数据库连接数或重启数据库
1205:加锁超时
1211:当前用户没有创建用户的权限
1216:外键约束检查失败,更新子表记录失败
1217:外键约束检查失败,删除或修改主表记录失败
1226:当前用户使用的资源已超过所允许的资源,请重启数据库或重启服务器
1227:权限不足,您无权进行此操作
1235:MySQL版本过低,不具有本功能

互联网新闻的“整风运动”

无语了......

  《互联网新闻信息服务管理规定》出台之后,最先受到“整风”影响的必然是以新闻信息传播为主业的网站。这其中当属新浪、搜狐和网易三大门户网站,而门户网站对此的看法也成为人们所关心的。

  “我们一直遵守国家相关的规定,应该不会受到影响。” 当记者联系到新浪网总编辑兼全球资深副总裁陈彤时,他的回答显得很轻松。陈彤同时还表示,这个规定肯定会有积极的作用,至少不会让虚假信息成为吸引眼球的方式。

  网易和搜狐方面对记者同样表示,《规定》对大网站的影响是积极的,避免出现网上互相炒作虚假信息。

  当记者追问门户网站中一些专门以爆料和传闻吸引网民的论坛是否会因为这次《规定》出台而面临调整的时候,三家门户网站都没有给出正面回答。而在网易,记者已经看不到一度非常出名的乱弹BBS中的“谣言中心”。

  《规定》中有这样的条款:如果网站未经允许,从事新闻信息传播,而且属于虚假信息,那么将受到巨额罚款。

  大网站在这方面基本上不会受到限制,因为本身在新闻授权方面都建立了一整套完整机制。但是小网站呢?尤其是一些以信息交流为主的论坛将发现自己平时很轻松地转载新闻,此时却是走到了触犯法规的边缘。

  下面是记者同一家知名论坛站长的对话记录(应站长要求,在此没有公布该论坛和站长的真实名字),很能反映一些论坛管理人员的心态。

  记者:这个规定对你们的影响如何,应该受到很多限制吧?

  站长:有限制,但不大,毕竟这个规定主要针对的是时政类新闻,而如今网上比较火的论坛都是做娱乐八卦内容的。

  记者:不过时政这个范畴很广,我看到你们论坛就经常转载一些社会政治新闻,而这类新闻参与讨论的网民还不少。

  站长:你说得没错,这方面的确比较头痛。估计很多论坛的网站跟我有一样的感受。以后只有转载的时候千万小心,别不经意就踩了雷区。

  记者:你们这种论坛一般是如何辨别和处理虚假信息的?

  站长:这个很麻烦,个人开办的论坛都没有多少管理人员,即使有,也不可能全面鉴别,所以只有碰到一个删一个。而且发布这种虚假信息的人并不会受到任何约束。

  事实上,网络谣言不仅是只存在于小论坛,如今已经成为整个互联网的普遍现象。

  前不久爆出的某IT网站老总向别人下跪要求收购自己的传闻就轰动一时,甚至引发当事人起诉某大型网站。从2002年到现在,互联网出现过不少造成极大影响的轰动性网络谣言,包括微软董事长遇刺、唐骏从盛大“下课”这些经典谣言。

  娱乐恶搞型:唐骏“下课”

  在职业经理中,唐骏被传辞职的次数最多。

  最新的一次是9月1日。当天记者刚打开电子邮箱,就收到一位朋友的来信,告知唐骏即将从盛大辞职。而此刻网上唐骏即将“下课”的消息已经满天飞,而且很多报道都煞有介事地描绘了唐骏被迫“辞职”的原因,因为某笔收购触怒盛大老板陈天桥,最终让唐骏出局。

  第二天,记者联系到当事人唐骏,询问有关他离开盛大的消息。

  “怎么可能呢?”一开口唐骏就否认了这个消息,“谣言,绝对是谣言。我现在就好端端地坐在办公室里。”

  那么这个谣言是怎样出现的呢?记者为此进行了一番跟踪调查。

  最初关于唐骏从盛大辞职的帖子是出现在8月下旬新浪网的一个论坛上,发帖人的ID叫做“越王_够贱”,标题为《特大爆料:据传盛大总裁唐骏这次真的辞职嘞!!》。这位发帖人表示自己已从盛大高层获知唐骏辞职的消息,还分析了唐辞职的原因。

  记者对这位发帖人专门进行了调查,结果又发现早在7月29日,同样在新浪网论坛,“越王_够贱”发表了一个名为《唐骏,为了这一切的一切,你就辞职吧!》的帖子,内容完全是极尽搞笑之能,用调侃的语言嘲讽了中国互联网。从这个帖子可以看出,实际上这个所谓的消息爆料者更多是出于娱乐大众或者出风头的目的,炮制了“唐骏辞职”这样一条假新闻。

  但就这样一条假新闻,经过各大网站和媒体争相转载和渲染,竟成为一条轰动业界的消息。

  断章取义型一:惠普收购柯达

  有心的读者不会忘记前不久网上关于惠普要与柯达合并的传言。

  自今年7月份起,关于惠普收购柯达的谈论很多。9月2日,传言又起。柯达股价因此上升5%,达到25.5美元。

  事实胜于雄辩。到9月底惠普与柯达仍然各自一家。这个合并的虚假消息又是从哪儿传出来的呢?

  事实上整个谣言的源头是8月底纽约证券界一篇关于柯达股票走势的分析文章,其中提到惠普收购的可能性。

  按理说这纯粹是一个技术层面的探讨。但问题是这篇评估报告后来被大名鼎鼎的《华尔街日报》和《纽约时报》所摘录,更要命的是摘录的内容正好是惠普收购柯达的评估分析。

  这下好了,国内网站上关于惠普即将收购柯达的消息立即风起云涌,门户网站纷纷做出专题报道,从各方面进行跟踪报道。当有人把电话打到柯达中国时,都把工作人员吓坏了,这么大个消息自己怎么都不知道总部也没通知?

  后来双方都出来辟谣。惠普表示同柯达有合作,但没上升到收购层面。柯达则表示,近期绝对没有合并的打算。

  断章取义型二:盖茨遇刺

  在断章取义类型的谣言中,比尔·盖茨遭枪击身亡的消息大概是最具轰动效应。

  2003年3月29日上午11时左右,国内各大网站突然爆出特大消息:全球首富、微软公司董事长比尔·盖茨在出席洛杉矶的一个慈善活动时遭枪击身亡。尽管两天之后就是愚人节了,但是几乎没人想到去进一步确认这个消息,网站又是做专题,又是收集盖茨最近访华的照片,准备供全世界人民缅怀悼念。一切都准备好了,只欠东风,就等着微软发哀文了。

  结果当天下午微软中国宣布 “比尔·盖茨被暗杀一事,经确认并非属实,特此澄清。至此,网站盛传“盖茨遇刺”的闹剧才得以收场。

  而这个谣言出炉的全过程是怎样的呢?最早发布这个消息的是《中国日报》网站,那么《中国日报》的消息源又是什么呢?

  原来该网站值班编辑在当天上午看到美国CNN网站上出现了一条“比尔·盖茨遇刺”的消息,立刻毫不犹豫地照搬过来。后来才知道人家那个消息实际上是为愚人节准备的一个内容,完全就是一个搞笑的内容。可是对于中国网站来说,只要有这个消息就足够了,短短两小时之内,这个谣言传遍了整个互联网,直到微软公司正式辟谣。

  恶意煽动型:非典造谣

  在所有谣言中,这类谣言是最让人感到可怕,已经触犯了国家相关法律法规。

  最典型的莫过于2003年全国上下万众一心抗击非典时期,一些谣言制造者利用互联网,散布虚假信息,造谣惑众,制造恐慌,严重影响和干扰了防治非典工作的正常开展。

  2003年4月28日,北方某地公安局网络监察科发现有人在当地论坛上发布所谓《非典最新通报》,宣称当地已经出现多少例非典,疫情是多么多么严重。

  公安部门立即意识到这是别有用心的人制造的虚假信息,若不及时揪住造谣者的尾巴,则后患无穷。为此,网络警察迅速启动侦查预案,利用技术手段锁定造谣者范围,最后一举抓获犯罪嫌疑人李某。

  谣言在网络上为何如此猖獗?这跟互联网本身的特点有相当大的关系。包括互联网的匿名性、可复制性和丰富性。这些特点在推动互联网本身繁荣发展的同时,也给造谣者们提供了相当的便利。

  互联网的匿名性:“在网上,没人知道你是一条狗”。

  在实际生活中散布谣言会受到指责的。在网络上,这样的担心变成了多余。

  互联网的可复制性:就如同电脑病毒一样,网络谣言的复制极其容易。利用电子邮件、IM工具等可以在几秒钟时间里向成千上万的网民发送虚假信息。

  互联网信息的丰富性:网络被称为海量信息的集散地,谁能得到网民的注意力谁就能得到网上价值的最大体现。这样,很多人就捏造发布虚假信息。

  消除网络谣言比传播网络谣言困难得多,同色情信息不同,谣言这样的虚假信息是无法从技术上过滤掉的。目前惟一可行的是从法律上制裁造谣者。

  目前,法律关于在互联网上传播谣言的规定非常模糊。美国底特律大学宪法学教授Larry Dubin认为,传播诽谤性言论的法律责任是可以适用到互联网的,但问题是很难证明谣言的来源。“如果某些人只是重复他们听到的消息,他们就没有责任” 。

  著名互联网法律专家、律师于国富在接受记者采访时肯定了《规定》的必要性:“新的规定更具可操作性。新规定对于管理对象的分类,互联网新闻信息服务单位的设立条件及审批、备案程序,互联网新闻信息服务规范,日常监督管理,以及法律责任等都有了更加明确的界定。”当然,新的规定也给我们留下了遗憾。从法规效力等级来讲,国务院部委发布的“规定”仅属于部门规章性质。与全国人大通过的“法律”相比,效力等级还相当低。

  读者朋友,对于网络谣言和这场互联网新闻“整风运动”,你有什么看法,有什么亲身遭遇,请告诉我们。记住我们的互动通道:电子邮件发送到pcw-report@vip.sina.com,电脑报官方论坛(bbs.cpcw.com)。

About 它它它它

This page contains an archive of all entries posted to a one and a two in the 它它它它 category. They are listed from oldest to newest.

学习学习 is the previous category.

幸福生活 is the next category.

Many more can be found on the main index page or by looking through the archives.

Creative Commons License
This weblog is licensed under a Creative Commons License.