[转载]数据库 的版本为 661,无法打开。此服务器支持 655 版及更低版本。不支持降级路径。 - 虾壳的世界 - 博客频道 - CSDN.NET

mikel阅读(1022)

[转载]数据库 的版本为 661,无法打开。此服务器支持 655 版及更低版本。不支持降级路径。 – 虾壳的世界 – 博客频道 – CSDN.NET.

喜欢vs2010的界面,于是安装了WIN7旗舰版,全新的系统,然后安装vs2010,结果带来一连串的麻烦。

 

SQL2008 sp1 express与SQL 2008 R2(RTM)

 

vs2010带的是sql2008 sp1 express,查看sql2008 sp1的版本号为10.0.2531.0,如下:

use master

select @@VERSION

Microsoft SQL Server 2008 (SP1) – 10.0.2531.0 (Intel X86)   Mar 29 2009 10:27:29   Copyright (c) 1988-2008

Microsoft Corporation  Express Edition on Windows NT 6.1 <X86> (Build 7600: )

 

我的程序在vs2010上跑了一下后,把程序带回家后出现了问题,家里是XP+vs2008+sql2005 express,结果出现“数据库版本为655 无法打开,此服务器支持612版本及更低版本,不支持降级路径”的故障。

 

查询后得知,是数据库被自动升级到655版本也就是sql2008 sp1了。

 

家里机器有些慢,跑不动WIN7,也不想升级到vs2010,所以只好保持vs2008,升级sql2005 express到sql2008 express。

在升级的时候看到有sql2008 r2放出,于是直接把家里的sql2005升级到sql2010 R2 RTM,版本号为:

Microsoft SQL Server 2008 R2 (RTM) – 10.50.1600.1 (Intel X86)

升级过程要安装vs2008 sp1,花了些时间,终于把sql2008 R2(RTM) Express+SQL Server Management Studio Express搞定了。

 

结果,把程序从家里带到单位后又出现了新问题:“数据库 的版本为 661,无法打开。此服务器支持 655 版及更低版本。不支持降级路径。”

 

我晕,查询后得知,661是sql2008 R2的版本号,于是把单位的sql2008 sp1 express升级到sql2008 r2 express,版本号如下:

Microsoft SQL Server 2008 R2 (RTM) – 10.50.1600.1 (Intel X86)   Apr  2 2010 15:53:02   Copyright (c) Microsoft

Corporation  Express Edition with Advanced Services on Windows NT 6.1 <X86> (Build 7600: )

 

问题解决了,是不是该考虑把服务器里的sql2005 server升级到sql2008 R2呢……

[转载]ecshop推荐分成实现原理(1)_ecshop二次开发_ecshop模板_ecmall二次开发_模板_善仁网

mikel阅读(1060)

[转载]ecshop推荐分成实现原理(1)_ecshop二次开发_ecshop模板_ecmall二次开发_模板_善仁网.

最近在和朋友一起研究一个项目,项目的主题就是ECSHOP的分成,ECSHOP的推荐分成,具有递归性,如果A他推荐了B,B推荐了C。那么C购买了商品之后,B,A都能得到一定的推荐分成金额。

1:ECSHOP分成处理步骤

后台->推荐管理->分成管理

2:ECSHOP分成原理

在ecshop的users表中,parent_id就是用来处理EC推荐分成中推荐人的会员ID的。通过分成等级。可以循环出EC某会员下所有的推荐人.

$num = count($affiliate['item']);//推荐等级

for ($i=0; $i &lt; $num; $i++) { $affiliate['item'][$i]['level_point'] = (float)$affiliate['item'][$i]['level_point']; $affiliate['item'][$i]['level_money'] = (float)$affiliate['item'][$i]['level_money']; if ($affiliate['item'][$i]['level_point']) { $affiliate['item'][$i]['level_point'] /= 100; } if ($affiliate['item'][$i]['level_money']) { $affiliate['item'][$i]['level_money'] /= 100; } $setmoney = round($money * $affiliate['item'][$i]['level_money'], 2); $setpoint = round($point * $affiliate['item'][$i]['level_point'], 0); $row = $db-&gt;getRow("SELECT o.parent_id as user_id,u.user_name FROM " . $GLOBALS['ecs']-&gt;table('users') . " o" .
" LEFT JOIN" . $GLOBALS['ecs']-&gt;table('users') . " u ON o.parent_id = u.user_id".
" WHERE o.user_id = '$row[user_id]'"
);
$up_uid = $row['user_id'];
if (empty($up_uid) || empty($row['user_name']))
{
break;
}
else
{
$info = sprintf($_LANG['separate_info'], $order_sn, $up_uid, $row['user_name'], $setmoney, $setpoint);
log_account_change($up_uid, $setmoney, 0, 0, $setpoint, $info);
write_affiliate_log($oid, $up_uid, $row['user_name'], $setmoney, $setpoint, $separate_by);
}
}

而这里的”SELECT o.parent_id as user_id,u.user_name FROM ” . $GLOBALS[‘ecs’]->table(‘users’) . ” o” . ” LEFT JOIN” . $GLOBALS[‘ecs’]->table(‘users’) . ” u ON o.parent_id = u.user_id”.” WHERE o.user_id = ‘$row[user_id]'”;就是用来寻找上一级推荐人的帐户信息。通过循环,而进行分成。然后写入对应的日志。

[转载]c# sqlite中的like 模糊查询参数 - 随记 - 博客频道 - CSDN.NET

mikel阅读(1164)

[转载]c# sqlite中的like 模糊查询参数 – 随记 – 博客频道 – CSDN.NET.

在操作SQL 与 ACCESS数据库,使用LIKE传递参数进行模糊查询时,可以使用这样的写法:

SQL:

string sql = “Select Count(ID) As rcount From tbArticle WHERE  classID IN(” + ids + “) AND  Title LIKE ‘%’+@Title+’%'”;

 

参数直接这样传递:

 

 

SqlParameter[] sps = new SqlParameter[1];

sps[0] = SQLDB.CreateParameter(“@Title”, SqlDbType.VarChar, title, 50, ParameterDirection.Input);

 

其中title是一个变量。

 

在上边两个数据库中,这样做是可以查询出内容的,不过在SQLITE中却不可以,经多次尝试,发现换种方式也可以实现这样的模糊参数传递

SQL:

 

string sql = “Select Count(ID) As rcount From tbArticle WHERE  classID IN(” + ids + “) AND  Title LIKE @Title “;

参数:

 

 

SQLiteParameter[] sps = new SQLiteParameter[1];

sps[0] = SQLite.CreateParameter(“@Title”, DbType.String, “%” + title + “%”, 50, ParameterDirection.Input);

 

就是在变量里直接模拟成 ‘%test%’ ,把这个传递进去,就可以查出结果了

 

注意:SQLite的语法和SQL Server的like不一样,不用再%号前加 ‘ 号

[转载]QQ自动发日志分析 - 水木 - 博客园

mikel阅读(1314)

[转载]QQ自动发日志分析 – 水木 – 博客园.

首先列举比较重要的问题在前面。

1.关于QQ密码码的加密:

2.关于登陆是否需要验证码的校验。

3. 发日志的时候g_tk参数的算法。

 

分析过程。

1.登陆的时候,需要先判断是否需要使用验证码。

string url = String.Format(“http://ptlogin2.qq.com/check?uin={0}&appid={1}&r=0.{2}”, TxtUser.Text.Trim(), “2001601”, Bases.GetGuid(Bases.RandEnum.Numeric, 16));

进行Get请示,如果返回值 是1开头结果的需要验证码,如果是0开头的,是不需要验证码的。

 

2.有验证码的情况 ,获得验证码图片地址,同时要记录验证码的cookie,在提交的时候需要用到。

string strImageUrl = String.Format(“http://captcha.qq.com/getimage?&uin={0}&vc_type={1}&aid={2}&0.{3}”,TxtUser.Text.Trim(),vcCode, “2001601”, Bases.GetGuid(Bases.RandEnum.Numeric, 16));

 

3.进行登陆,

登陆地址:http://ptlogin2.qq.com/login?u={0}&p={1}&verifycode={2}&aid=1006102&u1=http%3A%2F%2Fid.qq.com%2Findex.html&h=1&ptredirect=1&ptlang=2052&from_ui=1&dumy=&fp=loginerroralert

注:u:你的QQ号, p:加密过的QQ密码,verifycode:验证码

 

3.1 :QQ密码的加密代码:C#版的。

public static class qqPwdEncrypt
{
///
/// 计算网页上QQ登录时密码加密后的结果
///

///QQ密码 ///验证码 ///
public static String Encrypt(string pwd, string verifyCode)
{
return (md5(md5_3(pwd).ToUpper() + verifyCode.ToUpper())).ToUpper();
}
///
/// 计算字符串的三次MD5
///

//////
private static String md5_3(String s)
{
System.Security.Cryptography.MD5 md5 = new System.Security.Cryptography.MD5CryptoServiceProvider();
byte[] bytes = System.Text.Encoding.UTF8.GetBytes(s);

bytes = md5.ComputeHash(bytes);
bytes = md5.ComputeHash(bytes);
bytes = md5.ComputeHash(bytes);

md5.Clear();

string ret = "";
for (int i = 0; i &lt; bytes.Length; i++)
{
ret += Convert.ToString(bytes[i], 16).PadLeft(2, '0');
}

return ret.PadLeft(32, '0');
}
///
/// 计算字符串的一次MD5
///

//////
private static String md5(String s)
{
System.Security.Cryptography.MD5 md5 = new System.Security.Cryptography.MD5CryptoServiceProvider();
byte[] bytes = System.Text.Encoding.UTF8.GetBytes(s);

bytes = md5.ComputeHash(bytes);

md5.Clear();

string ret = "";
for (int i = 0; i &lt; bytes.Length; i++)
{
ret += Convert.ToString(bytes[i], 16).PadLeft(2, '0');
}

return ret.PadLeft(32, '0');
}
}

3.2 关于js版的加密方法,请直接查看源代码,从QQ的页面上读取。
4.登陆成功后,开始发日志,

发日志地址:http://b.qzone.qq.com/cgi-bin/blognew/blog_add?g_tk=” + gtkValue

1:g_tk的参数如何取:

gtkValue的值是也是经过QQ加密过的

加密原理:对于登陆成功后,会在登陆成功的cookie值中有一个skey的cookie,取该cookie的值,进行循环取单字符的二进制并取左值。

找了一个获得gtkValue的js方法:【期待谁可以翻译成C#版的,因为js的方法,在C#的调用不太方便,还要引用一个dll的控件才可以。】

js方法提供如下:

function getGTK(str){
var hash = 5381;
for(var i = 0, len = str.length; i &lt; len; ++i)
{
hash += (hash &lt;&lt; 5) + str.charAt(i).charCodeAt();
}
return hash &amp; 0x7fffffff;
}

通过调用些方法后,就可以获得发日志的具体地址了、

5.进行post提供要发的日志内容【注:登陆的时候,是get请求,非post请求】

前面都很顺利,到这里把我卡住了,不知道为什么提交后,没有数据返回,相对应也就是没有发布成功,也怪调试不细心。

后来发现提交的时候,会catch到 “关于“服务器提交了协议冲突. Section=ResponseStatusLine”

经常查询问题根源:【网上找的,嘿嘿】

The server committed a protocol violation. Section=ResponseHeader Detail=CR must be followed by LF 微软没有容忍不符合RFC 822中的httpHeader必须以CRLF结束的规定的服务器响应。
通过修改配置文件解决:在app.config(WinForm)或web.config(Web)文件里修改。
WinForm下的app.config默认不存在,手动在Debug文件夹所在的同级目录下新建一个XML配置文件,内容为:

<!--?xml version="1.0" encoding="utf-8" ?-->







编译以后会在Debug下面自动创建一个 程序名.exe.config 的配置文件

 

 

加入以上代码就OK了。

 

本文以记录分析过程,并留以后查看备忘 ,如果对大家无用,请飘了。哈

 

 

 

关于程序文章,或收藏一般同步发到javaeye,cnblogs,

 

关于其它文章,一般同步发到sina,QQ空间。

 

 

 

发成功了。哈哈。

 

image

 

作者:水木

出处:http://www.hitidc.com/

[转载]SQlite 数据库遇到的问题 “该字符串未被识别为有效的 DateTime - 无恨星晨 - 博客园

mikel阅读(1324)

[转载]SQlite 数据库遇到的问题 “该字符串未被识别为有效的 DateTime – 无恨星晨 – 博客园.

找了很久都没有找到合理的解释,幸好找到一篇文章,解答了这个问题,特收藏于此,以备参考。

http://www.xueit.com/html/2009-02/21_644_00.html

最近使用ASP.NET+SQLite数据库开发一个网站程序,结果在日期处理上出现了很头痛的问题,看下图

 

说明: 执行当前 Web 请求期间,出现未处理的异常。请检查堆栈跟踪信息,以了解有关该错误以及代码中导致错误的出处的详细信息。
异常详细信息: System.FormatException: 该字符串未被识别为有效的 DateTime。

 

解决方案:

在日期保存到SQLite数据库时转换一个类型,比如:string _now = System.DateTime.Now.ToString(“s”);

也就是说在.ToString()方法中加一个s,即可解决日期读取错误的问题。

简单代码示例:

string _indate = Request[“indate”]; //输入的日期如:2009-2-21
DateTime _inTime = Convert.ToDateTime(_indate);

//如下是保存数据SQL语句

insert into 表(indate) values(‘“ + _inTime.ToString(“s”) + “‘);   //这里转换

 

之后日期保存在Sqlite数据库的内容为:

SQlite 数据库遇到的问题 “该字符串未被识别为有效的 DateTime - GB2013 - GB2013的博客

 

奇怪为什么日期成为:1899-12-30了,放心这是正常,看下面我读取日期出来的内容是什么?如下:

SQlite 数据库遇到的问题 “该字符串未被识别为有效的 DateTime - GB2013 - GB2013的博客

 

看,是正确的日期。

 

因为iso 8601的描述:(http://msdn.microsoft.com/zh-cn/library/ms187819.aspx)

给出了字符串示例:
* 2004-05-23T14:25:10
* 2004-05-23T14:25:10.487

所以Sqlite保存的日期要转为iso 8601标准字符串格式

使用 日期.ToString(“s”);这种方法转换成 iso 8601标准字符串格式了。

1块钱没花赚了3200

mikel阅读(1083)

psb
先看图,算算账!
月销量1345,也就是收入了。

真的如表面这么点儿吗?那他倒底卖的是什么?买了看看,结果人家给个网盘地址,自已下载,很牛B地来一句,给好评,再免费给赚钱项目。正常人都不会拒绝吧,给了好评又得到一个网盘地址,打开教程见到有8个项目介绍,还算不错说明哪个好操作,每个项目一个链接,看到链接我乐了!

为什么我乐了?那都是“带尾巴”的链接,行家看到这儿都懂了,

什么是“带尾巴的”?就是推广裢接!

通过这些你注册了就给他1一5元不等的推广佣金,这还没完,你在这个网站以后赚多少钱,他都得30%的佣金!

好了,算下他这一个月的真实收入吧!

1345十1345(推广注册佣金)十1345人份赚钱的和×30% 预计3121 以上,这还是1345人每人赚1元的情况

真想对这家店主说:你这么推广,不怕被封号吗?
人家会一甩头回一句:信息不要钱啊?!

思路比方法重要,这种推广方法,我们可以借鉴,模仿也可以人家能行,你也能行的。

说到万能的淘宝,你想做什么项目,建议不是百度一下,而是淘宝一下,你能想到的淘宝上可能已经有了,没想到的你也会有所发现,然后就要看你自己如何把握了,是照搬模仿,还是领会精神了,上面的例子是我再推广过程中分析的一个案例,其实操作的项目多了,会产生很多模式,总结起来后,会发现后面推广其他项目就会轻松多了,套用或者改良下即可。

互联网需要不断的学习总结才能生存,不要说自己靠几个推广方法就能过得很好,那你只能被后浪拍死在沙滩上了。

好了,废话这么多,总之不要跟风儿,要有自己的想法。

更多信息加我QQ 3379152 关注微信公众号:weikebao

qrcode_for_gh_e8f970702774_430

[转载]BackgroundWorker使用实例教程 - moss_tan_jun - 博客园

mikel阅读(998)

[转载]BackgroundWorker – moss_tan_jun – 博客园.

C# BackgroundWorker 控件的几个实例(C# backgroundworker使用方法):

在 WinForms 中,有时要执行耗时的操作,在该操作未完成之前操作用户界面,会导致用户界面停止响应。
解决的方法就是新开一个线程,把耗时的操作放到线程中执行,这样就可以在用户界面上进行其它操作。
新建线程可以用 Thread 类,可以实现多线程同时操作,简单的可以通过 BackgroundWorker 类实现。

用 BackgroundWorker 类执行耗时的操作
BackgroundWorker 类在 System.ComponentModel 命名空间下。
VS 的工具箱时有一个 BackgroundWorker 组件,就是这个类。


常用方法

1.RunWorkerAsync
开始执行后台操作。引发 DoWork 事件

2.CancelAsync
请求取消挂起的后台操作。
注意:这个方法是将 CancellationPending 属性设置为 true,并不会终止后台操作。在后台操作中要检查 CancellationPending 属性,来决定是否要继续执行耗时的操作。

3.ReportProgress
引发 ProgressChanged 事件。

常用属性
1.CancellationPending
指示应用程序是否已请求取消后台操作。
只读属性,默认为 false,当执行了 CancelAsync 方法后,值为 true。

2.WorkerSupportsCancellation
指示是否支持异步取消。要执行 CancelAsync 方法,需要先设置该属性为 true。

3.WorkerReportsProgress
指示是否能报告进度。要执行 ReportProgress 方法,需要先设置该属性为 true。

 

常用事件
1.DoWork
调用 RunWorkerAsync 方法时发生。

2.RunWorkerCompleted
后台操作已完成、被取消或引发异常时发生。

3.ProgressChanged
调用 ReportProgress 方法时发生。

在 DoWork 事件处理程序中不操作任何用户界面对象。而应该通过 ProgressChanged 和 RunWorkerCompleted 事件与用户界面进行通信。
如果想在 DoWork 事件处理程序中和用户界面的控件通信,可在用 ReportProgress 方法。
ReportProgress(int percentProgress, object userState),可以传递一个对象。
ProgressChanged 事件可以从参数 ProgressChangedEventArgs 类的 UserState 属性得到这个信息对象。

简单的程序用 BackgroundWorker 比 Thread 方便,Thread 中和用户界面上的控件通信比较麻烦,需要用委托来调用控件的 Invoke 或 BeginInvoke 方法,没有 BackgroundWorker 方便。

============================

一个简单的刷网页流量的小工具代码

1. 从工具栏拖一个BackgroundWorker控件,设置其属性WorkerReportsProgress为true

2. 要让worker开始工作,执行如下代码:
mBackgroundWorker.RunWorkerAsync(arg);
这里有重写,如果不需要传递参数直接mBackgroundWorker.RunWorkerAsync();

3. 编辑DoWork事件代码:
e.Argument为mBackgroundWorker.RunWorkerAsync(arg);对应的参数
之所以使用进度条,肯定是有循环的,在循环中报告进度:
worker.ReportProgress(i * 100 / totalNum, obj );
其中第一个参数是当前进度的百分之多少,obj为你要传递的UserState,如果没有可以不要

4. 编辑ProgressChanged事件代码:
e.ProgressPercentage为进度的百分数,e.UserState为刚才传递过来的object
在这个事件中可以调用ui的进度条和其他控件:
mToolStripProgressBar.Value = e.ProgressPercentage;

5. 编辑RunWorkerCompleted事件代码:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.Threading;

namespace WindowsApplication15
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

private void button1_Click(object sender, EventArgs e)
{
//textBox1.Text里面储存URL
backgroundWorker1.RunWorkerAsync(textBox1.Text);
}

private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker bw = (BackgroundWorker)sender;
string url = e.Argument.ToString();

for (int i = 0; i &lt; 10; i++)
{
//没有取消后台操作
if (!bw.CancellationPending)
{
WebRequest req = WebRequest.Create(url);
WebResponse resp = req.GetResponse();
resp.Close();

Thread.Sleep(1000);
bw.ReportProgress(i * 100 / 10, i);
}
}
}

private void backgroundWorker1_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
progressBar1.Value = e.ProgressPercentage;
label1.Text = e.UserState.ToString();
}

private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
MessageBox.Show("ok!");
}
}
}

工作完成了告诉ui

======================

http://hi.baidu.com/yebihaigsino/blog/item/eeccbb02fdf1228fd43f7c8a.html 更高级的backgroundworker控件实例应用

===================

http://blog.163.com/j_yd168/blog/static/4967972820092114269195/ c# BackGroundWorker 多线程操作的小例子

============ ================这个例子含数据库操作

一、BackGroundWorker工作步骤

1.向窗体中拖入一个BackGroundWorker控件。

2.在某个方法或者事件中,调用BackGroundWorker的RunWorkerAsync()方法。

3.该方法为异步操作,将自动引发BackGroundWorker的DoWork事件。

4.调用ReportProgress方法将引发ProgressChanged事件。

二、一个使用了BackGroundWorker的例子

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Threading;
using System.Data.SqlClient;

//该用例需要一个名为bgwTestDB的Sql Server数据库
//数据库中应包含tbBgwTest表。
//表中有data1、data2两列。
//数据库中还需要一个存储过程,sql语句如下:

namespace winBackgroundWorkerTest
{
public partial class backgroundWorkerTest : Form
{
int count = 30;

public backgroundWorkerTest()
{
InitializeComponent();
}

private void btnAdd_Click(object sender, EventArgs e)
{
//1.调用bgwInsertData的RunWorkerAsync方法,用来引发DoWork事件
bgwInsertData.RunWorkerAsync(count);
}

private void bgwInsertData_DoWork(object sender, DoWorkEventArgs e)
{
BackgroundWorker worker = sender as BackgroundWorker;
//2.在DoWork中调用自定义函数,并将引发DoWork事件的sender传递出去
insertData(worker);
}

private void bgwInsertData_ProgressChanged(object sender, ProgressChangedEventArgs e)
{
progressBar1.Value = e.ProgressPercentage;
}

//自定义函数 insertData()
private void insertData(BackgroundWorker worker)
{
SqlConnection conn = new SqlConnection(@"Data Source=.\sqlexpress;Initial Catalog=bgwTestDB;Integrated Security=True");

SqlCommand cmd = new SqlCommand("insertOneData", conn);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add("data1", SqlDbType.NChar, 10);
cmd.Parameters.Add("data2", SqlDbType.Int);

for (int i = 0; i &lt; count; i++)
{
try
{
conn.Open();
cmd.Parameters["data1"].Value = i + 1;
cmd.Parameters["data2"].Value = i + 1;
cmd.ExecuteNonQuery();

//3.调用worker的ReportProgress函数,用来引发事件ProgressChanged
worker.ReportProgress(i, worker);
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
finally
{
if (conn.State == ConnectionState.Open)
conn.Close();
}

Thread.Sleep(50);
}
}

private void bgwInsertData_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
if (e.Error != null)
{
MessageBox.Show(e.Error.Message, "提示", MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
else if (e.Cancelled)
{
MessageBox.Show("取消操作!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
return;
}
else
MessageBox.Show("操作成功!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
}

[转载]BackgroundWorker原理剖析 - ProJKY - 博客园

mikel阅读(1042)

[转载]BackgroundWorker原理剖析 – ProJKY – 博客园.

BackgroundWorker类位于System.ComponentModel命名空间下,主要用来异步执行一个长时间的操作,然后,在完成事件中安全更新UI的控件属性。UI中的控件是不允许非创建该控件的线程修改的。典型用法如下:

BackgroundWorker m_worker = new BackgroundWorker();
// 设置支持进度报告、异步取消功能,默认都为false
m_worker.WorkerReportsProgress = true;
m_worker.WorkerSupportsCancellation = true;

// 绑定事件
m_worker.DoWork += m_worker_DoWork;
m_worker.ProgressChanged += m_worker_ProgressChanged;
m_worker.RunWorkerCompleted += m_worker_RunWorkerCompleted;

void m_worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) {
if (e.Cancelled == true) {
// 处理取消
return;
} else if (e.Error != null) {
// 处理异常
return;
}

// 在UI中显示结果
// txtBox.Text = e.Result.ToString();
}

void m_worker_ProgressChanged(object sender, ProgressChangedEventArgs e) {
//progressBar.Value = e.ProgressPercentage;
}

void m_worker_DoWork(object sender, DoWorkEventArgs e) {
BackgroundWorker sendWorker = sender as BackgroundWorker;

for (int i = 0; i &lt; 100; i++) {
// 做异步工作。。。。

// 报告进度
sendWorker.ReportProgress(i);

// 请求取消工作内容
if (sendWorker.CancellationPending == true) {
e.Cancel = true;
return;
}
}

// 可选,设置异步工作结果
e.Result = GetResultData();
}

它的实现原理最重要的只有两点:

一点是用异步委托间接使用线程池执行长时间的操作;

另外一点是通过AsyncOperationManager和AsyncOperation对调用RunWorkerAsync的线程SynchronizationContext进行抽象;

BackgroundWorker的源码参见 http://www.projky.com/dotnet/4.5.1/System/ComponentModel/BackgroundWorker.cs.html

首先从它的构造函数开始:

private delegate void WorkerThreadStartDelegate(object argument);

private AsyncOperation asyncOperation = null;
private readonly WorkerThreadStartDelegate threadStart;
private readonly SendOrPostCallback operationCompleted;
private readonly SendOrPostCallback progressReporter;

public BackgroundWorker()
{
threadStart = new WorkerThreadStartDelegate(WorkerThreadStart);
operationCompleted = new SendOrPostCallback(AsyncOperationCompleted);
progressReporter = new SendOrPostCallback(ProgressReporter);
}

定义了一个私有的委托类型WorkerThreadStartDelegate,以便于在该委托类型对象上直接调用BaginInvoke到线程池执行委托。SendOrPostCallback 是方便在UI线程(本质是调用RunWorkAsync时捕获的当前线程同步上下文对象,为了容易理解,就叫它UI线程)上执行回调而创建的。而asyncOperation则通过Post方法在UI线程上异步来执行SendOrPostCallback委托。

在对DoWork添加事件后,需要调用RunWorkerAsync,有两个重载,但我们只关注最后一个带参数的:

public void RunWorkerAsync(object argument)
{
if (isRunning)
{
throw new InvalidOperationException(SR.GetString(SR.BackgroundWorker_WorkerAlreadyRunning));
}

isRunning = true;
cancellationPending = false;

asyncOperation = AsyncOperationManager.CreateOperation(null);
threadStart.BeginInvoke(argument,
null,
null);
}

其实,asyncOperation = AsyncOperationManager.CreateOperation(null);这一行代码,等同于下面的代码:

if (SynchronizationContext.Current == null) {
SynchronizationContext.SetSynchronizationContext(new SynchronizationContext());
}
SynchronizationContext currentContext = SynchronizationContext.Current;
asyncOperation = AsyncOperation.CreateOperation(null, currentContext)

简单来说,就是获得当前的SynchronizationContext的对象,如果不存在,则创建一个默认的(基于线程池实现的)。并让asyncOperation拥有SynchronizationContext的引用。

在.NET中,有很多种SynchronizationContext的子类,比如Winform里面的WindowsFormsSynchronizationContext类,WPF里面的DispatcherSynchronizationContext类,ASP.NET里面的AspNetSynchronizationContext类。重点是,当在Winform的UI线程中访问SynchronizationContext.Current属性,获得的就是WindowsFormsSynchronizationContext的对象。

那么,最终,AsyncOperation的Post方法,就是直接调用SynchronizationContext的Post方法,来实现在UI中回调的目的。


public void Post(SendOrPostCallback d, object arg)
{
VerifyNotCompleted();
VerifyDelegateNotNull(d);
syncContext.Post(d, arg);
}

还有一点,threadStart.BeginInvoke会用线程池中的线程执行类似如下的代码:

object workerResult = null;
Exception error = null;
bool cancelled = false;

try
{
DoWorkEventArgs doWorkArgs = new DoWorkEventArgs(argument);
DoWorkEventHandler handler = (DoWorkEventHandler)(Events[doWorkKey]);
if (handler != null)
{
handler(this, doWorkArgs);
}
if (doWorkArgs.Cancel)
{
cancelled = true;
}
else
{
workerResult = doWorkArgs.Result;
}
}
catch (Exception exception)
{
error = exception;
}

RunWorkerCompletedEventArgs e =
new RunWorkerCompletedEventArgs(workerResult, error, cancelled);

asyncOperation.PostOperationCompleted(operationCompleted, e);

其中,对DoWork事件的声明如下:

private static readonly object doWorkKey = new object();

public event DoWorkEventHandler DoWork{
add{
this.Events.AddHandler(doWorkKey, value);
}
remove{
this.Events.RemoveHandler(doWorkKey, value);
}
}

Events是从Component下派生来的protected EventHandlerList对象。

从BackgroundWorker的实现可以看出,它的实现是普遍性的,并不一定要用在Winform或者WPF中。

本文引用的源码参考列表可以从扣丁格鲁上查看。

http://www.projky.com/dotnet/4.5.1/System/ComponentModel/BackgroundWorker.cs.html

http://www.projky.com/dotnet/4.5.1/System/ComponentModel/AsyncOperation.cs.html

http://www.projky.com/dotnet/4.5.1/System/ComponentModel/AsyncOperationManager.cs.html

http://www.projky.com/dotnet/4.5.1/System/Threading/SynchronizationContext.cs.html

 

http://www.projky.com/dotnet/4.5.1/System/Windows/Forms/WindowsFormsSynchronizationContext.cs.html

http://www.projky.com/dotnet/4.5.1/System/Windows/Threading/DispatcherSynchronizationContext.cs.html

http://www.projky.com/dotnet/4.5.1/System/Web/AspNetSynchronizationContext.cs.html

 

关于基于事件的异步编程设计模式EAP更多参考请见http://msdn.microsoft.com/zh-cn/library/hkasytyf(v=vs.110).aspx

版权归博客园和作者共有。.NET类库源码参考 扣丁格鲁 www.projky.com,转载请注明出处。

[转载]c# 对SQLite操作类借鉴并修改 - Light Xun - 博客园

mikel阅读(970)

[转载]c# 对SQLite操作类借鉴并修改 – Light Xun – 博客园.

/// <summary>
/// SQLite 操作类
/// Author Light
/// </summary>
public class SQLite
{
    /// <summary>
    /// 数据库
    /// </summary>
    public static string dataBasePath;
 
    public static string dataBasePasssord;
 
    /// <summary>
    /// 获取连接
    /// </summary>
    /// <returns></returns>
    private static SQLiteConnection getSQLiteConnection()
    {
        SQLiteConnection conn = null;         
        try
        {
            conn = new SQLiteConnection();
            SQLiteConnectionStringBuilder connStr = new SQLiteConnectionStringBuilder();
            connStr.DataSource = dataBasePath;
            connStr.Password = dataBasePasssord;                        //设置密码,SQLite ADO.NET实现了数据库密码保护
            conn.ConnectionString = connStr.ToString();
        }
        catch (ExceptionUtility ex)
        {
            throw new ExceptionUtility("连接数据库异常:" + ex.Message);
        }                    
        return conn;
    }
 
    #region 执行查询
 
    /// <summary>
    /// 执行SQL,返回影响的记录数
    /// </summary>
    /// <param name="sql"></param>
    /// <returns></returns>
    public static int ExecuteSql(string sql)
    {
        int iResult = -1;
        using (SQLiteConnection conn = getSQLiteConnection())
        {
            using (SQLiteCommand cmd = new SQLiteCommand(sql, conn))
            {
                try
                {
                    conn.Open();
                    iResult = cmd.ExecuteNonQuery();
                }
                catch (ExceptionUtility ex)
                {
                    throw new ExceptionUtility("执行SQL,返回影响的记录数异常:" + ex.Message);
                }
            }
        }
        return iResult;
    }
 
    /// <summary>
    /// 执行带一个存储过程参数的SQL语句
    /// </summary>
    /// <param name="sql"></param>
    /// <param name="content"></param>
    /// <returns></returns>
    public static int ExecuteSql(string sql, string content)
    {
        int iResult = -1;
        using (SQLiteConnection conn = getSQLiteConnection())
        {
            using (SQLiteCommand cmd = new SQLiteCommand(sql, conn))
            {
                try
                {
                    SqlParameter parameter = new SqlParameter("@content", SqlDbType.NText);
                    parameter.Value = content;
                    cmd.Parameters.Add(parameter);
                    conn.Open();
                    iResult = cmd.ExecuteNonQuery();
                }
                catch (ExceptionUtility ex)
                {
                    throw new ExceptionUtility("执行带一个存储过程参数的SQL语句异常:" + ex.Message);
                }
            }
        }
        return iResult;
    }
 
    /// <summary>
    /// 执行SQL语句,返回影响的记录数
    /// </summary>
    /// <param name="sql"></param>
    /// <param name="sqlParams"></param>
    /// <returns></returns>
    public static int ExecuteSql(string sql, params SqlParameter[] sqlParams)
    {
        int iResult = -1;
        using (SQLiteConnection conn = getSQLiteConnection())
        {
            using (SQLiteCommand cmd = new SQLiteCommand())
            {
                try
                {
                    PrepareCommand(conn, cmd, null, sql, sqlParams);
                    iResult = cmd.ExecuteNonQuery();
                    cmd.Parameters.Clear();
                }
                catch (ExceptionUtility ex)
                {
                    throw new ExceptionUtility("执行SQL语句,返回影响的记录数异常:" + ex.Message);
                }
            }
        }
        return iResult;
    }
 
    /// <summary>
    /// 执行查询
    /// </summary>
    /// <param name="sql"></param>
    /// <returns></returns>
    public static DataSet Query(string sql)
    {
        DataSet dsResult = null;
        using (SQLiteConnection conn = getSQLiteConnection())
        {
            using (SQLiteDataAdapter da = new SQLiteDataAdapter(sql, conn))
            {
                try
                {
                    conn.Open();
                    dsResult = new DataSet();
                    da.Fill(dsResult, "ds");
                }
                catch (ExceptionUtility ex)
                {
                    throw new ExceptionUtility("执行查询异常:" + ex.Message);
                }
            }
        }
        return dsResult;
    }
 
    /// <summary>
    /// 执行查询语句,返回DataSet
    /// </summary>
    /// <param name="sql"></param>
    /// <param name="sqlParams"></param>
    /// <returns></returns>
    public static DataSet Query(string sql, params SqlParameter[] sqlParams)
    {
        DataSet dsResult = null;
        using (SQLiteConnection conn = getSQLiteConnection())
        {
            using (SQLiteCommand cmd = new SQLiteCommand())
            {
                using (SQLiteDataAdapter da = new SQLiteDataAdapter(cmd))
                {
                    try
                    {
                        PrepareCommand(conn, cmd, null, sql, sqlParams);
                        dsResult = new DataSet();
                        da.Fill(dsResult, "ds");
                        cmd.Parameters.Clear();
                    }
                    catch (ExceptionUtility ex)
                    {
                        throw new ExceptionUtility("执行查询返回DataSet异常:" + ex.Message);
                    }
                }
            }
        }
        return dsResult;
    }
 
    /// <summary>
    /// 执行一条计算查询结果语句,返回查询结果(object)
    /// 第一行第一列
    /// </summary>
    /// <param name="sql"></param>
    /// <returns></returns>
    public static object GetSingle(string sql)
    {
        object oResult = null;
        using (SQLiteConnection conn = getSQLiteConnection())
        {
            using (SQLiteCommand cmd = new SQLiteCommand(sql, conn))
            {
                try
                {
                    conn.Open();
                    oResult = cmd.ExecuteScalar();
                }
                catch (ExceptionUtility ex)
                {
                    throw new ExceptionUtility("执行一条计算查询结果语句,返回查询结果(object)异常:" + ex.Message);
                }
            }
        }
        return oResult;
    }
 
    /// <summary>
    /// 执行一条计算查询结果语句,返回查询结果(object)
    /// </summary>
    /// <param name="sql"></param>
    /// <param name="sqlParams"></param>
    /// <returns></returns>
    public static object GetSingle(string sql, params SqlParameter[] sqlParams)
    {
        object oResult = null;
        using (SQLiteConnection conn = getSQLiteConnection())
        {
            using (SQLiteCommand cmd = new SQLiteCommand())
            {
                try
                {
                    PrepareCommand(conn, cmd, null, sql, sqlParams);
                    oResult = cmd.ExecuteScalar();
                    cmd.Parameters.Clear();
                }
                catch (ExceptionUtility ex)
                {
                    throw new ExceptionUtility("执行查询异常:" + ex.Message);
                }
            }
        }
        return oResult;
    }
 
    /// <summary>
    /// 执行查询,返回sqliteDataReader
    /// </summary>
    /// <param name="sql"></param>
    /// <returns></returns>
    public static SQLiteDataReader ExecuteReader(string sql)
    {
        SQLiteDataReader rResult = null;
        using (SQLiteConnection conn = getSQLiteConnection())
        {
            using (SQLiteCommand cmd = new SQLiteCommand(sql, conn))
            {
                try
                {
                    conn.Open();
                    rResult = cmd.ExecuteReader();
                }
                catch (ExceptionUtility ex)
                {
                    throw new ExceptionUtility("执行查询返回sqliteDataReader异常:" + ex.Message);
                }
            }
        }
        return rResult;
    }
 
    /// <summary>
    /// 执行查询语句,返回SqliteDataReader
    /// </summary>
    /// <param name="sql"></param>
    /// <param name="sqlParams"></param>
    /// <returns></returns>
    public static SQLiteDataReader ExecuteReader(string sql, params SqlParameter[] sqlParams)
    {
        SQLiteDataReader rResult = null;
        using (SQLiteConnection conn = getSQLiteConnection())
        {
            using (SQLiteCommand cmd = new SQLiteCommand())
            {
                try
                {
                    PrepareCommand(conn, cmd, null, sql, sqlParams);
                    rResult = cmd.ExecuteReader();
                    cmd.Parameters.Clear();
                }
                catch (ExceptionUtility ex)
                {
                    throw new ExceptionUtility("执行查询返回SqliteDataReader异常:" + ex.Message);
                }
            }
        }
        return rResult;
    }
 
    #endregion  执行查询
 
    #region  执行事务
 
    /// <summary>
    /// 执行SQL事务操作
    /// </summary>
    /// <param name="sql"></param>
    /// <returns></returns>
    public static int ExecuteSqlTran(string sql)
    {
        int iResult = -1;
        using (SQLiteConnection conn = getSQLiteConnection())
        {
            using (SQLiteTransaction tran = conn.BeginTransaction())
            {
                using (SQLiteCommand cmd = new SQLiteCommand(sql, conn, tran))
                {
                    try
                    {
                        if (!string.IsNullOrEmpty(sql))
                        {
                            conn.Open();
                            iResult = cmd.ExecuteNonQuery();
                            tran.Commit();
                        }
                    }
                    catch (ExceptionUtility ex)
                    {
                        tran.Rollback();
                        throw new ExceptionUtility("执行SQL事务操作异常:" + ex.Message);
                    }
                }
            }
        }
        return iResult;
    }
 
    /// <summary>
    /// 执行多条SQL事务操作
    /// </summary>
    /// <param name="sql"></param>
    /// <returns></returns>
    public static int ExecuteSqlTran(List<string> sqlList)
    {
        int iResult = -1;
        using (SQLiteConnection conn = getSQLiteConnection())
        {
            using (SQLiteTransaction tran = conn.BeginTransaction())
            {
                using (SQLiteCommand cmd = new SQLiteCommand())
                {
                    try
                    {
                        conn.Open();
                        cmd.Connection = conn;
                        cmd.Transaction = tran;
                        foreach (string sql in sqlList)
                        {
                            if (!string.IsNullOrEmpty(sql))
                            {
                                cmd.CommandText = sql;
                                iResult += cmd.ExecuteNonQuery();
                            }
                        }
                        tran.Commit();
                    }
                    catch (ExceptionUtility ex)
                    {
                        tran.Rollback();
                        throw new ExceptionUtility("执行多条SQL事务操作异常:" + ex.Message);
                    }
                }
            }
        }
        return iResult;
    }
 
    /// <summary>
    /// 执行多条SQL语句,实现数据库事务
    /// </summary>
    /// <param name="sqlHashTable"></param>
    /// <returns></returns>
    public static int ExecuteSqlTran(Hashtable sqlHashTable)
    {
        int iResult = -1;
        using (SQLiteConnection conn = getSQLiteConnection())
        {
            using (SQLiteTransaction tran = conn.BeginTransaction())
            {
                using (SQLiteCommand cmd = new SQLiteCommand())
                {
                    try
                    {
                        conn.Open();
                        foreach (DictionaryEntry de in sqlHashTable)
                        {
                            string cmdSql = de.Key.ToString();
                            SqlParameter[] cmdParams = (SqlParameter[])de.Value;
                            PrepareCommand(conn, cmd, tran, cmdSql, cmdParams);
                            iResult = cmd.ExecuteNonQuery();
                            cmd.Parameters.Clear();
                            tran.Commit();
                        }
                    }
                    catch (ExceptionUtility ex)
                    {
                        tran.Rollback();
                        throw new ExceptionUtility("执行多条SQL事务异常:" + ex.Message);
                    }
                }
            }
        }
        return iResult;
    }
 
 
 
    /// <summary>
    /// 向数据库中插入图像格式字段
    /// </summary>
    /// <param name="sql"></param>
    /// <param name="fs"></param>
    /// <returns></returns>
    public static int ExecuteSqlInsertImg(string sql, byte[] fs)
    {
        int iResult = -1;
        using (SQLiteConnection conn = getSQLiteConnection())
        {
            using (SQLiteCommand cmd = new SQLiteCommand(sql, conn))
            {
                try
                {
                    SqlParameter sqlParam = new SqlParameter("@fs", SqlDbType.Image);
                    sqlParam.Value = fs;
                    cmd.Parameters.Add(sqlParam);
                    conn.Open();
                    iResult = cmd.ExecuteNonQuery();
                }
                catch (ExceptionUtility ex)
                {
                    throw new ExceptionUtility("插入图像字段异常:" + ex.Message);
                }
            }
        }
        return iResult;
    }
 
    #endregion 执行事务
 
    #region 私有公共方法
 
    private static void PrepareCommand(SQLiteConnection conn, SQLiteCommand cmd, SQLiteTransaction tran, string sql, SqlParameter[] sqlParams)
    {
        if (conn.State != ConnectionState.Open)
        {
            conn.Open();
        }
        cmd.Connection = conn;
        cmd.CommandText = sql;
 
        if (tran != null)
        {
            cmd.Transaction = tran;
        }
        cmd.CommandType = CommandType.Text;
 
        if (sqlParams != null)
        {
            foreach (SqlParameter param in sqlParams)
            {
                cmd.Parameters.Add(param);
            }
        }
    }
 
    #endregion 私有公共方法
 
    #region 存储过程
 
    /// <summary>
    /// 执行存储过程
    /// </summary>
    /// <param name="storedProcName"></param>
    /// <param name="dataParams"></param>
    /// <returns></returns>
    public static SQLiteDataReader RunProcedure(string storedProcName, IDataParameter[] dataParams)
    {
        SQLiteDataReader rResult = null;
        using (SQLiteConnection conn = getSQLiteConnection())
        {
            using (SQLiteCommand cmd = BuildQueryCommand(conn, storedProcName, dataParams))
            {
                try
                {
                    rResult = cmd.ExecuteReader();
                }
                catch (ExceptionUtility ex)
                {
                    throw new ExceptionUtility("执行存储过程异常:" + ex.Message);
                }
            }
        }
        return rResult;
    }
 
    /// <summary>
    /// 执行存储过程
    /// </summary>
    /// <param name="storedProcName"></param>
    /// <param name="dataParams"></param>
    /// <param name="tableName"></param>
    /// <returns></returns>
    public static DataSet RunProcedure(string storedProcName, IDataParameter[] dataParams, string tableName)
    {
        DataSet dsResult = null;
        using (SQLiteConnection conn = getSQLiteConnection())
        {
            using (SQLiteDataAdapter da = new SQLiteDataAdapter())
            {
                try
                {
                    dsResult = new DataSet();
                    da.SelectCommand = BuildQueryCommand(conn, storedProcName, dataParams);
                    da.Fill(dsResult, tableName);
                }
                catch (ExceptionUtility ex)
                {
                    throw new ExceptionUtility("执行存储过程异常:" + ex.Message);
                }
            }
        }
        return dsResult;
    }
 
    /// <summary>
    /// 执行存储过程,返回影响的行数
    /// </summary>
    /// <param name="storedProcName"></param>
    /// <param name="dataParams"></param>
    /// <param name="rowsAffected"></param>
    /// <returns></returns>
    public static int RunProcedure(string storedProcName, IDataParameter[] dataParams, out int rowsAffected)
    {
        int iResult = -1;
        using (SQLiteConnection conn = getSQLiteConnection())
        {
            try
            {
                SQLiteCommand cmd = BuildIntCommand(conn, storedProcName, dataParams);
                rowsAffected = cmd.ExecuteNonQuery();
                iResult = (int)cmd.Parameters["ReturnValue"].Value;
            }
            catch (ExceptionUtility ex)
            {
                throw new ExceptionUtility("执行存储过程异常:" + ex.Message);
            }               
        }
        return iResult;
    }
 
 
    /// <summary>
    /// 创建SQLiteCommand对象实例(用来返回一个整数值)
    /// </summary>
    /// <param name="conn"></param>
    /// <param name="storedProcName"></param>
    /// <param name="dataParams"></param>
    /// <returns></returns>
    private static SQLiteCommand BuildIntCommand(SQLiteConnection conn, string storedProcName, IDataParameter[] dataParams)
    {
        SQLiteCommand cmd = BuildQueryCommand(conn, storedProcName, dataParams);
        cmd.Parameters.Add(new SqlParameter("ReturnValue", SqlDbType.Int, 4, ParameterDirection.ReturnValue, false, 0, 0, string.Empty, DataRowVersion.Default, null));
        return cmd;
    }
 
    /// <summary>
    /// 构建SqliteCommand对象(用来返回一个结果集,而不是一个整数值)
    /// </summary>
    /// <param name="conn"></param>
    /// <param name="storedProcName"></param>
    /// <param name="dataParams"></param>
    /// <returns></returns>
    private static SQLiteCommand BuildQueryCommand(SQLiteConnection conn, string storedProcName, IDataParameter[] dataParams)
    {
        SQLiteCommand cmd = new SQLiteCommand(storedProcName, conn);
        try
        {
            if (conn.State != ConnectionState.Open)
            {
                conn.Open();
            }
            cmd.CommandType = CommandType.StoredProcedure;
            foreach (SqlParameter param in dataParams)
            {
                cmd.Parameters.Add(param);
            }
        }
        catch (ExceptionUtility ex)
        {
            throw new ExceptionUtility("构建SQLiteCommand异常:" + ex.Message);
        }
        return cmd;
    }
 
    #endregion  存储过程
 
     
}

[转载]一个小时内学习 SQLite 数据库 - 开源中国社区

mikel阅读(1145)

[转载]一个小时内学习 SQLite 数据库 – 开源中国社区.

1. 介绍
SQLite 是一个开源的嵌入式关系数据库,实现自包容、零配置、支持事务的SQL数据库引擎。 其特点是高度便携、使用方便、结构紧凑、高效、可靠。 与其他数据库管理系统不同,SQLite 的安装和运行非常简单,在大多数情况下 – 只要确保SQLite的二进制文件存在即可开始创建、连接和使用数据库。如果您正在寻找一个嵌入式数据库项目或解决方案,SQLite是绝对值得考虑。

2. 安装

SQLite on Windows

  1. 进入 SQL 下载页面:http://www.sqlite.org/download.html
  2. 下载 Windows 下的预编译二进制文件包:
    • sqlite-shell-win32-x86-<build#>.zip
    • sqlite-dll-win32-x86-<build#>.zip
  3. 注意: <build#> 是 sqlite 的编译版本号

  4. 将 zip 文件解压到你的磁盘,并将解压后的目录添加到系统的 PATH 变量中,以方便在命令行中执行 sqlite 命令。
  5. 可选: 如果你计划发布基于 sqlite 数据库的应用程序,你还需要下载源码以便编译和利用其 API
    • sqlite-amalgamation-<build#>.zip

SQLite on Linux

在 多个 Linux 发行版提供了方便的命令来获取 SQLite:

1 /* For Debian or Ubuntu /*
2 $ sudo apt-get install sqlite3 sqlite3-dev
3
4 /* For RedHat, CentOS, or Fedora/*
5 $ yum install SQLite3 sqlite3-dev

SQLite on Mac OS X

如果你正在使用 Mac OS 雪豹或者更新版本的系统,那么系统上已经装有 SQLite 了。

3. 创建首个 SQLite 数据库

现在你已经安装了 SQLite 数据库,接下来我们创建首个数据库。在命令行窗口中输入如下命令来创建一个名为  test.db 的数据库。

1 sqlite3 test.db

创建表:

1 sqlite> create table mytable(id integer primary key, value text);
2
3 2 columns were created.

该表包含一个名为 id 的主键字段和一个名为 value 的文本字段。

注意: 最少必须为新建的数据库创建一个表或者视图,这么才能将数据库保存到磁盘中,否则数据库不会被创建。

接下来往表里中写入一些数据:

1 sqlite> insert into mytable(id, value) values(1, 'Micheal');
2 sqlite> insert into mytable(id, value) values(2, 'Jenny');
3 sqlite> insert into mytable(value) values('Francis');
4 sqlite> insert into mytable(value) values('Kerk');

查询数据:

1 sqlite> select * from test;
2 1|Micheal
3 2|Jenny
4 3|Francis
5 4|Kerk

设置格式化查询结果:

1 sqlite> .mode column;
2 sqlite> .header on;
3 sqlite> select * from test;
4 id          value
5 ----------- -------------
6 1           Micheal
7 2           Jenny
8 3           Francis
9 4           Kerk

.mode column 将设置为列显示模式,.header 将显示列名。

修改表结构,增加列:

1 sqlite> alter table mytable add column email text not null '' collate nocase;;

创建视图:

1 sqlite> create view nameview as select * from mytable;

创建索引:

1 sqlite> create index test_idx on mytable(value);

4. 一些有用的 SQLite 命令

显示表结构:
sqlite> .schema [table]

获取所有表和视图:

sqlite > .tables

获取指定表的索引列表:

sqlite > .indices [table ]

导出数据库到 SQL 文件:

sqlite > .output [filename ]
sqlite > .dump
sqlite > .output stdout

从 SQL 文件导入数据库:

sqlite > .read [filename ]

格式化输出数据到 CSV 格式:

sqlite >.output [filename.csv ]
sqlite >.separator ,
sqlite > select * from test;
sqlite >.output stdout

从 CSV 文件导入数据到表中:

sqlite >create table newtable ( id integer primary key, value text );
sqlite >.import [filename.csv ] newtable

备份数据库:
/* usage: sqlite3 [database] .dump > [filename] */
sqlite3 mytable.db .dump > backup.sql

恢复数据库:

/* usage: sqlite3 [database ]<[filename ]*/
sqlite3 mytable.db < backup.sql

 

英文原文OSCHINA原创翻译