[转载]JavaScript处理Json的invalid label错误解决办法

mikel阅读(1419)

[转载]Js处理Json的”invalid label”错 | 风雪之隅.

当你使用ajax的时候,json是一个很方便的数据传输手段.
但是对于很多人来说,经常会遇到的一个很令人头疼的问题就是”invalid label”错. 明明json串看起来是对的,怎么还会出错呢?

比如,如下的代码:

  function handle_success(response){
       var json = eval(response); // response = "{'foo' : 'bar'}";
  }

浏览器会报,invalid label错, 这是因为, eval会尝试将你的response解释为一个label, 当你在脚本中直接写:

    <script>
      {'foo' : 'bar'};
    </script>

会报错的原理是一样的.

解决办法有俩个:

var json = eval('(' + response + ')'); // response = "{'foo' : 'bar'}";

或者

      eval('var json = ' + response); // response = "{'foo' : 'bar'}";
       //json is available now

[转载]使用嵌入式关系型SQLite数据库存储数据

mikel阅读(977)

[转载]使用嵌入式关系型SQLite数据库存储数据 – forrest001 – 博客园.

除了可以使用文件或SharedPreferences存储数据,还可以选择使用SQLite数据库存储数据。
Android平台上,集 成了一个嵌入式关系型数据库—SQLite,SQLite3支持 NULL、INTEGER、REAL(浮点数字)、TEXT(字符串文本)和BLOB(二进制对象)数据类型,虽然它支持的类型只有五种,但实际上 sqlite3也接受varchar(n)、char(n)、decimal(p,s) 等数据类型,只不过在运算或保存时会转成对应的五种数据类型。 SQLite最大的特点是你可以把各种类型的数据保存到任何字段中,而不用关心字段声明的数据类型是什么。例如:可以在Integer类型的字段中存放字 符串,或者在布尔型字段中存放浮点数,或者在字符型字段中存放日期型值。 但有一种情况例外:定义为INTEGER PRIMARY KEY的字段只能存储64位整数, 当向这种字段保存除整数以外的数据时,将会产生错误。 另外, SQLite 在解析CREATE TABLE 语句时,会忽略 CREATE TABLE 语句中跟在字段名后面的数据类型信息,如下面语句会忽略 name字段的类型信息:
CREATE TABLE person (personid integer primary key autoincrement, name varchar(20))
SQLite可以解析大部分标准SQL语句,如:
查询语句:select * from 表名 where 条件子句 group by 分组字句 having … order by 排序子句
如:select * from person
select * from person order by id desc
select name from person group by name having count(*)>1
分页SQL与mysql类似,下面SQL语句获取5条记录,跳过前面3条记录
select * from Account limit 5 offset 3 或者 select * from Account limit 3,5
插入语句:insert into 表名(字段列表) values(值列表)。如: insert into person(name, age) values(‘传智’,3)
更新语句:update 表名 set 字段名=值 where 条件子句。如:update person set name=‘传智‘ where id=10
删除语句:delete from 表名 where 条件子句。如:delete from person  where id=10

使用SQLiteOpenHelper对数据库进行版本管理

我们在编写数据库应用软件时,需要考虑这样的问题:因为我们开发的软件可能会安装在很多用户的手机上,如果应用使用到了SQLite数据库,我们必 须在用户初次使用软件时创建出应用使用到的数据库表结构及添加一些初始化记录,另外在软件升级的时候,也需要对数据表结构进行更新。那么,我们如何才能实 现在用户初次使用或升级软件时自动在用户的手机上创建出应用需要的数据库表呢?总不能让我们在每个需要安装此软件的手机上通过手工方式创建数据库表吧?因 为这种需求是每个数据库应用都要面临的,所以在Android系统,为我们提供了一个名为SQLiteOpenHelper的抽象类,必须继承它才能使 用,它是通过对数据库版本进行管理来实现前面提出的需求。

为了实现对数据库版本进行管理,SQLiteOpenHelper类提供了两个重要的方法,分别是onCreate(SQLiteDatabase db)和onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion),前者用于初次使用软件时生成数据库表,后者用于升级软件时更新数据库表结构。当调用SQLiteOpenHelper的 getWritableDatabase()或者getReadableDatabase()方法获取用于操作数据库的SQLiteDatabase实例 的时候,如果数据库不存在,Android系统会自动生成一个数据库,接着调用onCreate()方法,onCreate()方法在初次生成数据库时才 会被调用,在onCreate()方法里可以生成数据库表结构及添加一些应用使用到的初始化数据。onUpgrade()方法在数据库的版本发生变化时会 被调用,一般在软件升级时才需改变版本号,而数据库的版本是由程序员控制的,假设数据库现在的版本是1,由于业务的变更,修改了数据库表结构,这时候就需 要升级软件,升级软件时希望更新用户手机里的数据库表结构,为了实现这一目的,可以把原来的数据库版本设置为2(有同学问设置为3行不行?当然可以,如果 你愿意,设置为100也行),并且在onUpgrade()方法里面实现表结构的更新。当软件的版本升级次数比较多,这时在onUpgrade()方法里 面可以根据原版号和目标版本号进行判断,然后作出相应的表结构及数据更新。

getWritableDatabase()和getReadableDatabase()方法都可以获取一个用于操作数据库的 SQLiteDatabase实例。但getWritableDatabase() 方法以读写方式打开数据库,一旦数据库的磁盘空间满了,数据库就只能读而不能写,倘若使用的是getWritableDatabase() 方法就会出错。getReadableDatabase()方法先以读写方式打开数据库,如果数据库的磁盘空间满了,就会打开失败,当打开失败后会继续尝 试以只读方式打开数据库。

public class DatabaseHelper extends SQLiteOpenHelper {
//类没有实例化,是不能用作父类构造器的参数,必须声明为静态
private static final String name = “itcast”; //数据库名称
private static final int version = 1; //数据库版本
public DatabaseHelper(Context context) {
//第三个参数CursorFactory指定在执行查询时获得一个游标实例的工厂类,设置为null,代表使用系统默认的工厂类
super(context, name, null, version);
}
@Override public void onCreate(SQLiteDatabase db) {
db.execSQL(“CREATE TABLE IF NOT EXISTS person (personid integer primary key autoincrement, name varchar(20), age INTEGER)”);
}
@Override public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL(“DROP TABLE IF EXISTS person”);
onCreate(db);
}
}
上面onUpgrade()方法在数据库版本每次发生变化时都会把用户手机上的数据库表删除,然后再重新创建。一般在实际项目中是不能这样做的,正确的做法是在更新数据库表结构时,还要考虑用户存放于数据库中的数据不会丢失。

使用SQLiteDatabase操作SQLite数据库

Android提供了一个名为SQLiteDatabase的类,该类封装了一些操作数据库的API,使用该类可以完成对数据进行添加 (Create)、查询(Retrieve)、更新(Update)和删除(Delete)操作(这些操作简称为CRUD)。对 SQLiteDatabase的学习,我们应该重点掌握execSQL()和rawQuery()方法。 execSQL()方法可以执行insert、delete、update和CREATE TABLE之类有更改行为的SQL语句; rawQuery()方法用于执行select语句。
execSQL()方法的使用例子:
SQLiteDatabase db = ….;
db.execSQL(“insert into person(name, age) values(‘传智播客’, 4)”);
db.close();
执 行上面SQL语句会往person表中添加进一条记录,在实际应用中, 语句中的“传智播客”这些参数值会由用户输入界面提供,如果把用户输入的内容原样组拼到上面的insert语句, 当用户输入的内容含有单引号时,组拼出来的SQL语句就会存在语法错误。要解决这个问题需要对单引号进行转义,也就是把单引号转换成两个单引号。有些时候 用户往往还会输入像“ & ”这些特殊SQL符号,为保证组拼好的SQL语句语法正确,必须对SQL语句中的这些特殊SQL符号都进行转义,显然,对每条SQL语句都做这样的处理工 作是比较烦琐的。 SQLiteDatabase类提供了一个重载后的execSQL(String sql, Object[] bindArgs)方法,使用这个方法可以解决前面提到的问题,因为这个方法支持使用占位符参数(?)。使用例子如下:
SQLiteDatabase db = ….;
db.execSQL(“insert into person(name, age) values(?,?)”, new Object[]{“传智播客”, 4});
db.close();
execSQL(String sql, Object[] bindArgs)方法的第一个参数为SQL语句,第二个参数为SQL语句中占位符参数的值,参数值在数组中的顺序要和占位符的位置对应。

SQLiteDatabase的rawQuery() 用于执行select语句,使用例子如下: SQLiteDatabase db = ….;
Cursor cursor = db.rawQuery(“select * from person”, null);
while (cursor.moveToNext()) {
int personid = cursor.getInt(0); //获取第一列的值,第一列的索引从0开始
String name = cursor.getString(1);//获取第二列的值
int age = cursor.getInt(2);//获取第三列的值
}
cursor.close();
db.close();
rawQuery()方法的第一个参数为select语句;第二个参数为select语句中占位符参数的值,如果select语句没有使用占位符,该参数可以设置为null。带占位符参数的select语句使用例子如下:
Cursor cursor = db.rawQuery(“select * from person where name like ? and age=?”, new String[]{“%传智%”, “4”});

Cursor是结果集游标,用于对结果集进行随机访问,如果大家熟悉jdbc, 其实Cursor与JDBC中的ResultSet作用很相似。使用moveToNext()方法可以将游标从当前行移动到下一行,如果已经移过了结果集 的最后一行,返回结果为false,否则为true。另外Cursor 还有常用的moveToPrevious()方法(用于将游标从当前行移动到上一行,如果已经移过了结果集的第一行,返回值为false,否则为true )、moveToFirst()方法(用于将游标移动到结果集的第一行,如果结果集为空,返回值为false,否则为true )和moveToLast()方法(用于将游标移动到结果集的最后一行,如果结果集为空,返回值为false,否则为true ) 。

演示一个具体的代码,可以实现增删改查的功能,具体代码如下

首先新建一个cn.itcast.domain包,在包下新建一个person类,主要用于存放上面解析出来的xml内容,javaBeanMVC设计模型中是model,又称模型层,在一般的程序中,我们称它为数据层,就是用来设置数据的属性和一些行为,然后我会提供获取属性和设置属性的get/set方法,如题代码如下:

package cn.itcast.domain;

public class Person {
private Integer id;
private String name;

public Person(){}

public Person(Integer id, String name) {
this.id = id;
this.name = name;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}

@Override
public String toString() {
return "Person [id=" + id + ", name=" + name + "]";
}

}

然后新建一个DBOpenHelper.java类,这个主要是起到一开始创建数据表用还有当版本更新的时候使用,具体解释都在代码里

package cn.itcast.service;

import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;

public class DBOpenHelper extends SQLiteOpenHelper {
private static final String DATABASENAME = "itcast.db"; //数据库名称
private static final int DATABASEVERSION = 2;//数据库版本

public DBOpenHelper(Context context) {
//第一个参数是上下文对象,用于创建数据库,第二个参数是数据库名称,第三个参数是游标,第四个参数是版本
super(context, DATABASENAME, null, DATABASEVERSION);
}

@Override//数据库第一次被创建时被调用,只会调用一次
public void onCreate(SQLiteDatabase db) {
db.execSQL("CREATE TABLE person (personid integer primary key autoincrement, name varchar(20), amount integer)");//执行有更改的sql语句
}

@Override//软件升级用到这个方法
public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
db.execSQL("DROP TABLE IF EXISTS person");
onCreate(db);
}

}

第三步:新建一个PersonService.java类,这个类主要是业务类,增删改查的功能都在这里,具体代码如下;

package cn.itcast.service;

import java.util.ArrayList;
import java.util.List;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import cn.itcast.domain.Person;

public class PersonService {
private DBOpenHelper dbOpenHelper;
//利用上下文构造出dbOpenHelper对象
public PersonService(Context context) {
this.dbOpenHelper = new DBOpenHelper(context);
}
//增
public void save(Person person){
//如果要对数据进行更改,就调用此方法得到用于操作数据库的实例,该方法以读和写方式打开数据库
SQLiteDatabase db = dbOpenHelper.getWritableDatabase();
//?代表占位符
db.execSQL("insert into person (name) values(?)", new Object[]{person.getName()});
}
//改
public void update(Person person){
SQLiteDatabase db = dbOpenHelper.getWritableDatabase();
db.execSQL("update person set name=? where personid=?",
new Object[]{person.getName(),person.getId()});
}
//删
public void delete(Integer id){
SQLiteDatabase db = dbOpenHelper.getWritableDatabase();
db.execSQL("delete from person where personid=?", new Object[]{id.toString()});
}
//查
public Person find(Integer id){
//如果只对数据进行读取,建议使用此方法
SQLiteDatabase db = dbOpenHelper.getReadableDatabase();
//查询语句,得到游标
Cursor cursor = db.rawQuery("select * from person where personid=?", new String[]{id.toString()});
if(cursor.moveToFirst()){//把游标移到第一条数据
//首先取得字段名称的列索引,然后把这个索引传给getColumnIndex()方法,根据这个方法取得索引下的ID值
int personid = cursor.getInt(cursor.getColumnIndex("personid"));
//首先取得字段名称的列索引,然后把这个索引传给getColumnIndex()方法,根据这个方法取得索引下的name值
String name = cursor.getString(cursor.getColumnIndex("name"));
return new Person(personid, name);
}
return null;
}
//分页
public List getScrollData(Integer offset, Integer maxResult){
List persons = new ArrayList();
SQLiteDatabase db = dbOpenHelper.getReadableDatabase();
Cursor cursor = db.rawQuery("select * from person limit ?,?",
new String[]{offset.toString(), maxResult.toString()});
//迭代
while(cursor.moveToNext()){//将指针移动到下一条数据上
int personid = cursor.getInt(cursor.getColumnIndex("personid"));
String name = cursor.getString(cursor.getColumnIndex("name"));
Person person = new Person(personid, name);
persons.add(person);//把得到的person加入到persons容器中
}
cursor.close();
return persons;
}
//得到总数
public long getCount() {
SQLiteDatabase db = dbOpenHelper.getReadableDatabase();
Cursor cursor = db.rawQuery("select count(*) from person", null);
cursor.moveToFirst();
return cursor.getLong(0);
}
}

最后新建一个测试类,主要是验证增删该查的功能是否实现了

package cn.itcast.db;

import java.util.List;

import cn.itcast.domain.Person;
import cn.itcast.service.DBOpenHelper;
import cn.itcast.service.PersonService;
import android.test.AndroidTestCase;
import android.util.Log;

public class PersonServiceTest extends AndroidTestCase {
private static final String TAG = "PersonServiceTest";

public void testCreateDB() throws Throwable{
DBOpenHelper dbOpenHelper = new DBOpenHelper(this.getContext());//new出DBOpenHelper对象,传入一个上下文参数
dbOpenHelper.getWritableDatabase();//第一次调用该方法就会创建数据库
}
//测试增加
public void testSave() throws Throwable{
//new出一个PersonService对象,传入一个上下文对象
PersonService personService = new PersonService(this.getContext());
Person person = new Person();
person.setName("xiaoxiao");
personService.save(person);

person = new Person();
person.setName("zhangliming");
personService.save(person);

person = new Person();
person.setName("libaobao");
personService.save(person);

person = new Person();
person.setName("taobao");
personService.save(person);
}
//测试更改
public void testUpate() throws Throwable{
PersonService personService = new PersonService(this.getContext());
Person person = personService.find(1);
person.setName("lili");
personService.update(person);
}
//测试删除
public void testDelete() throws Throwable{
PersonService personService = new PersonService(this.getContext());
personService.delete(1);
}
//测试查找
public void testFind() throws Throwable{
PersonService personService = new PersonService(this.getContext());
Person person = personService.find(1);
Log.i(TAG, person.toString());
}
//测试分页
public void testGetScrollData() throws Throwable{
PersonService personService = new PersonService(this.getContext());
List persons = personService.getScrollData(0, 3);
for(Person person : persons){
Log.i(TAG, person.toString());
}
}
//测试总数
public void testGetCount() throws Throwable{
PersonService personService = new PersonService(this.getContext());
Log.i(TAG, personService.getCount()+"");
}
}

实验测试:

[转载]JavaScript跨域访问问题解决方法

mikel阅读(1877)

[转载]js 跨域访问问题解决方法 – DWZ富客户端-jUI – 博客园.

什么引起了ajax不能跨域请求的问题?

ajax本身实际上是通过XMLHttpRequest对象来进行数据的交互,而浏览器出于安全考虑,不允许js代码进行跨域操作,所以会警告。

有什么完美的解决方案么?

解决方案有不少,但是只能是根据自己的实际情况来选择。

跨域的安全限制都是指浏览器端来说的,服务器端是不存在跨域安全限制的。所以针对这2种情况衍生出2类跨域解决方案,一类是服务器端做中转类似代理方式,一类是js处理浏览器端的真正跨域访问。


具体情况有:

  1.   本域和子域的相互访问: www.aa.combook.aa.com document.domain = “aa.com”;
  2. 本域和其他域的相互访问: www.aa.comwww.bb.com XMLHttpRequest访问代理,既服务器端代理方式
  3. 本域和其他域的相互访问: www.aa.comwww.bb.com JS创建动态脚本,<script>标签的src属性实现跨域访问

解决方法:

  1. 如果想做到数据的交互,那么www.aa.combook.aa.com必须由你来开发才可以。可以将book.aa.comiframe添加到 www.aa.com的某个页面下,www.aa.comiframe里面都加上document.domain = “aa.com”,这样就可以统一域了,可以实现跨域访问。就和平时同一个域中镶嵌iframe一样,直接调用里面的JS就可以了。
  2. 这种情形是最经常遇到的,也是用的最多的了。就是www.aa.comwww.bb.com你只能修改一个,也就是另外一个是别人的,人家告诉你你要取得数据就访问某某连接参数是什么样子的,最后返回数据是什么格式的。而你需要做的就是让你的服务器端充当中转代理,让服务器去别人的网站上取得数据,再返回给浏览器端。

服务器端充当中转代理方式有很多可以由服务器端程序实现,也可以修改服务器配置实现,下面举例Apache重写(mod_rewrite proxy模式)方式:
Apache的安装目录下的conf/httpd.conf 文件添加如下语句:

LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_http_module modules/mod_proxy_http.so
LoadModule rewrite_module modules/mod_rewrite.so
RewriteEngine On
RewriteRule ^/_proxy/(.*)$ http://$1 [P,L]

这样就可以把其他网站url映射为本服务器的/_proxy/目录下面, 例如可以这么访问百度http://html.duqn.com/_proxy/www.baidu.com


 这个的区别就是请求是使用<script>标签来请求的,这个要求也是两个域都是由你来开发才行。原理就是JS文件注入,在本域内的aa.com 内生成一个JS标签,它的SRC指向请求的另外一个域bb.com的某个页面bb返回数据即可,可以直接返回JS的代码。因为scriptsrc属性是可以跨域的。具体看代码,这个也比较简单

aa.com/a.jsp

<script type="text/JavaScript">
function myTest(data) {
    alert(data);
}
</script>
<script type="text/JavaScript" src="http://www.bb.com/index!getData.action?jsoncallback=myTest"></script>

bb.com/b.jsp页面代码如下:

$(param.jsoncallback)({"name": "Zhang Huihua", "QQ": "350863780"})

b.jsp页面通过$(param.jsoncallback)得到浏览器端随后要回调的js function name:myTest

实际上客户端接收到的response如下:myTest({“name”: “Zhang Huihua”, “QQ”: “350863780”})

JQuery浏览器端跨域访问

目前JQuery $.ajax()支持get方式的跨域,这其实是采用jsonp的方式来完成的。其原理就是上面第三种方式,<script>标签的src属性实现跨域访问

真实案例代码如下:

$.ajax({
    url: http://跨域的dns/index!searchJSONResult.action,
    type: "GET",
    dataType: 'jsonp',
    data: {name:”ZhangHuihua”},
    timeout: 5000,
    success: function (json) {//客户端JQuery预先定义好的callback函数,成功获取跨域服务器上的json数据后,会动态执行这个callback函数
        alert(json);
    },
    error: function (xhr, ajaxOptions, thrownError){
          alert("Http status: " + xhr.status + " " + xhr.statusText + "\najaxOptions: " + ajaxOptions + "\nthrownError:"+thrownError + "\n" +xhr.responseText);
    }
});

注意:

$.getJSON("http://跨域的dns/index!searchJSONResult.action?name1="+value1+"&jsoncallback=?", function(json){
    // 执行代码
});

这种方式其实是上例$.ajax({..}) api的一种高级封装,有些$.ajax api底层的参数就被封装而不可见了.

这样,jQuery就会拼装成如下的url get请求

http:// 跨域的 dns/index!searchJSONResult.action?&jsoncallback=jsonp1236827957501&_=1236828192549&name=ZhangHuihua

在响应端(http://跨域的dns/index!searchJSONResult.action),

通过 jsoncallback = request.getParameter(“jsoncallback”) 得到jQuery端随后要回调的js function name:jsonp1236827957501

然后 response的内容为一个Script Tags:”jsonp1236827957501(“+按请求参数生成的json数组+”)”;

jquery就会通过回调方法动态加载调用这个js tag:jsonp1236827957501(json数组);

这样就达到了跨域数据交换的目的.


jsonp的最基本的原理是:动态添加一个<script>标签,而script标签的src属性是没有跨域的限制的。这样说来,这种跨域方式其实与ajax XmlHttpRequest协议无关了.

这样其实“jQuery AJAX跨域问题就成了个伪命题了,jquery $.ajax方法名有误导人之嫌.

如果设为dataType: ‘jsonp’, 这个$.ajax方法就和ajax XmlHttpRequest没什么关系了,取而代之的则是JSONP协议.

JSONP是一个非官方的协议,它允许在服务器端集成Script tags返回至客户端,通过javascript callback的形式实现跨域访问

JSONPJSON with Padding。由于同源策略的限制,XmlHttpRequest只允许请求当前源(域名、协议、端口)的资源。如果要进行跨域请求,

我们可以通过使用htmlscript标记来进行跨域请求,并在响应中返回要执行的script代码,其中可以直接使用JSON传递javascript对象。

这种跨域的通讯方式称为JSONP

jsonCallback 函数jsonp1236827957501(….): 是浏览器客户端注册的,获取跨域服务器上的json数据后,回调的函数


Jsonp原理:

首先在客户端注册一个callback (:’jsoncallback’), 然后把callback的名字(:jsonp1236827957501)传给服务器。

此时,服务器先生成 json 数据。

然后以 javascript 语法的方式,生成一个function , function 名字就是传递上来的参数 ‘jsoncallback’的值 jsonp1236827957501 .

最后将 json 数据直接以入参的方式,放置到 function 中,这样就生成了一段 js 语法的文档,返回给客户端。

客户端浏览器,解析script标签,并执行返回的 javascript 文档,此时javascript文档数据,作为参数,

传入到了客户端预先定义好的 callback 函数(如上例中jquery $.ajax()方法封装的的success: function (json)).(动态执行回调函数)

可以说jsonp的方式原理上和<script src=”http://跨域/…xx.js”></script>是一致的(qq空间就是大量采用这种方式来实现跨域数据交换的) .JSONP是一种脚本注入(Script Injection)行为,所以也有一定的安全隐患.


注意,jquey是不支持post方式跨域的.

虽然采用post +动态生成iframe是可以达到post跨域的目的,但这样做是一个比较极端的方式,不建议采用.

也可以说get方式的跨域是合法的,post方式从安全角度上,被认为是不合法的, 万不得已还是不要剑走偏锋..

浏览器端跨域访问的需求看来也引起w3c的注意了,看资料说html5 WebSocket标准支持跨域的数据交换,应该也是一个将来可选的跨域数据交换的解决方案.

[转载]SQL语句join on 和 where条件引发的执行顺序解读

mikel阅读(1091)

[转载]SQL语句join on 和 where条件 引发的执行顺序解读!!! – Rouse Law – 博客园.

SQL server 2000和SQL Server 2005的各个逻辑步骤的简单描述。

(8)SELECT (9)DISTINCT  (11)<Top Num><select list>
(
1)FROM[left_table]
(
3)<join_type>JOIN<right_table>
(
2)        ON<join_condition>
(
4)WHERE<where_condition>
(
5)GROUPBY<group_by_list>
(
6)WITH<CUBE | RollUP>
(
7)HAVING<having_condition>
(
10)ORDERBY<order_by_list>
逻辑查询处理阶段简介

FROM:对FROM子句中的前两个表执行笛卡尔积(Cartesian product)(交叉联接),生成虚拟表VT1
ON:对VT1应用ON筛选器。只有那些使<join_condition>为真的行才被插入VT2。
OUTER(JOIN):如 果指定了OUTER JOIN(相对于CROSS JOIN 或(INNERJOIN),保留表(preserved table: 左外部联接把左表标记为保留表,右外部联接把右表标记为保留表,完全外部联接把两个表都标记为保留表)中未找到匹配的行将作为外部行添加到 VT2,生成VT3.如果FROM子句包含两个以上的表,则对上一个联接生成的结果表和下一个表重复执行步骤1到步骤3,直到处理完所有的表为止。
WHERE:对VT3应用WHERE筛选器。只有使<where_condition>为true的行才被插入VT4.
GROUPBY:按GROUP BY子句中的列列表对VT4中的行分组,生成VT5.
CUBE
|ROLLUP:把超组(Suppergroups)插入VT5,生成VT6.
HAVING:对VT6应用HAVING筛选器。只有使<having_condition>为true的组才会被插入VT7.
SELECT:处理SELECT列表,产生VT8.
DISTINCT:将重复的行从VT8中移除,产生VT9.
ORDERBY:将VT9中的行按ORDER BY 子句中的列列表排序,生成游标(VC10).
TOP:从VC10的开始处选择指定数量或比例的行,生成表VT11,并返回调用者。

[转载]推荐大家一个保护视力的Visual Studio皮肤

mikel阅读(1111)

[转载]推荐大家一个保护视力的Visual Studio皮肤 – Terry Zeng – 博客园.

推荐大家保护视力的皮肤下载网站:http://studiostyl.es/schemes

本人比较喜欢这款:http://studiostyl.es/schemes/coding-horror-2010

——————————————————————————————————

使用方法转载于:http://www.cnblogs.com/n-pei/archive/2010/07/04/1771050.html

皮肤的安装:

这个我觉得大部分人应该都会,,不过对于VS新手还是说说吧。

首先你打开VS,然后选择工具,导入导出设置,如下图:

接下来的界面中,选择导入皮肤:

点击下一步,会提示你是否备份现有的皮肤,最好备份下。

备份完后再点击下一步,点击浏览按钮,把你刚才下载的皮肤导入:

然后点击完成,就O啦。

希望对你的眼睛有帮助。

[转载]Html5版本的全套股票行情图开源了

mikel阅读(1019)

[转载]Html5版本的全套股票行情图开源了,附带实现技术简介 – 玉开 – 博客园.

请使用支持html5的浏览器查看,推荐使用google chrom或者ipad体验,ie6,7,8都不支持html5

下面是行情图的快照和每个图的实现难点简介,有兴趣的朋友请用svn checkout出来,或者直接访问项目文件看源码 。

Google code的项目地址是:https://html54stock.googlecode.com

K线图 滑块控制

这个K线图和flash实现的K线图非常接近,滑块控制是实现的难点,这里是根据滑块滑动的位置计算k线数据的范围,并实时重画,事实证明 html5 canvas标签的性能还是相当的好的,在PC机上每秒可以重画20次以上,而在iPad上每秒可以重画10次左右,在ipad上流畅性有一定问题,所以 在ipad上实现了另外一个版本,使用手指滑动通过touch相关的时间控制范围

K线图 触摸控制

请使用ipad体验效果 

这个K线图和上面的基本一样,但是控制K线范围改用了触摸事件,用touchstart,touchmove等事件,这个需要事实计算手指所在的坐标,然后根据坐标判断是否要显示浮窗,显示K线柱的高,开,低,收等信息。

大分时图

分时图的实现是在一张画布上,当鼠标在画布上移动时,需要根据鼠标的坐标出十字,并显示鼠标所在时间的价格,这儿的十字叉是div实现的,而在画布 上显示对应时间的价格是用了画布的clearRect方法,先把指定区域的内容清除掉,然后再重新画上对应价格。这样实现的流畅性非常的好,无论是在平板 上还是在PC上。

小分时图

交易分析图

交易分析图画图不是难点,难点在于对鼠标事件或touch事件的处理,上图中的浮动框、十字叉都是div,这样的性能可以接受,而事实修改画布则不流畅。

成交额分析图

成交额分析图的实现基本上没什么难点。

 

个人非常看好html5。对html5有兴趣希望参与项目的朋友,请与我联系。

[原创]ASP.NET使用Fckeditor图片上传路径错误问题解决办法

mikel阅读(1153)

问题:

我用FCKeditor的快速上传把图片上传到UserFiles文件夹下,可是用图片属性里面的浏览服务器确看不到图片,那个浏览服务器浏览的是 UserFiles/Image文件夹下面的图片,而我快速上传的路径是UserFiles文件夹下,我把上传路径改为UserFiles/Image, 可是那个浏览服务器的路径自动变为UserFiles/Image/Image,始终和我上传的路径不一致,请问怎样设置能够让浏览服务器的路径指向 UserFiles文件夹下面,而不是指向Image下面?

解决办法:

修改了/fckedior/editor/filemanager/connectors/aspx/config.ascx文件的快速上传路径为%UserFileAbsolutPath%image/

修改代码如下:

TypeConfig[ "Image" ].AllowedExtensions = new string[] { "bmp", "gif", "jpeg", "jpg", "png" };
TypeConfig[ "Image" ].DeniedExtensions = new string[] { };
TypeConfig[ "Image" ].FilesPath = "%UserFilesPath%image/";
TypeConfig[ "Image" ].FilesAbsolutePath = ( UserFilesAbsolutePath == "" ? "" : "%UserFilesAbsolutePath%image/" );
TypeConfig["Image"].QuickUploadPath = "%UserFilesPath%image/";
TypeConfig["Image"].QuickUploadAbsolutePath = (UserFilesAbsolutePath == "" ? "" : "%UserFilesAbsolutePath%image/");

上传文件或者flash其他类型的类似

[转载]asp.net fckeditor使用方法|fck经验总结|ckeditor.net问题|FCKeditor1.Value为空

mikel阅读(1173)

[转载]asp.net fckeditor使用方法|fck经验总结|ckeditor.net问题|FCKeditor1.Value为空_asp.net web程序员软件开发_百度空间.

1、保存的时候没有值,FCKeditor1.Value为空?

可能是form表单应该runat=”server”。

不然的话就是逻辑问题(或者是值没变的问题),在获取页面输入之后又重新加载了页面,设置了FCKeditor1.Value。

 

2、使用FCK需要设置的几个地方?

下载有2个rar文件,dll和fckeditor目录。需要设置dll、fckeditor目录、web.config、page页面引入以及标签使用<FCKeditor …>

 

runat=”server”的块,不能显示<%=%>的内容
= = = = = = =出现“未能加载类型 FredCK.FCKeditorV2.Uploader”
原因是使用得例程版本与控件版本不一致,导致命名空间不一致,修改办法:改为正确的即可,位于fckedior目录内
例如:
<%@ Page language=”C#” Inherits=”FredCK.FCKeditorV2.FileBrowser.Uploader” AutoEventWireup=”false” %>
<%@ Page language=”C#” Inherits=”FredCK.FCKeditorV2.FileBrowser.Connector” AutoEventWireup=”false” %>

[转载]FCKeditor 2.3 在ASP.NET中的设置和使用

mikel阅读(986)

[转载]FCKeditor 2.3 在ASP.NET中的设置和使用 – cnming的专栏 – 博客频道 – CSDN.NET.

框架都一样,两个链接有可能下载不到了

 

 

 

一、准备工作

首先下载最新版的FCKeditor V2.3,下载地址:http://prdownloads.sourceforge.net/fckeditor /FCKeditor_2.3.zip?download;这个压缩包里并不包含ASP.NET要用到的DLL控件,所以还要下载另外一个压缩包,下载地 址:http://sourceforge.net/project/showfiles.php?group_id=75348& package_id=137125。把第一个文件解压到WEB根目录,默认文件夹名为:FCKeditor;再把第二个包解压,里面包含了源代码,如果 你想自己再次开发,可以双击 FredCK.FCKeditorV2.csproj文件,打开VS.NET进行修改,所用的语言是C#;不想修改的话,直接把bin/Release下 面的FredCK.FCKeditorV2.DLL文件拷到WEB目录的bin下面。

二、精简文件

因为只用到ASP.NET,所以有必要精简一下文件。
进入FCKeditor文件夹,把所有“_”开头的文件和文件夹删掉,这些都是一些范例,只保留editor文件夹、fckconfig.js、fckeditor.js、fckstyles.xml、fcktemplates.xml就可以了;
进入editor文件夹,删掉“_source”文件夹,里面放的同样是源文件;
退回上一级目录进入filemanager文件夹,有browser和upload两个文件夹。进入browser/default/connectors,只保留aspx文件夹,其余的删掉;mcpuk目录亦可删除;upload也一样,只保留aspx文件夹;
退到editor再进入images文件夹,smiley里面放的是表情图标,有msn和fun两个系列,如果你想用自己的表情图标,可以把它们都删除;如果你想用这里的表情图标那就不要删了;
lang里面放的是语言包,如果只是用简体中文,那么只保留fcklanguagemanager.js、zh-cn.js两个文件就行了,建议也保留 en.js(英文)、zh.js(繁体中文)两个文件,fcklanguagemanager.js是语言配置文件,有了它才能和 fckconfig.js里的设置成对,对应上相应的语言文件,一定要保留!
再退出lang文件夹,进入skins文件夹,如果你想使用FCKeditor默认的奶黄色,那就把除了default文件夹外的另两个文件夹直接删除,如果想用别的,那就看你自己的喜好了,不要上传文件的话把filemanager也删除算了。
至此,文件精简完毕,由原来的2.55M变成现在的689K了。接着修改设置。

三、修改设置

打开位于根目录的fckconfig.js文件。
FCKConfig.SkinPath = FCKConfig.BasePath + ‘skins/default/’ ;这行是设置皮肤的,如果精简时保留了silver,就把路径改成skins/silver,默认就不用管它了;
FCKConfig.DefaultLanguage = ‘en’ ;设置默认语言,把en改成zh-cn,即简体中文;
FCKConfig.TabSpaces = 0;如果在编辑过程中要用到TAB键,就把0改成1;
因为FCKeditor默认是ASP的,所以要把它换成ASP.NET。把ASP跟其它被注释掉的代码删掉,用ASP.NET来代替。例如:
var _FileBrowserLanguage    = ‘aspx’
var _QuickUploadLanguage    = ‘aspx’
余下的代码都按照以上操作,删掉其它WEB语言,只保留ASP.NET。也可以点这里下载我精简过的文件,注意:只适用于ASP.NET,其他语言勿下!建议先解压到别的目录,再复制到WEB目录相对应的位置,以免造成文件丢失。
改完后保存,FCKeditor已经完全支持ASP.NET了。当然还有一些安全问题,只要修改相应的toolbar,鼠标右键菜单等等,因为我的后台 不面对前台用户的,即没有留言本和日记回复,所以略过这些步骤。下一步是打开VS.NET,在ASP.NET页面中加入FCKeditor。

四、ASP.NET中的应用

打开项目的“资源管理器”,添加“FredCK.FCKeditorV2”引用。
打开添加文章、管理文章相对应的文件以修改其中的内容。下面以“添加文章”为例。切换到“HTML”界面,添加FCK的引用,代码如下:
<%@ Register TagPrefix=”FCKeditorV2″ Namespace=”FredCK.FCKeditorV2″ Assembly=”FredCK.FCKeditorV2″ %>
并 确保@ Page中的“AutoEventWireup”“validateRequest”两个值都为false,不然当你发表的文章中含有链接或是其他 HTML语句时,.NET会警告你有安全隐患而出错。在form的适当位置加入FCKeditor控件,当然form一定要有“runat= “server””,代码如下:
<FCKeditorV2:FCKeditor id=”content” runat=”server”></FCKeditorV2:FCKeditor>
id可以自己命名,自己喜欢易记就行。如果程序中有检测输入是否为空的话,那么就不再是content.Text了,而是content.Value。
至此,文件修改完毕。所有代码如下:

 

程序代码 程序代码
<%@ Page language=”C#” Codebehind=”AdminFileAdd.aspx.cs” AutoEventWireup=”false” Inherits=”MyBlog.Admin.AdminFileAdd” validateRequest=false%>
<%@ Register TagPrefix=”FCKeditorV2″ Namespace=”FredCK.FCKeditorV2″ Assembly=”FredCK.FCKeditorV2″ %>
<!DOCTYPE HTML PUBLIC “-//W3C//DTD HTML 4.0 Transitional//EN” >
<HTML>
<HEAD>
<title>AdminFileAdd</title>
<meta content=”Microsoft Visual Studio .NET 7.1″ name=”GENERATOR”>
<meta content=”C#” name=”CODE_LANGUAGE”>
<meta content=”JavaScript” name=”vs_defaultClientScript”>
<meta content=”http://schemas.microsoft.com/intellisense/ie5″ name=”vs_targetSchema”>
<LINK href=”admin.css” type=”text/css” rel=”stylesheet”>
</HEAD>
<body class=”right”>
<form id=”Form1″ method=”post” runat=”server”>
<div>添加文章</div>
<div class=”main”>
<ul>
<li>
标题:<asp:textbox id=”title” runat=”server” MaxLength=”50″ Width=”250px”></asp:textbox>
<li>
栏目:<asp:dropdownlist id=”m” runat=”server” AutoPostBack=”True”></asp:dropdownlist>
<li>
<FCKeditorV2:FCKeditor id=”content” runat=”server”></FCKeditorV2:FCKeditor>
<li>
<asp:button id=”add” runat=”server” Text=”提 交”></asp:button>
</li>
</ul>
</div>
</form>
</body>
</HTML>

 

 

 

发生“未能加载类型 FredCK.FCKeditorV2.Uploader ”请见

 

http://blog.csdn.net/cnming/archive/2008/02/28/2129070.aspx

 

 

 

相关链接

FCKeditor   2.3   在ASP.NET中的设置和使用
http://blog.csdn.net/cnming/archive/2008/02/28/2128474.aspx

Fckeditor   2.5   for   asp.net配置详解
http://blog.csdn.net/cnming/archive/2008/02/28/2128616.aspx

FCKeditor相关资料简介
http://blog.csdn.net/cnming/archive/2008/02/28/2128886.aspx

未能加载类型   FredCK.FCKeditorV2.Uploader
http://blog.csdn.net/cnming/archive/2008/02/28/2129070.aspx

[转载]asp.net网站开发中用jquery实现滚动浏览器滚动条加载数据(类似于腾讯微博)

mikel阅读(1022)

[转载]asp.net网站开发中用jquery实现滚动浏览器滚动条加载数据(类似于腾讯微博) – Tandy Tang – 博客园.

自从腾讯微博上线以来,基本上就开始用了,一直到现在,作为一个开发人员,也看到了腾讯微博一直在不停的改变,也不知道大家有没有发现,腾讯微 博提供两种加载数据的方式,一种是分页,一种是滚动浏览器滚动条加载数据,分页功能我想大家都做得太多了,今天我与大家分享一下我用滚动条滚动加载数据, 小生不才,还望各位大侠指教,呵呵~

下面开讲:

首先说一下思路,我用的是JQuery,然后通过JQuery的ajax()方法通过 HTTP 请求加载远程数据来实现的,用到jQuery,首先要应用jQuery.min.js类库,如果本地没有,也可以直接引用下面地址<script type=”text/JavaScript” src=”http://ajax.googleapis.com/ajax/libs/jquery/1.4.0/jquery.min.js”></script>。

好吧,下面我们看下核心代码:

// - -!,你懂的.
            var count=<%=allcount %>;
            var times=0;
            var loaded = true;
            function Add_Data()
            {
              var top = $("#main_left_add").offset().top;
              if(loaded && ($(window).scrollTop() + $(window).height() > top))
              {
                 $("#main_left_add").html("数据加载中...");
                 times++;
                 $.ajax(
                 {
                     type: "POST",
                     dataType: "text",
                     url: "weibo.ashx",
                     data: "userid="+<%=hf.Value %>+"&touserid="+<%=hf1.Value %>+"&count="+count+"&times="+times+"&type=1",
                     success: function(data)
                     {
                        //alert("第"+times+"次追加数据.");
                        if(data == "没有数据")
                        {
                            $("#main_left_add").css("display","none");
                            loaded=false;
                            AddEffect();
                        }
                        else if(data == "")
                        {
                            $("#main_left_add").html("点击加载更多...");
                            $("#main_left_add").css("display","block");
                            loaded=false;
                            AddEffect();
                        }
                        else if(data != "")
                        {
                            $("#main_left_down").append(data);                            
                            AddEffect();
                        }
                     }
                  }
                );
              }
            }
            $(window).scroll(Add_Data);            
            //点击追加数据
            $("#main_left_add").click(function(){
                $.ajax({
                    type: "POST",
                    dataType: "text",
                    url: "weibo.ashx",
                    data:"userid="+<%=hf.Value %>+"&touserid="+<%=hf1.Value %>+"&count="+count+"&times="+times+"&type=2",
                    success: function(data){
                        if(data=="没有数据")
                        {
                            $("#main_left_add").css("display","none");
                            AddEffect();
                        }
                        else
                        {
                            $("#main_left_down").append(data);
                            $("#main_left_add").html("点击加载更多...");
                            AddEffect();                            
                        }
                    }
            });
            //鼠标移动效果
            $("#main_left_add").mouseover(function(){
                $(this).css("background-color","#e4eef8");
            });
            $("#main_left_add").mouseout(function(){
                $(this).css("background-color","#f0f5f8");
            });

  这是前台js代码,下面我稍微的解释一下代码:count是定义的数据总数,定义两个div,一的div用来追加数据,一个div用来判断滚动条的位置,再建一个*.ashx文件用来处理程序并返回相应的数据,根据此数据我们肯定判断加载情况,滚动追加完成后我还多加了一个”点击加载更多的功能…”,此功能实现也与上面差不多…代码都在上面,供大家参考。

  注意:为了防止滚动事件一直会被执行,所以才定义了一个loaded来控制滚动事件的执行。