Position: CSST软件>> 手机开发                          

ubuntu 下安装eclipse ( Archived on 2009-11-25 11:44:20 104 Views )

1、官方下载:http://www.eclipse.org/downloads/

2、解压到指定目录:/opt
可先解压到当前目录然后
mv eclipse /opt

(1)如果想把eclipse目录的更改为root拥有,可以执行下面的命令
sudo chown -R root:root /opt/eclipse
在/usr/bin目录下创建一个启动脚本eclipse

(2)用下面的命令来创建:
sudo gedit /usr/bin/eclipse

然后在该文件中添加以下内容:
#!/bin/sh
export MOZILLA_FIVE_HOME=”/usr/lib/mozilla/”
export ECLIPSE_HOME=”/opt/eclipse”

$ECLIPSE_HOME/eclipse $*

(3)让修改该脚本的权限,让它变成可执行,执行下面的命令:
sudo chmod +x /usr/bin/eclipse

3、在桌面或者gnome菜单中添加eclipse启动图标

(1)在桌面或者启动面板上添加图标:
在桌面(右键单击桌面->创建启动器)或面板(右键单击面板->添加到面板 ->定制应用程序启动器)上创建一个新的启动器,然后添加下列数据:

名称:Eclipse Platform
命令:eclipse
图标: /opt/eclipse/icon.xpm

(2)在Applications(应用程序)菜单上添加一个图标
用文本编辑器在/usr/share/applications目录里新建一个名为eclipse.desktop的启动器,如下面的命令:

sudo vi /usr/share/applications/eclipse.desktop
或者
sudo gedit /usr/share/applications/eclipse.desktop

然后在文件中添加下列内容:

[Desktop Entry]
Encoding=UTF-8
Name=Eclipse Platform
Comment=Eclipse IDE
Exec=eclipse
Icon=/opt/eclipse/icon.xpm
Terminal=false
StartupNotify=true
Type=Application
Categories=Application;Development;

保存文件。完成整个安装过程。可以双击桌面eclipse的图标来运行eclipse。


邮件正文中带图片的邮件发送方法 ( Archived on 2009-11-3 16:41:44 233 Views )

using System.Net.Mail;

private void SendMail()
{
    string mailFrom = "george@tom.com";//发送人
    string mailSendTo = "tom@tom.com";//接收人
    string subject = "Send Inline Image Email Test";//主题
    MailMessage email = new MailMessage(mailFrom, mailSendTo);
    email.To.Add("cs_chenzz@qq.com");//添加收件人
    email.To.Add("cliton@qq.com");

    email.CC.Add("andy@sina.com");//添加抄送人

    Attachment attachment = new Attachment(txtImagePath.Text);//图片附件
    //Random rgen = new Random();
    attachment.ContentId = Guid.NewGuid().ToString();//rgen.Next(100000, 9999999).ToString();
    email.Attachments.Add(attachment);//添加图片附件到邮件
    email.Subject = subject;
    email.Body = string.Format("& lt;html><head><title>CSOFT</title>< /head><body>{0}<br><img src='cid:{1}'></body& gt;</html>", txtBody.Text, attachment.ContentId);//生成包含图片的邮件正文
    email.IsBodyHtml = true;//设置邮件发送格式为html格式

    SmtpClient client = new SmtpClient();

    client.Host = "smtp.yeetung.com";//邮件发送服务器
    client.UseDefaultCredentials = false;
    client.Credentials = new System.Net.NetworkCredential("username", "password");//登陆服务器的用户名和密码
    client.DeliveryMethod = SmtpDeliveryMethod.Network;

    client.Send(email);
}


日期格式化{0:yyyy-MM-dd HH:mm:ss.fff}和{0:yyyy-MM-dd hh:mm:ss.fff}的区别 ( Archived on 2009-10-14 22:01:05 408 Views )

{0:yyyy-MM-dd HH:mm:ss.fff}:使用24小时制格式化日期
{0:yyyy-MM-dd hh:mm:ss.fff}:使用12小时制格式化日期

以下同理,从左至右分别为-年-月-日 时:分:秒.毫秒
{0:yyyy-MM-dd HH:mm:ss zzz}
{0:yyyy-MM-dd HH:mm:ss.ff zzz}
{0:yyyy-MM-dd HH:mm:ss.fff zzz}
{0:yyyy-MM-dd HH:mm:ss.ffff zzz}

以下测试代码
//---假设时间为-2009-03-17 16:50:49.92
object objValue2 = Business.Services.ExecuteScalar(sqliteconnstring, "Select LastUpdate From CmItemClass2 order by LastUpdate desc limit 0,1");
string lastUpdate2 = objValue2 == null ? string.Empty : string.Format(" {0:yyyy-MM-dd HH:mm:ss.fff}", objValue2); //--输出2009-03-17 16:50:49.920
string lastUpdate3 = objValue2 == null ? string.Empty : string.Format(" {0:yyyy-MM-dd hh:mm:ss.fff}", objValue2); //--输出2009-03-17 04:50:49.920

//--------------------
y 将指定 DateTime 对象的年份部分显示为位数最多为两位的数字。忽略年的前两位数字。如果年份是一位数字 (1-9),则它显示为一位数字。
yy 将指定 DateTime 对象的年份部分显示为位数最多为两位的数字。忽略年的前两位数字。如果年份是一位数字 (1-9),则将其格式化为带有前导 0 (01-09)。
yyyy 显示指定 DateTime 对象的年份部分(包括世纪)。如果年份长度小于四位,则按需要在前面追加零以使显示的年份长度达到四位。

z 仅 以整小时数为单位显示系统当前时区的时区偏移量。偏移量总显示为带有前导或尾随符号(零显示为“+0”),指示早于格林威治时间 (+) 或迟于格林威治 时间 (-) 的小时数。值的范围是 –12 到 +13。如果偏移量为一位数 (0-9),则将其显示为带合适前导符号的一位数。该时区的设置指定 为 +X 或 –X,其中 X 是相对 GMT 以小时为单位的偏移量。所显示的偏移量受夏时制的影响。
zz 仅以整小时数为单位显示系统当前时 区的时区偏移量。偏移量总显示为带有前导或尾随符号(零显示为“+00”),指示早于格林威治时间 (+) 或迟于格林威治时间 (-) 的小时数。值范 围为 –12 到 +13。如果偏移量为单个数字 (0-9),则将其格式化为前面带有 0 (01-09) 并带有适当的前导符号。该时区的设置指定 为 +X 或 –X,其中 X 是相对 GMT 以小时为单位的偏移量。所显示的偏移量受夏时制的影响。
zzz, zzz(外加任意数量的附加 “z”字符)以小时和分钟为单位显示系统当前时区的时区偏移量。偏移量总是显示为带有前导或尾随符号(零显示为“+00:00”),指示早于格林威治时 间 (+) 或迟于格林威治时间 (-) 的小时和分钟数。值范围为 –12 到 +13。如果偏移量为单个数字 (0-9),则将其格式化为前面带 有 0 (01-09) 并带有适当的前导符号。该时区的设置指定为 +X 或 –X,其中 X 是相对 GMT 以小时为单位的偏移量。所显示的偏移量 受夏时制的影响。

: 时间分隔符。
/ 日期分隔符。
" 带引号的字符串。显示转义符 (/) 之后两个引号之间的任何字符串的文本值。 
' 带引号的字符串。显示两个“'”字符之间的任何字符串的文本值。
%c 其中 c 是标准格式字符,显示与格式字符关联的标准格式模式。
\c 其中 c 是任意字符,转义符将下一个字符显示为文本。在此上下文中,转义符不能用于创建转义序列(如“\n”表示换行)。
任何其他字符 其他字符作为文本直接写入输出字符串。

向 DateTime.ToString 传 递自定义模式时,模式必须至少为两个字符长。如果只传递“d”,则公共语言运行库将其解释为标准格式说明符,这是因为所有单个格式说明符都被解释为标准格 式说明符。如果传递单个“h”,则引发异常,原因是不存在标准的“h”格式说明符。若要只使用单个自定义格式进行格式化,请在说明符的前面或后面添加一个 空格。例如,格式字符串“h”被解释为自定义格式字符串。

下表显示使用任意值 DateTime.Now(该值显示当前时间)的示例。示 例中给出了不同的区域性和时区设置,以阐释更改区域性的影响。可以通过下列方法更改当前区域性:更改 Microsoft Windows 的“日期/时 间”控制面板中的值,传递您自己的 DateTimeFormatInfo 对象,或将 CultureInfo 对象设置传递给不同的区域性。此表是说 明自定义日期和时间说明符如何影响格式化的快速指南。请参阅该表下面阐释这些说明符的代码示例部分。

格式说明符 当前区域性 时区 输出
d, M en-US GMT 12, 4
d, M es-MX GMT 12, 4
d MMMM en-US GMT 12 April
d MMMM es-MX GMT 12 Abril
dddd MMMM yy gg en-US GMT Thursday April 01 A.D.
dddd MMMM yy gg es-MX GMT Jueves Abril 01 DC
h , m: s en-US GMT 6 , 13: 12
hh,mm:ss en-US GMT 06,13:12
HH-mm-ss-tt en-US GMT 06-13-12-AM
hh:mm, G\MT z  en-US GMT 05:13 GMT +0
hh:mm, G\MT z  en-US GMT +10:00 05:13 GMT +10
hh:mm, G\MT zzz en-US GMT 05:13 GMT +00:00
hh:mm, G\MT zzz en-US GMT -9:00 05:13 GMT -09:00


C#中GUID的使用 ( Archived on 2009-10-14 21:56:46 820 Views )

GUID(全局统一标识符)是指在一台机器上生成的数字,它保证对在同一时空中的所有机器都是唯一的。通常平台会提供生成GUID的API。生成算法很有意思,用到了以太网卡地址、纳秒级时间、芯片ID码和许多可能的数字。GUID的唯一缺陷在于生成的结果串会比较大。”

1. 一个GUID为一个128位的整数(16字节),在使用唯一标识符的情况下,你可以在所有计算机和网络之间使用这一整数。

2. GUID 的 格式为“xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx”,其中每个 x 是 0-9 或 a-f 范围内的一个十六进制的 数字。例如:337c7f2b-7a34-4f50-9141-bab9e6478cc8 即为有效的 GUID 值。

3. 世界上(Koffer注:应该是地球上)的任何两台计算机都不会生成重复的 GUID 值。GUID 主要用于在拥有多个节点、多台计算机的网络或系统中,分配必须具有唯一性的标识符。

4. 在 Windows 平台上,GUID 应用非常广泛:注册表、类及接口标识、数据库、甚至自动生成的机器名、目录名等。

.NET中使用GUID 

当Windows开发人员需要一个唯一数值时,他们通常使用到一个全局唯一标识符(GUID, Globally Unique Identifier)。微软采用GUID术语来表示这一唯一数值,而这一数值能够标识一个实体,比如一个Word文档。

一个GUID为一个128位的整数(16字节),在使用唯一标识符的情况下,你可以在所有计算机和网络之间使用这一整数。

这一篇文章将解释.NET框架如何尽其最大潜力地为你建立自己的GUID。

你所看到的

GUIDs被用于整个Windows环境。当你在一个Windows系统中仔细阅读注册表时,你可以看到GUIDs被广泛用于唯一识别程序。特别地,它们作为程序的Ids集中在HKEY_CLASSES_ROOT部分(AppID键)。

这就是一个典型的GUID的格式:

936DA01F-9ABD-4d9d-80C7-02AF85C822A8

在.NET中生成一个GUID

处理一个唯一标识符使得存储和获得信息变得更加容易。在处理一个数据库中这一功能变得尤其有用,因为一个GUID能够操作一个主键。

同 样,SQL Server也很好地集成了GUID的用途。SQL Server数据类型uniqueidentifier能够存储一个GUID数值。你可 以通过使用NEWID()函数在SQL Server中生成这一数值,或者可以在SQL Server之外生成GUID,然后再手动地插入这一数值。

在.NET中,后面一种方法显得更加直接。.NET Framework中的基本System类包括GUID数值类型。除此之外,这一数值类型包含了处理GUID数值的方法。特别地,NewGUID方法允许你很容易地生成一个新的GUID。

以下的C#命令行程序说明这一使用过程:
using System;
namespace DisplayGUID {
class GuidExample {
static void Main(string[] args) {
Console.WriteLine("GUID: " + System.Guid.NewGuid().ToString());
}
} }

下面为这一程序的输出:(虽然不同系统之间的GUID是变化的。)

GUID: 9245fe4a-d402-451c-b9ed-9c1a04247482

在这一点上,你可以看到GUID是一个很好的功能,但在程序的什么地方使用到它们,并如何使用它们?

在程序中使用一个GUID

一个GUID可以在后台数据库中操作一个主键。以下代码使用一个GUID在一个后台数据库中存储信息,这一数据库包含以下的列:

pk_guid—uniqueidentifier数据类型
name—nvarchar数据类型
这样出现一个包含文本框的简单Windows窗体。当选择按钮时,文本框中的数据被插入到数据库中。通过程序代码可以生成一个GUID并存储在其它列中:

StringBuilder strSql = new StringBuilder();
strSql.Append("Insert into cs_Content(");
strSql.Append("Log_guid, Log_Title, Log_Content, Log_PostTime, Log_ViewNums)");
strSql.Append(" values (");
strSql.Append("@Log_guid, @Log_Title, @Log_Content, @Log_PostTime, @Log_ViewNums)");

DbCommand dbCommand = db.GetSqlStringCommand(strSql.ToString());

string guid = Guid.NewGuid().ToString();
// Add parameters
db.AddInParameter(dbCommand, "Log_guid", DbType.String, guid);
db.AddInParameter(dbCommand, "Log_Title", DbType.String, model.Log_Title);
db.AddInParameter(dbCommand, "Log_Content", DbType.String, model.Log_Content);
db.AddInParameter(dbCommand, "Log_PostTime", DbType.DateTime, model.Log_PostTime);
db.AddInParameter(dbCommand, "Log_ViewNums", DbType.Int32, model.Log_ViewNums);

int res = db.ExecuteNonQuery(dbCommand);


另一个GUID程序将一个唯一的标识符分配给一个.NET类或者接口,也就是说,GUID作为一个属性被分配给类或者接口。可以使用标准属性语法来实现这一过程

我们可以扩展第一个范例来分配一个GUID。System.Runtime.InteropServices空间名称必须被引用来使用GUID属性。以下C#代码实现了这一过程:

using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;

// 有关程序集的常规信息通过下列属性集
// 控制。更改这些属性值可修改
// 与程序集关联的信息。
[assembly: AssemblyTitle("Test")]

// 将 ComVisible 设置为 false 使此程序集中的类型
// 对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型,
// 则将该类型上的 ComVisible 属性设置为 true。
[assembly: ComVisible(false)]

// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
[assembly: Guid("198cfad8-041f-4141-8961-776b29af7a06")]

// 程序集的版本信息由下面四个值组成:
//
//      主版本
//      次版本 
//      内部版本号
//      修订号
//
// 可以指定所有这些值,也可以使用“内部版本号”和“修订号”的默认值,
// 方法是按如下所示使用“*”:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

GUID永远是方便的
对于程序开发的各个方面,.NET Framework简化了建立和处理GUID数值的过程。在.NET程序需要的地方,这一功能很容易地生成唯一的数值。

------------
1、Guid.NewGuid().ToString("N") 结果为:
    38bddf48f43c48588e0d78761eaa1ce6
2、Guid.NewGuid().ToString("D") 结果为:
    57d99d89-caab-482a-a0e9-a0a803eed3ba
3、Guid.NewGuid().ToString("B") 结果为:
    {09f140d5-af72-44ba-a763-c861304b46f8}
4、Guid.NewGuid().ToString("P") 结果为:
    (778406c2-efff-4262-ab03-70a77d09c2b5)
可见默认的为第2种效果

将字符串形式的GUID:EF41A66B-25E1-46B2-964B-E4F70534807F转换为System.Guid类型
System.Guid mGuid=new Guid("EF41A66B-25E1-46B2-964B-E4F70534807F");
-----------------
guid的每段位数:8+4+4+4+12
-------------------
GUID重复的可能性几乎为0,可放心使用,重复的机率比碰鬼的机率还小,在不同的机器上如此,在同一台机器上重复的机率更是几乎不可能
使用C#Guid.NewGuid()生成的GUID长度为36位


在WebService中使用Session示例 ( Archived on 2009-3-19 9:36:53 135 Views )

using System;
using System.ComponentModel;
using System.Configuration;
using System.Data;
using System.Web;
using System.Web.Services;

namespace CSoft.WebService
{
    [WebService(Namespace = "http://www.csstosft.com/")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    [ToolboxItem(false)]
    public class webService_orderCapacity : System.Web.Services.WebService
    {

        /// <summary>
        /// Abouts this instance.
        /// </summary>
        /// <returns></returns>
        [WebMethod]
        public string About()
        {
            return "csoft.orderCapacity.V1.0";
        }

        [WebMethod (EnableSession = true)]
        public string TestLogin(string account,string pwd)
        {
            if (account == "csoft" && pwd == "csoft")
            {
                HttpContext.Current.Session.Clear();
                HttpContext.Current.Session.Add("IsLogin", true);
                return "loginok";
            }
            else
            {
                return "loginerror";
            }
        }

        [WebMethod(EnableSession = true)]
        public bool TestIsLogin()
        {
            if (HttpContext.Current.Session == null || HttpContext.Current.Session["IsLogin"] == null || HttpContext.Current.Session["IsLogin"].ToString().Length < 1)
            {
                return false;
            }

            if (HttpContext.Current.Session.Count > 0 && bool.Parse(HttpContext.Current.Session["IsLogin"].ToString()))
            {
                return true;
            }
            else
            {
                //Jscript.AlertAndRedirect("Please login....", "Login.aspx");
                return false;
            }
        }
    }
}


QR码-快速矩阵二维条码 ( Archived on 2009-3-14 10:36:52 506 Views )

QR码是由日本Denso公司于1994年9月研制的一种矩阵二维码符号,QR码除具有一维条码及其它二维条码所具有的信息容量大、可靠性高、可表示汉字及图象多种文字信息、保密防伪性强等优点外,QR码还具有如下主要特点:

普通的一维条码只能在横向位置表示大约20为的字母或数字信息,无纠错功能,使用时候需要后台数据库的支持,而QR码二维条码是横向纵向都存有信息,可以放入字母、数字、汉字、照片、指纹等大量信息,相当一个可移动的数据库。如果用一维条码与二维条码表示同样的信息,QR二维码占用的空间只是条码1/11的面积。

QR 码 (2D 符号) 在横向和纵向上都包含有信息,而 条码只有一个方向上包含有信息。QR 码能够包含的信息比条码多得多

QR码比其他二维码相比,具有识读速度快、数据密度大、占用空间小的优势。QR码的三个角上有三个寻象图形,使用CCD识读设备来探测码的位置、大小、倾斜角度、并加以解码,实现360读高速识读。每秒可以识读30个含有100个字符QR码。QR码容量密度大,可以放入1817个汉字、7089个数字、 4200个英文字母。QR码用数据压缩方式表示汉字,仅用13bit即可表示一个汉字,比其他二维条码表示汉字的效率提高了20%。QR具有4个等级的纠错功能,即使破损或破损也能够正确识读。QR码抗弯曲的性能强,通过QR码中的每隔一定的间隔配置有校正图形,从码的外形来求得推测校正图形中心点与实际校正图形中心点的误差来修正各个模快的中心距离,即使将QR码贴在弯曲的物品上也能够快速识读。QR码可以分割成16个QR码,可以一次性识读数个分割码,适应于印刷面积有限及细长空间印刷的需要。此外微型QR码可以在1厘米的空间内放入35个数字或9个汉字或21个英文字母,适合对小型电路板对ID号码进行采集的需要。

多到 7,089 数字可以被编码(下图为300 个字符或数字被编进这样大小的QR码里面)

同样的数据只有条码的十分之一大小

超高速识读:
从QR Code码的英文名称Quick Response Code可以看出,超高速识读特点是QR Code码区别于四一七条码、Data Matrix等二维码的主要特性。由于在用CCD识读QR Code码时,整个QR Code码符号中信息的读取是通过QR Code码符号的位置探测图形,用硬件来实现,因此,信息识读过程所需时间很短,它具有超高速识读特点。用CCD二维条码识读设备,每秒可识读30个含有 100个字符的QR Code码符号;对于含有相同数据信息的四一七条码符号,每秒仅能识读3个符号;对于Data Martix矩阵码,每秒仅能识读2~3个符号。QR Code码的超高速识读特性是它能够广泛应用于工业自动化生产线管理等领域。

全方位识读:
QR Code码具有全方位(360°)识读特点,这是QR Code码优于行排式二维条码如四一七条码的另一主要特点,由于四一七条码是将一维条码符号在行排高度上的截短来实现的,因此,它很难实现全方位识读,其识读方位角仅为±10°.

能够有效地表示中国汉字、日本汉字:
由于QR Code码用特定的数据压缩模式表示中国汉字和日本汉字,它仅用13bit可表示一个汉字,而四一七条码、Data Martix等二维码没有特定的汉字表示模式,因此仅用字节表示模式来表示汉字,在用字节模式表示汉字时,需用16bit(二个字节)表示一个汉字,因此 QR Code码比其它的二维条码表示汉字的效率提高了20%。

编码字符集:
1、数字型数据(数字0~9);
2、字母数字型数据(数字0~9;大写字母A~Z;9个其他字符:space ,$, %, *, +, -, ., /, :);
3、8位字节型数据;
4、日本汉字字符;
5、中国汉字字符(GB 2312对应的汉字和非汉字字符)。

QR码符号的基本特性

符号规格 21×21模块(版本1)-177×177 模块(版本40) (每一规格:每边增加4个模块)

数据类型与容量(指最大规格符号版本40-L级)
· 数字数据 :7,089个字符
· 字母数据 :4,296个字符
· 8位字节数据 :2,953个字符
· 中国汉字、日本汉字数据 :1,817个字符

数据表示方法 深色模块表示二进制“1”,浅色模块表示二进制“0”。


纠错能力
· L级:约可纠错7%的数据码字
· M级:约可纠错15%的数据码字
· Q级:约可纠错25%的数据码字
· H级:约可纠错30%的数据码字

结构链接(可选) 可用1-16个QR Code码符号表示一组信息

掩模(固有) 可以使符号中深色与浅色模块的比例接近1:1,使因相邻模块的排列造成译码困难的可能性降为最小。

扩充解释(可选) 这种方式使符号可以表示缺省字符集以外的数据(如阿拉伯字符、古斯拉夫字符、希腊字母等),以及其他解释(如用一定的压缩方式表示的数据)或者对行业特点的需要进行编码。 独立定位功能

QR码QR Code可高效地表示汉字,相同内容,其尺寸小于相同密度的PDF417条码。目前市场上的大部分条码打印机都支持QR code条码,其专有的汉字模式更加适合我国应用。因此,QR码在我国具有良好的应用前景。


SQLite的查询优化 ( Archived on 2009-3-12 17:10:49 279 Views )

SQLite是个典型的嵌入式DBMS,它有很多优点,它是轻量级的,在编译之后很小,其中一个原因就是在查询优化方面比较简单,它只是运用索引机制来进行优化的,经过对SQLite的查询优化的分析以及对源代码的研究,我将SQLite的查询优总结如下:

一、影响查询性能的因素:

1. 对表中行的检索数目,越小越好

2. 排序与否。

3. 是否要对一个索引。

4. 查询语句的形式

二、几个查询优化的转换

1. 对于单个表的单个列而言,如果都有形如T.C=expr这样的子句,并且都是用OR操作符连接起来,形如: x = expr1 OR expr2 = x OR x = expr3 此时由于对于OR,在SQLite中不能利用索引来优化,所以可以将它转换成带有IN操作符的子句:x IN(expr1,expr2,expr3)这样就可以用索引进行优化,效果很明显,但是如果在都没有索引的情况下OR语句执行效率会稍优于IN语句的效率。

2. 如果一个子句的操作符是BETWEEN,在SQLite中同样不能用索引进行优化,所以也要进行相应的等价转换: 如:a BETWEEN b AND c可以转换成:(a BETWEEN b AND c) AND (a>=b) AND (a<=c)。 在上面这个子句中, (a>=b) AND (a<=c)将被设为dynamic且是(a BETWEEN b AND c)的子句,那么如果BETWEEN语句已经编码,那么子句就忽略不计,如果存在可利用的index使得子句已经满足条件,那么父句则被忽略。

3. 如果一个单元的操作符是LIKE,那么将做下面的转换:x LIKE ‘abc%’,转换成:x>=‘abc’ AND x<‘abd’。因为在SQLite中的LIKE是不能用索引进行优化的,所以如果存在索引的话,则转换后和不转换相差很远,因为对LIKE不起作用,但如果不存在索引,那么LIKE在效率方面也还是比不上转换后的效率的。

三、 几种查询语句的处理(复合查询)
1.查询语句为:<SelectA> <operator> <selectB> ORDER BY <orderbylist> ORDER BY
     执行方法: is one of UNION ALL, UNION, EXCEPT, or INTERSECT. 这个语句的执行过程是先将selectA和selectB执行并且排序,再对两个结果扫描处理,对上面四种操作是不同的,将执行过程分成七个子过程:

   outA: 将selectA的结果的一行放到最终结果集中

   outB: 将selectA的结果的一行放到最终结果集中(只有UNION操作和UNION ALL操作,其它操作都不放入最终结果集中)

    AltB: 当selectA的当前记录小于selectB的当前记录

    AeqB: 当selectA的当前记录等于selectB的当前记录

    AgtB: 当selectA的当前记录大于selectB的当前记录

    EofA: 当selectA的结果遍历完

    EofB: 当selectB的结果遍历完

         下面就是四种操作的执行过程:


 执行顺序
 UNION ALL
 UNION
 EXCEPT
 INTERSECT
 
AltB:
 outA, nextA
 outA, nextA
 outA,nextA
 nextA
 
AeqB:
 outA, nextA
 nextA
 nextA
 outA, nextA
 
AgtB:
 outB, nextB
 outB, nextB
 nextB
 nextB
 
EofA:
 outB, nextB
 outB, nextB
 halt
 halt
 
EofB:
 outA, nextA
 outA, nextA
 outA,nextA
 halt
 

     2. 如果可能的话,可以把一个用到GROUP BY查询的语句转换成DISTINCT语句来查询,因为GROUP BY有时候可能会用到index,而对于DISTINCT都不会用到索引的 。

四、子查询扁平化

     例子:SELECT a FROM (SELECT x+y AS a FROM t1 WHERE z<100) WHERE a>5

     对这个SQL语句的执行一般默认的方法就是先执行内查询,把结果放到一个临时表中,再对这个表进行外部查询,这就要对数据处理两次,另外这个临时表没有索引,所以对外部查询就不能进行优化了,如果对上面的SQL进行处理后可以得到如下SQL语句:SELECT x+y AS a FROM t1 WHERE z<100 AND a>5,这个结果显然和上面的一样,但此时只需要对

数据进行查询一次就够了,另外如果在表t1上有索引的话就避免了遍历整个表。

运用flatten方法优化SQL的条件:

1.子查询和外查询没有都用集函数

2.子查询没有用集函数或者外查询不是个表的连接

3.子查询不是一个左外连接的右操作数

4.子查询没有用DISTINCT或者外查询不是个表的连接

5.子查询没有用DISTINCT或者外查询没有用集函数

6.子查询没有用集函数或者外查询没有用关键字DISTINCT

7.子查询有一个FROM语句

8.子查询没有用LIMIT或者外查询不是表的连接

9.子查询没有用LIMIT或者外查询没有用集函数

10.子查询没有用集函数或者外查询没用LIMIT

11.子查询和外查询不是同时是ORDER BY子句

12.子查询和外查询没有都用LIMIT

13.子查询没有用OFFSET

14.外查询不是一个复合查询的一部分或者子查询没有同时用关键字ORDER BY和LIMIT

15.外查询没有用集函数子查询不包含ORDER BY

16.复合子查询的扁平化:子查询不是一个复合查询,或者他是一个UNION ALL复合查询,但他是都由若干个非集函数的查询构成,他的父查询不是一个复合查询的子查询,也没有用集函数或者是DISTINCT查询,并且在FROM语句中没有其它的表或者子查询,父查询和子查询可能会包含WHERE语句,这些都会受到上面11、12、13条件的限制。

例:   SELECT a+1 FROM (

              SELECT x FROM tab

              UNION ALL

              SELECT y FROM tab

               UNION ALL

               SELECT abs(z*2) FROM tab2

           ) WHERE a!=5 ORDER BY 1

转换为:

        SELECT x+1 FROM tab WHERE x+1!=5

           UNION ALL

           SELECT y+1 FROM tab WHERE y+1!=5

           UNION ALL

           SELECT abs(z*2)+1 FROM tab2 WHERE abs(z*2)+1!=5

           ORDER BY 1

17.如果子查询是一个复合查询,那么父查询的所有的ORDER BY语句必须是对子查询的列的简单引用

18.子查询没有用LIMIT或者外查询不具有WHERE语句

子查询扁平化是由专门一个函数实现的,函数为:

static int flattenSubquery(

 Parse *pParse,       /* Parsing context */

 Select *p,           /* The parent or outer SELECT statement */

 int iFrom,           /* Index in p->pSrc->a[] of the inner subquery */

 int isAgg,           /* True if outer SELECT uses aggregate functions */

 int subqueryIsAgg    /* True if the subquery uses aggregate functions */

)

       它是在Select.c文件中实现的。显然对于一个比较复杂的查询,如果满足上面的条件时对这个查询语句进行扁平化处理后就可以实现对查询的优化。如果正好存在索引的话效果会更好!

 

五、连接查询

       在返回查询结果之前,相关表的每行必须都已经连接起来,在SQLite中,这是用嵌套循环实现的,在早期版本中,最左边的是最外层循环,最右边的是最内层循环,连接两个或者更多的表时,如果有索引则放到内层循环中,也就是放到FROM最后面,因为对于前面选中的每行,找后面与之对应的行时,如果有索引则会很快,如果没有则要遍历整个表,这样效率就很低,但在新版本中,这个优化已经实现。

       优化的方法如下:

       对要查询的每个表,统计这个表上的索引信息,首先将代价赋值为SQLITE_BIG_DBL(一个系统已经定义的常量):

1)    如果没有索引,则找有没有在这个表上对rowid的查询条件:

1.如果有Rowid=EXPR,如果有的话则返回对这个表代价估计,代价计为零,查询得到的记录数为1,并完成对这个表的代价估计,

2.如果没有Rowid=EXPR 但有rowid IN (...),而IN是一个列表,那么记录返回记录数为IN列表中元素的个数,估计代价为NlogN,

3.如果IN不是一个列表而是一个子查询结果,那么由于具体这个子查询不能确定,所以只能估计一个值,返回记录数为100,代价为200。

4.如果对rowid是范围的查询,那么就估计所有符合条件的记录是总记录的三分之一,总记录估计为1000000,并且估计代价也为记录数。

5.如果这个查询还要求排序,则再另外加上排序的代价NlogN

6.如果此时得到的代价小于总代价,那么就更新总代价,否则不更新。

2)    如果WHERE子句中存在OR操作符,那么要把这些OR连接的所有子句分开再进行分析。

1. 如果有子句是由AND连接符构成,那么再把由AND连接的子句再分别分析。

2. 如果连接的子句的形式是X<op><expr>,那么就再分析这个子句。

3. 接下来就是把整个对OR操作的总代价计算出来。

4. 如果这个查询要求排序,则再在上面总代价上再乘上排序代价NlogN

5. 如果此时得到的代价小于总代价,那么就更新总代价,否则不更新。

3)    如果有索引,则统计每个表的索引信息,对于每个索引:

1. 先找到这个索引对应的列号,再找到对应的能用到(操作符必须为=或者是IN(…))这个索引的WHERE子句,如果没有找到,则退出对每个索引的循环,如果找到,则判断这个子句的操作符是什么,如果是=,那么没有附加的代价,如果是IN(sub-select),那么估计它附加代价inMultiplier为25,如果是IN(list),那么附加代价就是N(N为list的列数)。

2. 再计算总的代价和总的查询结果记录数和代价。

3. nRow = pProbe->aiRowEst[i] * inMultiplier;/*计算行数*/

4. cost = nRow * estLog(inMultiplier);/*统计代价*/

5. 如果找不到操作符为=或者是IN(…)的子句,而是范围的查询,那么同样只好估计查询结果记录数为nRow/3,估计代价为cost/3。

6. 同样,如果此查询要求排序的话,再在上面的总代价上加上NlogN

7. 如果此时得到的代价小于总代价,那么就更新总代价,否则不更新。

4)    通过上面的优化过程,可以得到对一个表查询的总代价(就是上面各个代价的总和),再对第二个表进行同样的操作,这样如此直到把FROM子句中所有的表都计算出各自的代价,最后取最小的,这将作为嵌套循环的最内层,依次可以得到整个嵌套循环的嵌套顺序,此时正是最优的,达到了优化的目的。

5)    所以循环的嵌套顺序不一定是与FROM子句中的顺序一致,因为在执行过程中会用索引优化来重新排列顺序。

六、索引

   在SQLite中,有以下几种索引:

1)    单列索引

2)    多列索引

3)    唯一性索引

4)    对于声明为:INTEGER PRIMARY KEY的主键来说,这列会按默认方式排序,所以虽然在数据字典中没有对它生成索引,但它的功能就像个索引。所以如果在这个主键上在单独建立索引的话,这样既浪费空间也没有任何好处。

运用索引的注意事项:

1)    对于一个很小的表来说没必要建立索引

2)    在一个表上如果经常做的是插入更新操作,那么就要节制使用索引

3)    也不要在一个表上建立太多的索引,如果建立太多的话那么在查询的时候SQLite可能不会选择最好的来执行查询,一个解决办法就是建立聚蔟索引

索引的运用时机:

1)    操作符:=、>、<、IN等

2)    操作符BETWEEN、LIKE、OR不能用索引,

       如BETWEEN:SELECT * FROM mytable WHERE myfield BETWEEN 10 and 20;

       这时就应该将其转换成:

       SELECT * FROM mytable WHERE myfield >= 10 AND myfield <= 20;

       此时如果在myfield上有索引的话就可以用了,大大提高速度

 

       再如LIKE:SELECT * FROM mytable WHERE myfield LIKE 'sql%';

       此时应该将它转换成:

       SELECT * FROM mytable WHERE myfield >= 'sql' AND myfield < 'sqm';

       此时如果在myfield上有索引的话就可以用了,大大提高速度

       再如OR:SELECT * FROM mytable WHERE myfield = 'abc' OR myfield = 'xyz';

       此时应该将它转换成:

       SELECT * FROM mytable WHERE myfield IN ('abc', 'xyz');

       此时如果在myfield上有索引的话就可以用了,大大提高速度

3)    有些时候索引都是不能用的,这时就应该遍历全表(程序演示)

       SELECT * FROM mytable WHERE myfield % 2 = 1;

       SELECT * FROM mytable WHERE substr(myfield, 0, 1) = 'w';

       SELECT * FROM mytable WHERE length(myfield) < 5;


记录日志到当前网站目录 ( Archived on 2009-2-13 14:24:59 116 Views )

using System;
using System.IO;
using System.Web;

public class Utility
{
    public static void LogError(string message)
    {
        message = string.Format("--------{0}------\r\n{1}", DateTime.Now, message);
        LogMsg("ErrorLog.txt", message);
    }

    /// <summary>
    /// Logs the MSG.
    /// </summary>
    /// <param name="file">The file.</param>
    /// <param name="message">The message.</param>
    private static void LogMsg(string file, string message)
    {
        StreamWriter _sw = null;

        try
        {
            //Instantiate an appendable streamwriter that writes to a file called ErrorLog.txt
            string filePath = HttpContext.Current.Server.MapPath("~") + file;
            _sw = new StreamWriter(filePath, true, System.Text.Encoding.UTF8);
            //Write a row of data containing the time, the error message, and the stack trace
            _sw.WriteLine(message);
        }
        finally
        {
            //Ensure the streamwriter gets closed
            if (_sw != null)
            {
                _sw.Close();
                _sw = null;
            }
        }
    }
}


打印DataTable表数据 ( Archived on 2008-9-25 11:35:20 131 Views )

public string FormatDataTableData(DataTable dt)
{
    StringBuilder sb = new StringBuilder();
    sb.AppendLine("-------------Table Data----------------");
    string columns = string.Empty;
    foreach (DataColumn dl in dt.Columns)
    {
        columns += string.Format("{0}({1}) | ", dl.ColumnName, dl.DataType);
    }
    sb.AppendLine(columns); int j = 1;
    foreach (DataRow dr in dt.Rows)
    {
        for (int i = 0; i < dt.Columns.Count; i++)
        {
            if (i == 0)
            {
                sb.Append(string.Format("{0} -> | {1} | ", j, dr[i]));
            }
            else if
                (i == dt.Columns.Count - 1)
            {
                sb.AppendLine(string.Format("{0} | ", dr[i]));
            }
            else
            {
                sb.Append(string.Format("{0} | ", dr[i]));
            }
        }
        j++;
    }
    return sb.ToString();
}


插入图片到SQLite数据库 ( Archived on 2008-9-24 17:26:24 163 Views )

test_webService.Service service = new test_webService.Service();
DataSet ds = service.GetEmployees();

string connstring = string.Format("Data Source={0};Version=3;", @"D:\cs\lj\dbbb.db");

//CREATE TABLE [Test] (
//[id] INTEGER  PRIMARY KEY AUTOINCREMENT NOT NULL,
//[image] Boob  NULL
//)

string insertSql = "Insert Into [Test] ([image]) Values(@image)";
using (SQLiteConnection conn = new SQLiteConnection(connstring))
{
    // 连接数据库
    conn.Open();
    SQLiteCommand cmd = conn.CreateCommand();
    cmd.Connection = conn;

    //DbTransaction trans = conn.BeginTransaction();
    SQLiteTransaction trans = conn.BeginTransaction();
    try
    {
        //保存數據
        cmd.CommandText = insertSql;
        // 添加参数
        //cmd.Parameters.Add(cmd.CreateParameter());
        cmd.Parameters.Add("image", DbType.Binary);

        DataTable dt = ds.Tables[0];
        foreach (DataRow dr in dt.Rows)
        {
            cmd.Parameters[0].Value = (byte[])(dr["Photo"]);
            cmd.ExecuteNonQuery();
        }
        // <-------------------
        trans.Commit();
    }
    catch (Exception ex)
    {
        trans.Rollback();
        throw;
    }
}


Page 1 In 4 |   1   2   3   4  
Remark:无边落日萧萧下 不尽长江滚滚来
Contact Us For: CSST软件 | About Us:关于我们 | RSS: 手机开发
Powered By CSST Soft Studio CopyRight 2008 - 2010