啊啦神灯

   :: 首页 :: 联系 :: 聚合  :: 管理
  11 Posts :: 0 Stories :: 1 Comments :: 0 Trackbacks

2006年9月18日 #

为了说明问题,我们用SqlServer自带的事例数据库(Northwind)来进行验证,所有的例子请放到Northwind中运行,我可能会省略Use语句,所引用的表,都是Northwind中的,下面我就不再说明了

这里指的交叉表,就是象Access的交叉表查询一样的效果,比如Employees表中City字段代表了城市的名称,TitleOfCourtesy代表称呼,我们希望按照City和TitleOfCourtesy的情况来统计ReportsTo字段的合计数(本统计没有任何实际意义,只是挑选一些记录包含重复内容的字段来说明情况),并显示成以下格式:(TitleOfCourtesy作为行,City作为列)
探讨这个问题之前,我们首先来看一下如何建立静态的交叉表,也就是说列数固定的交叉表,这种情况其实只要一句简单的Select查询就可以搞定:

SELECT  TitleOfCourtesy, 
  
SUM ( CASE  City  WHEN   ' London '   THEN  ReportsTo  ELSE   NULL   END AS   [ London City ]
 
SUM ( CASE  City  WHEN   ' Redmond '   THEN  ReportsTo  ELSE   NULL   END AS   [ Redmond City ]
 
SUM ( CASE  City  WHEN   ' Seattle '   THEN  ReportsTo  ELSE   NULL   END AS   [ Seattle City ]
FROM  Employees  GROUP   BY  TitleOfCourtesy

其中利用了CASE语句判断,如果是相应的列,则取需要统计的ReportsTo数值,否则取NULL,然后再合计
其中有两个常见问题说明一下:
a、用NULL而不用0是有道理的,假如用0,虽然求和函数SUM可以取到正确的数,但类似COUNT函数(取记录个数),结果就不对了,因为Null不算一条记录,而0要算,同理空字串("")也是这样,总之在这里应该用NULL,这样任何函数都没问题。

b、假如在视图的设计界面保存以上的查询,则会报错“没有输出列”,从而无法保存,其实只要在查询前面加上一段:Create View ViewName AS ...,ViewName是你准备给查询起的名称,...就是我们的查询,然后运行一下,就可以生成视图了,对于其他一些设计器不支持的语法,也可以这样保存。

以上查询作用也很大,对于很多情况,比如按照季度统计、按照月份统计等列头内容固定的情况,这样就行了,但往往大多数情况下列头内容是不固定的,象City,用户随时可能删除、添加一些城市,这种情况,我们就需要用存储过程来解决:

总体思路其实很简单,首先检索列头信息,形成一个游标,然后遍历游标,将上面查询语句里Case判断的内容用游标里的值替代,形成一条新的Sql查询,然后执行,返回结果,就可以了,以下是我写的一个存储过程,供大家参考:

CREATE   procedure  CorssTab 
@strTabName   as   varchar ( 50 =   ' Employees ' -- 此处放表名
@strCol   as   varchar ( 50 =   ' City ' ,                        -- 表头分组依据字段
@strGroup   as   varchar ( 50 =   ' TitleOfCourtesy ' , -- 分组字段
@strNumber   as   varchar ( 50 =   ' ReportsTo ' ,     -- 被统计的字段
@strSum   as   varchar ( 10 =   ' Sum '                       -- 运算方式
AS

DECLARE   @strSql   as   varchar ( 1000 ),  @strTmpCol   as   varchar ( 100 )
EXECUTE  ( ' DECLARE corss_cursor CURSOR FOR SELECT DISTINCT  '   +   @strCol   +   '  from  '   +   @strTabName   +   '  for read only  ' -- 生成游标
begin
  
SET  nocount  ON  
  
SET   @strsql   = ' select  '   +   @strGroup   +   ' '   +   @strSum   +   ' ( '   +   @strNumber   +   ' ) AS [ '   +   @strSum   +   '  of  '   +   @strNumber   +   ' ] '   -- 查询的前半段

  
OPEN  corss_cursor
  
while  ( 0 = 0 )
  
BEGIN
    
FETCH   NEXT   FROM  corss_cursor  -- 遍历游标,将列头信息放入变量@strTmpCol
     INTO   @strTmpCol
    
if  ( @@fetch_status <> 0 break
          
SET   @strsql   =   @strsql   +   ' '   +   @strSum   +   ' (CASE  '   +   @strCol   +   '  WHEN  '''   +   @strTmpCol   +   '''  THEN  '   +   @strNumber   +   '  ELSE Null END) AS [ '   +   @strTmpCol   +   '   '   +   @strCol   +   ' ] '   -- 构造查询
   END
        
SET   @strsql   =   @strsql   +   '  from  '   +   @strTabname   +   '  group by  '   +   @strGroup   -- 查询结尾

  
EXECUTE ( @strsql -- 执行
   IF   @@error   <> 0   RETURN   @@error   -- 如果出错,返回错误代码
   CLOSE  corss_cursor 
  
DEALLOCATE  corss_cursor  RETURN   0   -- 释放游标,返回0表示成功



end
GO

几点说明:
a、这是一个通用存储过程,使用时@strTabName、@strCol、@strGroup、@strNumber、@strSum几个变量设置一下就可以用到其他表上,其中结果集的第二列我加了个合计列
b、为了测试方便,我在存储过程中设置了默认值,就是前面提到的Employees表,这样直接运行时就可以出来我上面提到的结果。
c、使用时,可以把上面的代码复制到企业管理器的查询设计界面Sql窗格,或者查询分析器里运行一下(注意正确选择NorthWind数据库),就可以生成一个存储过程:CorssTab,然后直接运行CorssTab,如果出现本文前面类似的窗格,就表示运行成功了。
d、假如用于其它表,首先需要在你的用户数据库里生成此存储过程(当然也可以放到Master里,然后再加个变量:@DataBase,赋值为数据库名称,然后在上面代码打开指定数据库,这样所有的数据库都可以调用它),当你调用时,采取以下格式:

CorssTab @strTabName = 'Orders', @strCol = 'DATEPART(yy, OrderDate)',@strGroup = 'CustomerID', @strNumber = 'OrderID', @strSum = 'Count'

上面这条语句统计了NorthWind中Orders表里每个客户年度订单数量,大家可以运行试一下效果,虽然列头显示的名称不恰当,但基本效果出来了,相信大家通过对我的代码再作简单修改,可以达到满意的交叉表效果。

posted @ 2006-09-18 23:26 啊啦神灯 阅读(1161) | 评论 (0)编辑 收藏

2006年9月16日 #

     摘要: < script language = " javascript " > // 限制输入字符的位数开始 // m是用户输入,n是要限制的位数 ...  阅读全文
posted @ 2006-09-16 15:32 啊啦神灯 阅读(193) | 评论 (0)编辑 收藏

substr 方法
返回一个从指定位置开始的指定长度的子字符串。

stringvar.substr(start [, length ])

代码:
<script> 
var img='abc' 
alert(img.substr(
0,1)); 
</script> 

posted @ 2006-09-16 15:30 啊啦神灯 阅读(571) | 评论 (0)编辑 收藏

isNaN 函数
isNaN(expression:Object) : Boolean

计算参数,如果值为 NaN(非数字),则返回 true。此函数可用于检查一个数学表达式是否成功地计算为一个数字。

可用性:Flash Player 5;ActionScript 1.0

参数
expression:Object - 要计算的布尔值、变量或其它表达式。

返回
Boolean - 一个布尔值。

例子:
if(isNaN(document.login.imgcode.value))
   alert('验证码必须是数字!') 
   document.login.imgcode.focus(); 
   
return false
}
posted @ 2006-09-16 15:26 啊啦神灯 阅读(3036) | 评论 (1)编辑 收藏

首先ASP的(VBScript)类是由事件和方法(它们就是构成类的成员了)构成的,如果大家还没有接触过,可以先看看下面的说明。

在Class 块中,成员通过相应的声明语句被声明为 Private(私有成员,只能在类内部调用) 或 Public(公有成员,可以在类内外部调用) 。被声明为 Private 的将只在 Class 块内是可见的。被声明为 Public 不仅在 Class 块的内部是可见的,对 Class 块之外的代码也是可见的。没有使用 Private 或 Public 明确声明的被默认为 Public。在类的块内部被声明为 Public 的过程(Sub 或 Function)将成为类的方法。Public 变量将成为类的属性,同使用 Property Get、Property Let 和 Property Set 显式声明的属性一样。类的缺省属性和方法是在它们的声明部分用 Default 关键字指定的。

请大家内心看完上面的部分,下面我们来看一个例子

<script language=vbscript runat=server>

Class myClass
'//----声明(声明就是定义)myClass类的类内部(私有的[Private])变量
Private strAuthor
Private strVersion
Private strExample

'//定义类的事件//
'
//----Class_Initialize()是类的初始化事件,只要一开始使用该类,首先会触发该部分的执行,下面我们会在该成员中初始化该类的作者和版本以及在屏幕上显示一下该类已经开始了

Private Sub Class_Initialize()
strAuthor 
= "思源"
strVersion 
= "1.0"
Response.Write 
"<br>myClass开始了<br>"
End Sub
'//----Class_Terminate()是类的结束事件,只要一退出该类,就会触发该事件,下面我们会该事件中设定退出该类时会在屏幕上显示该类已结束了。

Private Sub Class_Terminate()
Response.Write 
"<br>myClass结束了<br>"
End Sub

'//用户自己定义的方法//

'//----该方法返回一个版本信息

Public Sub Information()
Response.Write 
"<br>Coding By <a href='mailto:coder@sinobe.com'>Maxid_Zen</a> @ <a href='http://www.design60s.com'>www.d  /a>.<br>"
End Sub

'//定义类的输出属性//

'//----定类的属性,该属性是让用户初始化strExapmle变量

Public Property Let setExapmle(ByVal strVar)
strExapmle 
= strVar
End Property

'//定义类的输出属性//

'//----定义类的属性,该属性是返回一个版本号

Public Property Get Version
Version 
= strVersion
End Property

'//----定义类的属性,该属性是返回该类的作者号

Public Property Get Author
Author 
= strAuthor
End Property

'//----定义类的属性,该属性是返回一个版本号

Public Property Get Exapmle
Exapmle 
= strExapmle
End Property

End Class

</script>
<%

'//这里是使用该类的例子

Dim oneNewClass

Set oneNewClass = New myClass

Response.Write 
"作者:" & oneNewClass.Author & "<br>"
Response.Write 
"版本:" & oneNewClass.Version & "<br>"

oneNewClass.setExapmle 
= "这是一个简单类的例子"

Response.Write 
"用户自定义:" & oneNewClass.Exapmle & "<br>"

oneNewClass.Information

Set oneNewClass = Nothing

%
>  
posted @ 2006-09-16 15:09 啊啦神灯 阅读(192) | 评论 (0)编辑 收藏

2006年9月15日 #

car
function  getcaroject(){
return 
new  car( " dodge " , " coronet r/t " , 1968 , " yellow " );
}

function  car(make,model, year ,color){
this.make
= make;
this.model
= model;
this.year
= year ;
this.color
= color;
}
posted @ 2006-09-15 20:36 啊啦神灯 阅读(195) | 评论 (0)编辑 收藏

一、引言

当微软把ActiveX XMLHTTP对象纳入到JavaScript的Internet Explorer实现中时,它实际上已经为Web应用程序的又一次革命(异步JavaScript+XML,简称AJAX)埋下了“火种”。今天,Firefox,Safari,Opera及其它浏览器都支持XMLHttpRequest对象,正是这些支持最终才导致了诸如colr.org,backpackit.com和maps.google.com等著名网站的产生。尽管这些网站(不止这些)所提供的应用程序运行于一种浏览器中,但是它们在行为和外观上却极类似于传统的桌面应用程序。


在AJAX技术中,在用户观看并与页面交互的同时(这正相应于AJAX中的“异步”部分),由页面中的JavaScript负责把数据请求发送到一个Web服务器。这些请求只是一些普通的HTTP请求,与浏览器用于页面(连同其中的任何图像,层叠式样表等内容)检索的HTTP完全相同。同时,XMLHttpRequest对象可以用于检索任何类型的数据,而不仅仅是XML类型。例如,JavaScript可以使用XMLHttpRequest来检索一个来自于Web服务器的普通文本文本并且把它的内容显示于一个表单中。

通过查找位于数据之前的“content-type”头部,XMLHttpRequest对象分析从Web服务器返回的数据的MIME类型。例如,如果这些数据的MIME类型是“text/plain”,那么你可以通过分析XMLHttpRequest对象的responseText属性来存取它;然而,如果其MIME类型为“text/xml”,那么XMLHttpRequest对象必须采取额外的措施:它要在返回的文档对象上运行一个XML分析器并在内存中构建一棵文档对象模型(DOM)树来描述该文档,并且还要使其可用于responseXML属性。然后,你才可以使用JavaScript的标准DOM方法在树中导航并检索元素、属性及位于该DOM树中的其它文本。

虽然XML是进行数据交换的标准方式,但是通常它不是最好的方式。尽管XML可以把结构和元数据添加到数据上,但是它使用了一种相当繁琐的方式。XML还有一种相对复杂的语法,因而需要一种分析器对之进行专门分析。在JavaScript中,XML必须被分析成一棵以备后用的DOM树。并且,一旦你构建了这棵DOM树,你还必须在其中导航以便创建相应的JavaScript对象或者以其它方式在你的客户端Web应用程序中使用XML数据。
幸好,你还有另外更好的可选方案。

二、JSON简介

JavaScript对象标志,简称JSON,是一种描述数据的轻量级语法。JSON的优越性基于这样的事实:它本身就是JavaScript语言的一个子集。你会在后面看到这种特征的重要性。首先,让我们比较一下JSON和XML的原始语法。
XML和JSON都使用结构化方法来标记数据。例如,一个地址簿应用程序可能提供一个Web服务—它将以XML形式生成如下的地址卡片:

xml代码
而使用JSON来表达,上面的形式将变成如下模样:
"fullname""Sean Kelly""org""SK Consulting""emailaddrs": [{"type""work", "value": kelly@seankelly.biz"},{"type""home", "pref": 1, "value""kelly@seankelly.tv"}],"telephones": [{"type""work", "pref": 1, "value""+1 214 555 1212"},{"type""fax", "value""+1 214 555 1213"},{"type""mobile", "value""+1 214 555 1214"}],"addresses": [{"type""work", "format""us""value""1234 Main StnSpringfield, TX 78080-1216"},{"type""home", "format""us""value""5678 Main StnSpringfield, TX 78080-1316"}],"urls": [{"type""work", "value""http://seankelly.biz/"},{"type""home", "value""http://seankelly.tv/"}]}

正如你所见,JSON也提供了一种具有嵌套数据元素的结构,就象XML一样。与XML一样,JSON也是基于文本的,且它们都使用Unicode编码,且其与XML一样具有可读性。主观上来看,JSON更为清晰且冗余更少些。JSON网站提供了对JSON语法的严格描述,只是描述较简短。从总体来看,XML比较适合于标记文档,而JSON却更适于进行数据交换处理。一个JSON文档的每一个实例都负责描述一个对象—具体的描述是通过使用嵌套的对象,数组,字符串,数字,布尔值或null值来实现的。

上面地址卡例子的JSON版本更为小些,仅占用大约682字节的空间,而XML版本需要744字节空间。当然,这不是什么惊人的节省。其实,JSON的真正优点在于数据分析方面。

三、JSON与XML数据分析对比

借助于XMLHttpRequest对象,你可以从自己的基于AJAX的应用程序内部检索XML和JSON文件。典型情况下,你可以使用类似如下的交互:

var req = new XMLHttpRequest();req.open("GET""http://localhost/addr?cardID=32", /*async*/true);req.onreadystatechange = myHandler;req.send(/*no params*/null);
 

随着对Web服务器的不断响应,被你传递的处理器函数(在本例中是myHandler)被反复调用,这种特征提供给你一种时机—及早地取消事务,更新一个进度条,等等。通常,你只是在Web请求完成时才采取行动(应用返回的数据)。

为了处理上面地址卡程序的XML版本,myHandler的编码可以类似如下:


注意,你不必自己分析XML文档,分析任务可以由XMLHttpRequest对象为你自动完成。之后,这个XMLHttpRequest对象使得由分析生成的DOM树可应用于responseXML属性中。然后,你可以借助这个responseXML属性并调用getElementsByTagName方法来查找文档中的addresses部分,但仅能使用找到的第一个(其实只有一个)。然后,你再次在找到的address上调用getElementsByTagName方法来查找下一层中的第一个address元素,然后再次使用找到的第一个address……然后,你得到该元素的第一个DOM子结点(它是一个文本结点)并得到该结点的值(它正是你想找的街道地址)。最后,你就可以在表单域中显示它。

显然,这是一项工作量很大的工作!现在,让我们试用一下JSON:

function myHandler() {
if (req.readyState == 4 /*complete*/) {
var addrField 
= document.getElementById('addr');
var card = eval('(' + req.responseText + ')');
addrField.value = card.addresses[0].value;}}

你需要做的第一件事情是手工地分析JSON响应。然而,因为JSON是JavaScript的一个子集,所以你可以通过调用eval方法使用JavaScript自己的编译器来完成这些。分析JSON是非常简单的!而且,在产生于JSON中的一个对象中导航与在任何JavaScript对象中导航完全一样。这比在DOM树中导航要容易得多。例如:

•card.addresses[0].value对应第一条街道地址:“1234 Main Stb &”;
•card.addresses[0].type对应地址的类型:“work”;
•card.addresses[1]对应一个家庭地址对象;
•card.fullname对应卡片名:“Sean Kelly”。

如果仔细观察,那么你可能注意到,示例程序的XML版本至少要处理包含在文档中的一个对象—根文档元素card。这在JSON版本中是不存在的。为什么?如果你曾开发过存取一个Web服务的JavaScript,那么你就会知道你要从Web服务中取回什么。然而,你可以在JSON中包括下面一种更为简练的形式:

{"card": {"fullname"}}

通过使用这一技术,你的JSON文件总是以一个对象开头并且用单个命名的属性来标记该对象的“类型”。

四、JSON的快速可靠性

JSON能够生成更小的文档,且其在JavaScript脚本中更易于使用。XMLHttpRequest能够为你自动分析XML文档,然而你必须手工分析JSON。这样以来,你可能质疑:分析JSON是否比分析XML更慢?对比JSON,我针对上面的地址卡测试了嵌入到XMLHttpRequest中的XML分析器—通过把这些数据置入上千次的循环中。最终结果表明,分析JSON比分析XML快大约10倍!如果想实现AJAX程序的行为类似于桌面应用程序,那么速度就是一切。很明显,JSON是胜者。

当然,你不可能一直控制为你的AJAX应用程序产生数据的服务器端。你可以使用一种第三方服务器来处理你的数据,而且让该服务器仅提供XML输出。然而,如果该服务器中恰巧能够提供JSON支持,那么你能否确定并敢于使用这一支持?

注意,在上面的示例中,你是直接把响应文本传递到一个对eval的调用中。如果你信任并控制了服务器,这是没有问题的;然而,另外一些情况下,一个恶意的服务器有可能给你的浏览器执行带来危险操作。为此,你最好使用一个用JavaScript编写的JSON分析器。幸好,已经存在可用的分析器了。

谈到分析器,Python迷们可能还没有注意到,JSON不仅是JavaScript的一个子集,而且它还是Python的一个子集。你可以直接在Python中使用JSON,或利用一种安全的JSON分析器。现在,针对于JSON的分析器也大量地存在于其它语言中;你可以参考JSON.org网站来选择使用相应的分析器。

五、服务器端技术对JSON的支持

到目前为止,我们一直集中于讨论如何把JSON应用于客户端浏览器上的基于AJAX技术的Web应用程序。当然,Web服务器端必须存在一定的技术支持才能实现首先生成JSON,然后由客户端使用JSON。幸好,基于现有数据结构创建JSON是一件相当直接的事情。另外,一些Web应用程序框架(例如TurboGears)已经自动包括支持JSON输出。

另外,商业Web服务供应商也都特别关注JSON。Yahoo最近在其Web服务中大量地加入对JSON的支持。Yahoo的多种搜索服务,旅行规划者,del.icio.us和高速公路交通服务都支持JSON输出。无疑,其它一些主要的Web服务供应商也都会逐渐地提供对JSON的支持。

六、结论

JSON的基本思想是,把自己实现为JavaScript(和Python)的一个子集,从而使其成为一种轻量级的和高度灵活的处理AJAX数据交换的方式。与传统的XML处理技术相比,这个工具的分析速度更快且更为易用。从该工具的性能和使用现状来看,它有可能会成为下一代Web 2.0开发中XML数据操作的主要替代者。任何开发者,无论是开发标准桌面应用程序还是开发Web应用程序,只要使用XML数据处理,都会欣赏JSON的简易特征。最后,我衷心祝愿JSON能加快你的基于AJAX技术的Web 2.0应用程序的开发。

posted @ 2006-09-15 20:20 啊啦神灯 阅读(154) | 评论 (0)编辑 收藏

2006年9月14日 #

代码
posted @ 2006-09-14 20:29 啊啦神灯 阅读(177) | 评论 (0)编辑 收藏

代码
posted @ 2006-09-14 16:35 啊啦神灯 阅读(181) | 评论 (0)编辑 收藏

在做电子商务站点的时候,经常要求浏览器在https和http之间转化
下面我给出相应的代码:

让一个ASP页面以https开始,请在该ASP页面顶部添加如下代码:
代码
posted @ 2006-09-14 16:28 啊啦神灯 阅读(167) | 评论 (0)编辑 收藏