• [技术干货] sqlite嵌入式数据库的移植和使用
    sQlite是D. Richard Hipp 用C语言编写的开源嵌入式数据库引擎。它是完全独立的,没有外部依赖性。占用资源非常低,在嵌人式设备中,只需要几百KB的内存。它能够支持Windows, Limux等主流操作系统,可与Tel, PHP和Java等程序语言结合,提供ODBC接口,其处理速度甚至令开源世界著名的数据库管理系统MysQL和PostgreSQL.望尘莫及。solie对50192标准的支持包括索引、限制、触发和查看,支持原子的、一致的、独立的和持久(ACID)的事务。在内部, SoLite由SQL编译器、内核、后端以及附件几个组件组成。 sqlite通过利用虚拟机和虚拟数据库引擎(VDBE) ,使调试、修改和扩展SQLite的内核变得更加方便。所有sql,语句都被编译成易读的,可以在SQLite虚拟机中执行的程序集。现在项目需要使用SOLite数据库,需要将SQLite移植到ARM 2440嵌人式主机中,并续写一个简单的测试程序。现在项目需要使用sqlite数据库  需要将sqlite移植到arm2440嵌入式主机中并编写一个简单的测试程序项目实施步骤:1)下载并编译sqlite2)下载到arm虚拟机并使用sqlite如何下载编译sqlite从http://www.sqlite.org/download.html下载sqlite文件 当前版本是:3.9.2 文件名为:sqlite-autoconf-3090200.tar.gz解压并查看当前目录及install文件# tar zsf sqlite -autoconf-309200.tar,gz#lsaclocal.m4 configure.ac #itmain.sh #Readme#sqlite3ext.hconfig guess depcomp  make file.am  shell.c sqlite3.hconfig.sub  install  makefile.in sqlite 3.1 sqlite 3.pc inconfigure install-sh missing sqlite3.c tea创建一个目录build进入主目录在这个目录中将进行交叉编译在build目录中运行sqlite-autoconf-309200中的configure脚本 生成makefile文件 代码如下:../configure--host=ARM-LINUX -- PREFIX =/opt/sqlite-autoconf-309200/build 选项host指定的是用arm交叉编译器进行编译 选项prefix后面的鲤鱼精是编译安装后目标存放的目录可以任意设置#mkdir build  #cd mkdir #../configure --houst=arm-linux--prefix=/opt/sqlite-autoconf-309200/build#ls#config.log config.log config.status libtool makefile sqlite3.pc#make #makeinstall#lsbin  include  libtool  sqlite3  sqlite3.pcconfig.log  lib   makefile  sqlite3.lo  sqkite3-shell.oconfig.status  libsqlite3.la share  sqlite3.o sqlite3-sqlite3.o编译和安装完成后 在/root/sqlite-autoconf-309200/bulid 目录中会生成3个目标文件夹  分别是bin  include和lib下载到arm虚拟机并使用sqlite 分别将bin下的文件下载到开发板的/user/bin目录中去 lib下的所有文件下载到开发板的/lib目录中即可nclude目录下是sqlite的c语言api的头文件编译时会用到下面示例在arm虚拟机中测试 将root/sqlite-autoconf-309200/build目录中的bin和lib分别复制到/opt/root_qtopia/usr/bin与root_qyopia/lib/目录中#cd /opt/sqlite-autoconf-309200/build#cd bin#cp *.*/opt/root_qtopia/usr/bin#cd..#cd lib#cp *.*/opt/root_qtopia/lib/启动虚拟机 在arm虚拟机终端中运行 sqlite3 tst.db测试运行是否正常#sqlite3 tst.db sqlite version.................sql使用命令行管理数据库 在运行.help会列出常用的命令说明 这里我就不打出来了  也可以在官网中 去查看作者:仙女本仙
  • [技术干货] SQLite 错误码整理
    #define SQLITE_OK 0 /* 成功 | Successful result *//* 错误码开始 */#define SQLITE_ERROR 1 /* SQL错误 或 丢失数据库 | SQL error or missing database */#define SQLITE_INTERNAL 2 /* SQLite 内部逻辑错误 | Internal logic error in SQLite */#define SQLITE_PERM 3 /* 拒绝访问 | Access permission denied */#define SQLITE_ABORT 4 /* 回调函数请求取消操作 | Callback routine requested an abort */#define SQLITE_BUSY 5 /* 数据库文件被锁定 | The database file is locked */#define SQLITE_LOCKED 6 /* 数据库中的一个表被锁定 | A table in the database is locked */#define SQLITE_NOMEM 7 /* 某次 malloc() 函数调用失败 | A malloc() failed */#define SQLITE_READONLY 8 /* 尝试写入一个只读数据库 | Attempt to write a readonly database */#define SQLITE_INTERRUPT 9 /* 操作被 sqlite3_interupt() 函数中断 | Operation terminated by sqlite3_interrupt() */#define SQLITE_IOERR 10 /* 发生某些磁盘 I/O 错误 | Some kind of disk I/O error occurred */#define SQLITE_CORRUPT 11 /* 数据库磁盘映像不正确 | The database disk image is malformed */#define SQLITE_NOTFOUND 12 /* sqlite3_file_control() 中出现未知操作数 | Unknown opcode in sqlite3_file_control() */#define SQLITE_FULL 13 /* 因为数据库满导致插入失败 | Insertion failed because database is full */#define SQLITE_CANTOPEN 14 /* 无法打开数据库文件 | Unable to open the database file */#define SQLITE_PROTOCOL 15 /* 数据库锁定协议错误 | Database lock protocol error */#define SQLITE_EMPTY 16 /* 数据库为空 | Database is empty */#define SQLITE_SCHEMA 17 /* 数据结构发生改变 | The database schema changed */#define SQLITE_TOOBIG 18 /* 字符串或二进制数据超过大小限制 | String or BLOB exceeds size limit */#define SQLITE_CONSTRAINT 19 /* 由于约束违例而取消 | Abort due to constraint violation */#define SQLITE_MISMATCH 20 /* 数据类型不匹配 | Data type mismatch */#define SQLITE_MISUSE 21 /* 不正确的库使用 | Library used incorrectly */#define SQLITE_NOLFS 22 /* 使用了操作系统不支持的功能 | Uses OS features not supported on host */#define SQLITE_AUTH 23 /* 授权失败 | Authorization denied */#define SQLITE_FORMAT 24 /* 附加数据库格式错误 | Auxiliary database format error */#define SQLITE_RANGE 25 /* 传递给sqlite3_bind()的第二个参数超出范围 | 2nd parameter to sqlite3_bind out of range */#define SQLITE_NOTADB 26 /* 被打开的文件不是一个数据库文件 | File opened that is not a database file */#define SQLITE_ROW 100 /* sqlite3_step() 已经产生一个行结果 | sqlite3_step() has another row ready */#define SQLITE_DONE 101 /* sqlite3_step() 完成执行操作 | sqlite3_step() has finished executing *//* 错误码结束 */
  • [技术干货] SQLite速度评测代码
    SQLite 效率太低,批量插入1000条记录,居然耗时 2 分钟!下面是他发给我的测试代码。using System.Data;using System.Data.Common;using System.Data.SQLite;// 创建数据库文件File.Delete("test1.db3");SQLiteConnection.CreateFile("test1.db3");DbProviderFactory factory = SQLiteFactory.Instance;using (DbConnection conn = factory.CreateConnection()){// 连接数据库conn.ConnectionString = "Data Source=test1.db3";conn.Open();// 创建数据表string sql = "create table [test1] ( INTEGER PRIMARY KEY, [s] TEXT COLLATE NOCASE)";DbCommand cmd = conn.CreateCommand();cmd.Connection = conn;cmd.CommandText = sql;cmd.ExecuteNonQuery();// 添加参数cmd.Parameters.Add(cmd.CreateParameter());// 开始计时Stopwatch watch = new Stopwatch();watch.Start();// 连续插入1000条记录for (int i = 0; i < 1000; i++){cmd.CommandText = "insert into [test1] ([s]) values (?)";cmd.Parameters[0].Value = i.ToString();cmd.ExecuteNonQuery();}// 停止计时watch.Stop();Console.WriteLine(watch.Elapsed);}哎~~~~ 一个常识性的错误,我加几行代码 (新增代码标记 "// <-------------------")。using System.Data;using System.Data.Common;using System.Data.SQLite;// 创建数据库文件File.Delete("test1.db3");SQLiteConnection.CreateFile("test1.db3");DbProviderFactory factory = SQLiteFactory.Instance;using (DbConnection conn = factory.CreateConnection()){// 连接数据库conn.ConnectionString = "Data Source=test1.db3";conn.Open();// 创建数据表string sql = "create table [test1] ( INTEGER PRIMARY KEY, [s] TEXT COLLATE NOCASE)";DbCommand cmd = conn.CreateCommand();cmd.Connection = conn;cmd.CommandText = sql;cmd.ExecuteNonQuery();// 添加参数cmd.Parameters.Add(cmd.CreateParameter());// 开始计时Stopwatch watch = new Stopwatch();watch.Start();DbTransaction trans = conn.BeginTransaction(); // <-------------------try{// 连续插入1000条记录for (int i = 0; i < 1000; i++){cmd.CommandText = "insert into [test1] ([s]) values (?)";cmd.Parameters[0].Value = i.ToString();cmd.ExecuteNonQuery();}trans.Commit(); // <-------------------}catch{trans.Rollback(); // <-------------------throw; // <-------------------}// 停止计时watch.Stop();Console.WriteLine(watch.Elapsed);}执行一下,耗时 0.2 秒。这差距是不是太大了点?为什么只是简单启用了一个事务会有这么大的差距呢?很简单,SQLite 缺省为每个操作启动一个事务,那么原代码 1000 次插入起码开启了 1000 个事务,"事务开启 + SQL 执行 + 事务关闭" 自然耗费了大量的时间,这也是后面显示启动事务后为什么如此快的原因。
  • [技术干货] 使用Python对SQLite数据库操作
    QLite是一种嵌入式数据库,它的数据库就是一个文件。由于SQLite本身是C写的,而且体积很小,所以,经常被集成到各种应用程序中,甚至在IOS和Android的APP中都可以集成。Python内置了SQLite3,所以,在Python中使用SQLite,不需要安装任何东西,直接使用。在使用SQLite前,我们先要搞清楚几个概念:表是数据库中存放关系数据的集合,一个数据库里面通常都包含多个表,比如学生的表,班级的表,学校的表,等等。表和表之间通过外键关联。要操作关系数据库,首先要连接到数据库,一个数据库连接称为Connection。连接到数据库后,需要打开游标,称之为Cursor,通过Cursor执行SQL语句,然后,获得执行结果。一、连接数据库import sqlite3#数据库名db_name = "test.db"#表名table_name = "catalog"conn = sqlite3.connect(db_name)二、打开游标rs = conn.cursor()三、建表sql = 'create table ' + table_name + ' (id varchar(20) primary key, pid integer, name varchar(10))'try: rs.execute(sql) print("建表成功")except: print("建表失败")四、增,删,改,查操作# 增:增加三条记录sql = "Insert into " + table_name + " values ('001', 1, '张三')"try: rs.execute(sql) #提交事务 conn.commit() print("插入成功")except: print("插入失败")sql = "Insert into " + table_name + " values ('002', 2, '李四')"try: rs.execute(sql) #提交事务 conn.commit() print("插入成功")except: print("插入失败")sql = "Insert into " + table_name + " values ('003', 3, '王五')"try: rs.execute(sql) #提交事务 conn.commit() print("插入成功")except: print("插入失败")# 删:删除pid等于3的记录sql = "Delete from " + table_name + " where pid = 3"try: rs.execute(sql) conn.commit() print("删除成功")except: print("删除失败")# 改:将pid等于2的记录的pid改为1sql = "Update " + table_name + " set pid = 1 where pid = 2"try: rs.execute(sql) conn.commit() print("修改成功")except: print("修改失败")# 查# 查询数据库中所有表名sql = "Select name From sqlite_master where type = 'table'"res = rs.execute(sql)print(res.fetchall())# 查询表中所有记录sql = "Select * from " + table_nametry: res = rs.execute(sql) print(res.fetchall())except: print([])五、关闭游标rs.close()六、关闭数据库连接conn.close()
  • [技术干货] python 连接sqlite及简单操作
    直接给大家贴代码了,具体代码如下所示:import sqlite3#查询def load(table): #连接数据库 con = sqlite3.connect("E:/Datebase/SQLiteStudio/Park.db") #获得游标 cur = con.cursor() #查询整个表 cur.execute('select *from '+table) lists = ['name','password'] if table == 'login': #将数据库列名存入字典 colnames = {desc[0] for desc in cur.description} 将字典和数据库的数据一起存入列表,获得了记录字典 rowdicts = [dict(zip(lists, row)) for row in cur.fetchall()] else: rowdicts = [] for row in cur: rowdicts.append(row) con.commit() cur.close() return rowdicts#插入数据def insert_data(ID,name,money): con = sqlite3.connect("E:/Datebase/SQLiteStudio/Park.db") cur = con.cursor() #使用SQL语句插入 cur.execute('insert into Charge values (?,?,?)', (ID,name, money)) #插入后进行整表查询,看是否成功插入 cur.execute('select *from Charge') print(cur.fetchall()) con.commit() cur.close()
  • [技术干货] SQLite Delete详解及实例代码
    SQLite Delete详解SQLite 的 DELETE 查询用于删除表中已有的记录。可以使用带有 WHERE 子句的 DELETE 查询来删除选定行,否则所有的记录都会被删除。语法带有 WHERE 子句的 DELETE 查询的基本语法如下:DELETE FROM table_nameWHERE [condition];您可以使用 AND 或 OR 运算符来结合 N 个数量的条件。实例假设 COMPANY 表有以下记录:ID NAME AGE ADDRESS SALARY---------- ---------- ---------- ---------- ----------1 Paul 32 California 20000.02 Allen 25 Texas 15000.03 Teddy 23 Norway 20000.04 Mark 25 Rich-Mond 65000.05 David 27 Texas 85000.06 Kim 22 South-Hall 45000.07 James 24 Houston 10000.0下面是一个实例,它会删除 ID 为 7 的客户:sqlite> DELETE FROM COMPANY WHERE ID = 7;现在,COMPANY 表有以下记录:ID NAME AGE ADDRESS SALARY---------- ---------- ---------- ---------- ----------1 Paul 32 California 20000.02 Allen 25 Texas 15000.03 Teddy 23 Norway 20000.04 Mark 25 Rich-Mond 65000.05 David 27 Texas 85000.06 Kim 22 South-Hall 45000.0如果您想要从 COMPANY 表中删除所有记录,则不需要使用 WHERE 子句,DELETE 查询如下:sqlite> DELETE FROM COMPANY;现在,COMPANY 表中没有任何的记录,因为所有的记录已经通过 DELETE 语句删除。
  • [技术干货] HTCondor 8.9.2编译过程报“sqlite3.h: No such file or directory”解决方法
    【问题描述】HTCondor 8.9.2编译过程报“fatal error: sqlite3.h: No such file or directory”错误,详细报错如下:【解决方法】查找sqlite3.h文件:find / -name sqlite3.h将上面红框内的sqlite3.h拷贝到src/gce_gahp/路径再次执行make编译即可。
  • [问题求助] sqlite如何在liteos下使用
    大家好,我尝试把sqlite3.5在liteos下使用,总是各种问题,请问有没有移植好的库可以使用呢?
  • [技术干货] 基于Android SQLite的升级详解
    做Android应用,不可避免的会与SQLite打交道。随着应用的不断升级,原有的数据库结构可能已经不再适应新的功能,这时候,就需要对SQLite数据库的结构进行升级了。SQLite提供了ALTER TABLE命令,允许用户重命名或添加新的字段到已有表中,但是不能从表中删除字段。并且只能在表的末尾添加字段,比如,为 Subscription添加两个字段:ALTER TABLE Subscription ADD COLUMN Activation BLOB;ALTER TABLE Subscription ADD COLUMN Key BLOB;另外,如果遇到复杂的修改操作,比如在修改的同时,需要进行数据的转移,那么可以采取在一个事务中执行如下语句来实现修改表的需求。1. 将表名改为临时表ALTER TABLE Subscription RENAME TO __temp__Subscription;2. 创建新表CREATE TABLE Subscription (OrderId VARCHAR(32) PRIMARY KEY ,UserName VARCHAR(32) NOT NULL ,ProductId VARCHAR(16) NOT NULL);3. 导入数据INSERT INTO Subscription SELECT OrderId, “”, ProductId FROM __temp__Subscription;4. 删除临时表DROP TABLE __temp__Subscription;通过以上四个步骤,就可以完成旧数据库结构向新数据库结构的迁移,并且其中还可以保证数据不会应为升级而流失。
  • [技术干货] sqlite中文乱码问题原因分析及解决
    在VC++中通过sqlite3.dll接口对sqlite数据库进行操作,包括打开数据库,插入,查询数据库等,如果操作接口输入参数包含中文字符,会导致操作异常。例如调用sqlite3_open打开数据库文件,如果文件路径出现中文,就会导致打开失败。sqlite3_exec执行sql语句,如果包含中文对应字符就会变成乱码。这是由于sqlite数据库使用的是UTF-8编码方式,而传入的字符串是ASCII编码或Unicode编码,导致字符串格式错误。解决方案是在调用sqlite接口之前,先将字符串转换成UTF-8编码,以下提供各种字符串编码转换函数。 //UTF-8转Unicode std::wstring Utf82Unicode(const std::string& utf8string) { int widesize = ::MultiByteToWideChar(CP_UTF8, 0, utf8string.c_str(), -1, NULL, 0); if (widesize == ERROR_NO_UNICODE_TRANSLATION) { throw std::exception("Invalid UTF-8 sequence."); } if (widesize == 0) { throw std::exception("Error in conversion."); } std::vector<wchar_t> resultstring(widesize); int convresult = ::MultiByteToWideChar(CP_UTF8, 0, utf8string.c_str(), -1, &resultstring[0], widesize); if (convresult != widesize) { throw std::exception("La falla!"); } return std::wstring(&resultstring[0]); } //unicode 转为 ascii string WideByte2Acsi(wstring& wstrcode) { int asciisize = ::WideCharToMultiByte(CP_OEMCP, 0, wstrcode.c_str(), -1, NULL, 0, NULL, NULL); if (asciisize == ERROR_NO_UNICODE_TRANSLATION) { throw std::exception("Invalid UTF-8 sequence."); } if (asciisize == 0) { throw std::exception("Error in conversion."); } std::vector<char> resultstring(asciisize); int convresult =::WideCharToMultiByte(CP_OEMCP, 0, wstrcode.c_str(), -1, &resultstring[0], asciisize, NULL, NULL); if (convresult != asciisize) { throw std::exception("La falla!"); } return std::string(&resultstring[0]); } //utf-8 转 ascii string UTF_82ASCII(string& strUtf8Code) { string strRet(""); //先把 utf8 转为 unicode wstring wstr = Utf82Unicode(strUtf8Code); //最后把 unicode 转为 ascii strRet = WideByte2Acsi(wstr); return strRet; } /////////////////////////////////////////////////////////////////////// //ascii 转 Unicode wstring Acsi2WideByte(string& strascii) { int widesize = MultiByteToWideChar (CP_ACP, 0, (char*)strascii.c_str(), -1, NULL, 0); if (widesize == ERROR_NO_UNICODE_TRANSLATION) { throw std::exception("Invalid UTF-8 sequence."); } if (widesize == 0) { throw std::exception("Error in conversion."); } std::vector<wchar_t> resultstring(widesize); int convresult = MultiByteToWideChar (CP_ACP, 0, (char*)strascii.c_str(), -1, &resultstring[0], widesize); if (convresult != widesize) { throw std::exception("La falla!"); } return std::wstring(&resultstring[0]); } //Unicode 转 Utf8 std::string Unicode2Utf8(const std::wstring& widestring) { int utf8size = ::WideCharToMultiByte(CP_UTF8, 0, widestring.c_str(), -1, NULL, 0, NULL, NULL); if (utf8size == 0) { throw std::exception("Error in conversion."); } std::vector<char> resultstring(utf8size); int convresult = ::WideCharToMultiByte(CP_UTF8, 0, widestring.c_str(), -1, &resultstring[0], utf8size, NULL, NULL); if (convresult != utf8size) { throw std::exception("La falla!"); } return std::string(&resultstring[0]); } //ascii 转 Utf8 string ASCII2UTF_8(string& strAsciiCode) { string strRet(""); //先把 ascii 转为 unicode wstring wstr = Acsi2WideByte(strAsciiCode); //最后把 unicode 转为 utf8 strRet = Unicode2Utf8(wstr); return strRet; }
  • [技术干货] SQLite表达式详解(分享)
    一、常用表达式:    和大多数关系型数据库一样,SQLite能够很好的支持SQL标准中提供的表达式,其函数也与SQL标准保持一致,如:    ||    *    /    %    +    -    <<   >>   &    |    <    <=   >    >=    =    ==   !=   <>   IS   IS NOT   IN   LIKE     AND       OR    ~    NOT在上面的表达式中,唯一需要说明的是"||",该表达式主要用于两个字符串之间的连接,其返回值为连接后的字符串,即便该操作符两边的操作数为非字符串类型,在执行该表达式之前都需要被提前转换为字符串类型,之后再进行连接。二、条件表达式:    该表达式的语法规则如下:    1). CASE x WHEN w1 THEN r1 WHEN w2 THEN r2 ELSE r3 END    2). CASE WHEN x=w1 THEN r1 WHEN x=w2 THEN r2 ELSE r3 END  对于第一种情况,条件表达式x只需计算一次,然后分别和WHEN关键字后的条件逐一进行比较,直到找到相等的条件,其比较规则等价于等号(=)表达式。如果找到匹配的条件,则返回其后THEN关键字所指向的值,如果没有找到任何匹配,则返回ELSE关键字之后的值,如果不存在ELSE分支,则返回NULL。对于第二种情况,和第一种情况相比,唯一的差别就是表达式x可能被多次执行,比如第一个WHEN条件不匹配,则继续计算后面的WHEN条件,其它规则均与第一种完全相同。最后需要说明的是,以上两种形式的CASE表达式均遵守短路原则,即第一个表达式的条件一旦匹配,其后所有的WHEN表达式均不会再被执行或比较。三、转换表达式:    该表达式的语法规则如下:    CAST(expr AS target_type)该表达式会将参数expr转换为target_type类型,具体的转换规则见如下列表:目标类型转换规则描述TEXT如果转换INTEGER或REAL类型的值到TEXT类型直接转换即可,就像C/C++接口函数sqlite3_snprintf所完成的工作。REAL如果转换TEXT类型的值到REAL类型,在该文本的最前部,将可以转换为实数的文本转换为相应的实数,其余部分忽略。其中该文本值的前导零亦将被全部忽略。如果该文本值没有任何字符可以转换为实数,CAST表达式的转换结果为0.0。INTEGER如果转换TEXT类型的值到INTEGER类型,在该文本的最前部,将可以转换为整数的文本转换为相应的整数,其余部分忽略。其中该文本值的前导零亦将被全部忽略。如果该文本值没有任何字符可以转换为整数,CAST表达式的转换结果为0。如果转换将一个实数值转换为INTEGER类型,则直接截断实数小数部分。如果实数过大,则返回最大的负整数:-9223372036854775808。NUMERIC如果转换文本值到NUMERIC类型,则先将该值强制转换为REAL类型,只有在将REAL转换为INTEGER不会导致数据信息丢失以及完全可逆的情况下,SQLite才会进一步将其转换为INTEGER类型。 最后需要说明的是,如果expr为NULL,则转换的结果也为NULL。
  • [技术干货] SQLite数据库和事务(分享)
    一、Attach数据库:     ATTACH DATABASE语句添加另外一个数据库文件到当前的连接中,如果文件名为":memory:",我们可以将其视为内存数据库,内存数据库无法持久化到磁盘文件上。如果操作Attached数据库中的表,则需要在表名前加数据库名,如dbname.table_name。最后需要说明的是,如果一个事务包含多个Attached数据库操作,那么该事务仍然是原子的。见如下示例:    sqlite> CREATE TABLE testtable (first_col integer);    sqlite> INSERT INTO testtable VALUES(1);    sqlite> .backup 'D:/mydb.db'   --将当前连接中的主数据库备份到指定文件。    sqlite> .exit    --重新登录sqlite命令行工具:    sqlite> CREATE TABLE testtable (first_col integer);    sqlite> INSERT INTO testtable VALUES(2);    sqlite> INSERT INTO testtable VALUES(1);    sqlite> ATTACH DATABASE 'D:/mydb.db' AS mydb;        sqlite> .header on            --查询结果将字段名作为标题输出。    sqlite> .mode column        --将每列都分开显示。    sqlite> SELECT t1.first_col FROM testtable t1, mydb.testtable t2 WHERE t.first_col = t2.first_col;    first_col    ----------    1    二、Detach数据库:        卸载将当前连接中的指定数据库,注意main和temp数据库无法被卸载。见如下示例:    --该示例承载上面示例的结果,即mydb数据库已经被Attach到当前的连接中。    sqlite> DETACH DATABASE mydb;    sqlite> SELECT t1.first_col FROM testtable t1, mydb.testtable t2 WHERE t.first_col = t2.first_col;    Error: no such table: mydb.testtable    三、事务:    在SQLite中,如果没有为当前的SQL命令(SELECT除外)显示的指定事务,那么SQLite会自动为该操作添加一个隐式的事务,以保证该操作的原子性和一致性。当然,SQLite也支持显示的事务,其语法与大多数关系型数据库相比基本相同。见如下示例:    sqlite> BEGIN TRANSACTION;    sqlite> INSERT INTO testtable VALUES(1);    sqlite> INSERT INTO testtable VALUES(2);    sqlite> COMMIT TRANSACTION;      --显示事务被提交,数据表中的数据也发生了变化。    sqlite> SELECT COUNT(*) FROM testtable;    COUNT(*)    ----------    2    sqlite> BEGIN TRANSACTION;    sqlite> INSERT INTO testtable VALUES(1);    sqlite> ROLLBACK TRANSACTION;  --显示事务被回滚,数据表中的数据没有发生变化。    sqlite> SELECT COUNT(*) FROM testtable;    COUNT(*)    ----------    2
  • [技术干货] Android批量插入数据到SQLite数据库的方法
    Android中在sqlite插入数据的时候默认一条语句就是一个事务,因此如果存在上万条数据插入的话,那就需要执行上万次插入操作,操作速度可想而知。因此在Android中插入数据时,使用批量插入的方式可以大大提高插入速度。有时需要把一些数据内置到应用中,常用的有以下几种方式:1、使用db.execSQL(sql)这里是把要插入的数据拼接成可执行的sql语句,然后调用db.execSQL(sql)方法执行插入。public void inertOrUpdateDateBatch(List<String> sqls) { SQLiteDatabase db = getWritableDatabase(); db.beginTransaction(); try { for (String sql : sqls) { db.execSQL(sql); } // 设置事务标志为成功,当结束事务时就会提交事务 db.setTransactionSuccessful(); } catch (Exception e) { e.printStackTrace(); } finally { // 结束事务 db.endTransaction(); db.close(); } } 2、使用db.insert("table_name", null, contentValues)这里是把要插入的数据封装到ContentValues类中,然后调用db.insert()方法执行插入。db.beginTransaction(); // 手动设置开始事务 for (ContentValues v : list) { db.insert("bus_line_station", null, v); } db.setTransactionSuccessful(); // 设置事务处理成功,不设置会自动回滚不提交 db.endTransaction(); // 处理完成 db.close() 3、使用InsertHelper类这个类在API 17中已经被废弃了InsertHelper ih = new InsertHelper(db, "bus_line_station"); db.beginTransaction(); final int directColumnIndex = ih.getColumnIndex("direct"); final int lineNameColumnIndex = ih.getColumnIndex("line_name"); final int snoColumnIndex = ih.getColumnIndex("sno"); final int stationNameColumnIndex = ih.getColumnIndex("station_name"); try { for (Station s : busLines) { ih.prepareForInsert(); ih.bind(directColumnIndex, s.direct); ih.bind(lineNameColumnIndex, s.lineName); ih.bind(snoColumnIndex, s.sno); ih.bind(stationNameColumnIndex, s.stationName); ih.execute(); } db.setTransactionSuccessful(); } finally { ih.close(); db.endTransaction(); db.close(); } 4、使用SQLiteStatement查看InsertHelper时,官方文档提示改类已经废弃,请使用SQLiteStatementString sql = "insert into bus_line_station(direct,line_name,sno,station_name) values(?,?,?,?)"; SQLiteStatement stat = db.compileStatement(sql); db.beginTransaction(); for (Station line : busLines) { stat.bindLong(1, line.direct); stat.bindString(2, line.lineName); stat.bindLong(3, line.sno); stat.bindString(4, line.stationName); stat.executeInsert(); } db.setTransactionSuccessful(); db.endTransaction(); db.close(); 第三种方法需要的时间最短,鉴于该类已经在API17中废弃,所以第四种方法应该是最优的方法。
  • [技术干货] 安装和使用 SQLite
    介绍SQLite是一个免费的跨平台数据库管理系统。它因其与许多不同的编程语言接口的效率和能力而广受欢迎。在此教程中,您将在Ubuntu 20.04上安装SQLite。然后,您将创建一个数据库,从其中读取数据,插入项目,删除项目,并从单独的表中加入项目。注意:本教程包括安装和使用 SQLite 的实际说明。它不包括更大的概念问题和生产问题,例如何时应该或不应该考虑使用 SQLite 数据库。有关流行关系数据库及其比较方式的出色概述,请查看我们的文章,SQLite vs MySQL vsPostgresQL:关系数据库管理系统的比较。此外,许多语言与 SQLite 保持集成。有关在 Python 代码中使用 SQLite 的说明,请查看我们的教程,如何在 Python 3 中使用sqlite3模块。先决条件要完成此教程,您需要:运行Ubuntu 20.04的本地机器或服务器。第1步-在乌本图20.04安装SQLite要在 Ubuntu 上安装 SQLite 命令线接口,请首先更新您的包列表:sudo apt update现在安装 SQ 利特:sudo apt install sqlite3要验证安装,请检查软件的版本:sqlite --version您将收到这样的输出:Output3.31.1 2020-01-27 19:55:54 3bfa9cc97da10598521b342961df8f5f68c7388fa117345eeb516eaa837balt1安装 SQLite 后,您现在已准备好创建新数据库。第 2 步 - 创建 SQLite 数据库在此步骤中,您将创建一个包含不同鲨鱼及其属性的数据库。要创建数据库,请打开终端并运行此命令:sqlite3sqlite3 sharks.db这将创建一个新的数据库命名。如果文件已经存在,SQLite 将打开与它的连接:如果它不存在,SQLite将创建它。sharkssharks.db您将收到这样的输出:OutputSQLite version 3.31.1 2020-01-27 19:55:54Enter ".help" for usage hints.在此之后,您的提示将更改。一个新的前缀,现在出现:sqlite>创建鲨鱼数据库后,您现在将创建一个新表并填充数据。第 3 步 - 创建 SQLite 表SQLite 数据库被组织成表格。表存储信息。为了更好地可视化一张桌子,人们可以想象行和列。本教程的其余部分将遵循进入 SQLite 命令的常见惯例。SQLite 命令是大写字母,用户信息是小写字母。线必须以分号结束。现在,让我们为各种数据创建一个表和一些列:An ID鲨鱼的名字鲨鱼的类型鲨鱼的平均长度(厘米)使用以下命令创建表:CREATE TABLE sharks(id integer NOT NULL, name text NOT NULL, sharktype text NOT NULL, length integer NOT NULL);使用使该字段成为必需的。我们将在下一节中更详细地讨论。NOT NULLNOT NULL创建表后,空提示将返回。现在,让我们插入一些值。将值插入表中在 SQLite 中,将值插入表中的命令遵循此一般形式:INSERT INTO tablename VALUES(values go here);你的桌子的名字在哪里,并进入括号内。tablenamevalues现在将三行插入您的表格:VALUESsharksINSERT INTO sharks VALUES (1, "Sammy", "Greenland Shark", 427);INSERT INTO sharks VALUES (2, "Alyoshka", "Great White Shark", 600);INSERT INTO sharks VALUES (3, "Himari", "Megaladon", 1800);因为您之前为表中的每一个变量指定了每个变量,因此您必须为每个变量输入一个值。NOT NULL例如,尝试添加另一条鲨鱼而不设置其长度:INSERT INTO sharks VALUES (4, "Faiza", "Hammerhead Shark");您将收到此错误:OutputError: table sharks has 4 columns but 3 values were supplied在此步骤中,您创建了一个表并将其插入值。在下一步中,您将从数据库表中阅读。第4步——在SQLite中阅读表格在此步骤中,我们将重点讨论从表中读取数据的最基本方法。认识到 SQLite 提供了更具体的表中查看数据的方法。要查看带有所有插入值的表,请使用:SELECTSELECT * FROM sharks;您将看到以前插入的条目:Output1|Sammy|Greenland Shark|4272|Alyoshka|Great White Shark|6003|Himari|Megaladon|1800要根据条目(我们手动设置的值)查看条目,请将命令添加到您的查询中:idWHERESELECT * FROM sharks WHERE id IS 1;这将返回鲨鱼的平等:id1Output1|Sammy|Greenland Shark|427让我们仔细看看这个命令。首先,我们都()从我们的数据库值,。SELECT*sharks然后我们查看所有值。id然后,我们将所有表格条目返回到等于。id1到目前为止,您已经创建了一个表,将数据插入其中,并查询保存的数据。现在,您将更新现有表。第 5 步 - 在 SQLite 中更新表在以下两个部分中,您将首先在现有表中添加一个新列,然后更新表中的现有值。向 SQLite 表添加列SQLite 允许您使用命令更改表。这意味着您可以创建新的行和列,或修改现有的行和列。ALTER TABLE用于创建新列。本新专栏将跟踪每条鲨鱼的年龄:ALTER TABLEALTER TABLE sharks ADD COLUMN age integer;你现在有第五栏了。age在 SQLite 表中更新值使用命令,为每只鲨鱼添加新值:UPDATEageUPDATE sharks SET age = 272 WHERE id=1;UPDATE sharks SET age = 70 WHERE id=2;UPDATE sharks SET age = 40 WHERE id=3;Output1|Sammy|Greenland Shark|427|2722|Alyoshka|Great White Shark|600|703|Himari|Megaladon|1800|40在此步骤中,您更改了表的组成,然后更新了表内的值。在下一步中,您将从表中删除信息。第 6 步 - 删除 SQLite 中的信息在此步骤中,您将根据对参数的评估删除表中的条目。在以下命令中,您正在查询您的数据库,并要求它删除您餐桌上所有年龄小于 200 岁的鲨鱼:sharksDELETE FROM sharks WHERE age <= 200;打字将验证这一点,并且,谁每个不到200岁,被删除。只有格陵兰鲨鱼仍然存在:SELECT * FROM sharks;AlyoshkaHimariSammyOutput1|Sammy|Greenland Shark|427|272第 7 步 - 在 SQLite 中加入信息试想一下,我们有两张桌子:我们目前的桌子和一张桌子。现在,如果表具有映射到表中的 s 的值,并且它具有指示每个鲨鱼保护状态的值,该怎么办?sharksendangeredendangeredididsharksstatus如果您想查询两个表中的数据,您可以使用 SQLite 的四个连接命令之一:INNER JOINOUTER JOINLEFT JOINCROSS JOIN让我们创建第二个表,然后使用加入一些数据。INNER JOIN首先,创建您的表:endangeredCREATE TABLE endangered (id integer NOT NULL, status text NOT NULL);INSERT INTO endangered VALUES (1,  "near threatened");现在加入您的表格:SELECT * FROM sharks INNER JOIN endangered on sharks.id = endangered.id;`您的输出将看起来像这样:Output1|Sammy|Greenland Shark|427|272|1|near threatened请注意,输出还包括来自 。您可以使用更明确的命令指定所需的输出:idendangeredSELECT sharks.id, sharks.name, sharks.sharktype, sharks.length, sharks.age, endangered.status FROM sharks INNER JOIN endangered on sharks.id = endangered.id;此时间输出排除了第二个值:idOutput1|Sammy|Greenland Shark|427|272|near threatened您现在已成功加入来自多个表的信息。结论SQLite 是数据库管理的有用工具。可以快速创建数据库,并使用各种命令操作它。在此教程之后,您现在对 SQLite 有了基本的了解,并准备深入到此数据库管理系统中。此外,许多语言与 SQLite 保持集成。对于 SQLite 语法的具体帮助,官方文档是另一个极好的资源。
  • [技术干货] SQLite内置函数
    一、聚合函数:    SQLite中支持的聚合函数在很多其他的关系型数据库中也同样支持,因此我们这里将只是给出每个聚集函数的简要说明,而不在给出更多的示例了。这里还需要进一步说明的是,对于所有聚合函数而言,distinct关键字可以作为函数参数字段的前置属性,以便在进行计算时忽略到所有重复的字段值,如count(distinct x)。函数说明avg(x)该函数返回在同一组内参数字段的平均值。对于不能转换为数字值的String和BLOB类型的字段值,如'HELLO',SQLite会将其视为0。avg函数的结果总是浮点型,唯一的例外是所有的字段值均为NULL,那样该函数的结果也为NULL。count(x|*)count(x)函数返回在同一组内,x字段中值不等于NULL的行数。count(*)函数返回在同一组内的数据行数。group_concat(x[,y])该函数返回一个字符串,该字符串将会连接所有非NULL的x值。该函数的y参数将作为每个x值之间的分隔符,如果在调用时忽略该参数,在连接时将使用缺省分隔符","。再有就是各个字符串之间的连接顺序是不确定的。max(x)该函数返回同一组内的x字段的最大值,如果该字段的所有值均为NULL,该函数也返回NULL。 min(x)该函数返回同一组内的x字段的最小值,如果该字段的所有值均为NULL,该函数也返回NULL。sum(x)该 函数返回同一组内的x字段值的总和,如果字段值均为NULL,该函数也返回NULL。如果所有的x字段值均为整型或者NULL,该函数返回整型值,否则就 返回浮点型数值。最后需要指出的是,如果所有的数据值均为整型,一旦结果超过上限时将会抛出"integer overflow"的异常。total(x)该函数不属于标准SQL,其功能和sum基本相同,只是计算结果比sum更为合理。比如当所有字段值均为NULL时,和sum不同的是,该函数返回0.0。再有就是该函数始终返回浮点型数值。该函数始终都不会抛出异常。二、核心函数:    以下函数均为SQLite缺省提供的内置函数,其声明和描述见如下列表:函数说明abs(X)该函数返回数值参数X的绝对值,如果X为NULL,则返回NULL,如果X为不能转换成数值的字符串,则返回0,如果X值超出Integer的上限,则抛出"Integer Overflow"的异常。changes()该函数返回最近执行的INSERT、UPDATE和DELETE语句所影响的数据行数。我们也可以通过执行C/C++函数sqlite3_changes()得到相同的结果。coalesce(X,Y,...)返回函数参数中第一个非NULL的参数,如果参数都是NULL,则返回NULL。该函数至少2个参数。ifnull(X,Y)该函数等同于两个参数的coalesce()函数,即返回第一个不为NULL的函数参数,如果两个均为NULL,则返回NULL。length(X) 如果参数X为字符串,则返回字符的数量,如果为数值,则返回该参数的字符串表示形式的长度,如果为NULL,则返回NULL。lower(X)返回函数参数X的小写形式,缺省情况下,该函数只能应用于ASCII字符。ltrim(X[,Y])  如果没有可选参数Y,该函数将移除参数X左侧的所有空格符。如果有参数Y,则移除X左侧的任意在Y中出现的字符。最后返回移除后的字符串。max(X,Y,...)返回函数参数中的最大值,如果有任何一个参数为NULL,则返回NULLmin(X,Y,...)返回函数参数中的最小值,如果有任何一个参数为NULL,则返回NULL。三、日期和时间函数:    SQLite主要支持以下四种与日期和时间相关的函数,如:    1). date(timestring, modifier, modifier, ...)    2). time(timestring, modifier, modifier, ...)    3). datetime(timestring, modifier, modifier, ...)    4). strftime(format, timestring, modifier, modifier, ...)    以上所有四个函数都接受一个时间字符串作为参数,其后再跟有0个或多个修改符。其中strftime()函数还接受一个格式字符串作为其第一个参数。strftime()和C运行时库中的同名函数完全相同。至于其他三个函数,date函数的缺省格式为:"YYYY-MM-DD",time函数的缺省格式为:"HH:MM:SS",datetime函数的缺省格式为:"YYYY-MM-DD HH:MM:SS"。      1. strftime函数的格式信息:格式说明%dday of month: 00%ffractional seconds: SS.SSS%Hhour: 00-24%jday of year: 001-366%JJulian day number%mmonth: 01-12%Mminute: 00-59%sseconds since 1970-01-01%Sseconds: 00-59需要额外指出的是,其余三个时间函数均可用strftime来表示,如:需要额外指出的是,其余三个时间函数均可用strftime来表示,如:    date(...)         strftime('%Y-%m-%d', ...)    time(...)         strftime('%H:%M:%S', ...)    datetime(...)   strftime('%Y-%m-%d %H:%M:%S', ...) 2. 时间字符串的格式:    见如下列表:    1). YYYY-MM-DD    2). YYYY-MM-DD HH:MM    3). YYYY-MM-DD HH:MM:SS    4). YYYY-MM-DD HH:MM:SS.SSS    5). HH:MM    6). HH:MM:SS    7). HH:MM:SS.SSS    8). now    5)到7)中只是包含了时间部分,SQLite将假设日期为2000-01-01。8)表示当前时间。      3. 修改符:    见如下列表:    1). NNN days    2). NNN hours    3). NNN minutes    4). NNN.NNNN seconds    5). NNN months    6). NNN years    7). start of month    8). start of year    9). start of day    10).weekday N        1)到6)将只是简单的加减指定数量的日期或时间值,如果NNN的值为负数,则减,否则加。7)到9)则将时间串中的指定日期部分设置到当前月、年或日的开始。10)则将日期前进到下一个星期N,其中星期日为0。注:修改符的顺序极为重要,SQLite将会按照从左到右的顺序依次执行修改符。       4. 示例:    --返回当前日期。    sqlite> SELECT date('now');      2012-01-15        --返回当前月的最后一天。    sqlite> SELECT date('now','start of month','1 month','-1 day');    2012-01-31    --返回从1970-01-01 00:00:00到当前时间所流经的秒数。    sqlite> SELECT strftime('%s','now');    1326641166        --返回当前年中10月份的第一个星期二是日期。    sqlite> SELECT date('now','start of year','+9 months','weekday 2');    2012-10-02
总条数:26 到第
上滑加载中