Android SQLite 数据库探索(三)— SQLite 中的 SQL 语句(下)

5. 更新数据 — update

update 语句用与更新表中的数据,它的格式为:

update table set update_list where predicate ;

update_list 是要修改的字段以及值,形式为:字段名 = 新值,每个字段赋值语句通过逗号分隔开。

例如:将 name 为 Jerry 的学生的电话改为 4321,cls_id 改为 3。

update students set tel_no = 4321, cls_id = 3 where name = 'Jerry' ;

6. 删除数据 — delete

delete 语句的通用格式如下:

delete from 表名 where predicate;

如果没有设定 where 条件,那么表中的所有数据都会被清空。

delete from students;

delete from students where cls_id = 2;

7. 修改表

SQLite 中的 alter 命令并没有实现标准 SQL 中的所有功能,它只有修改表名和添加字段两个功能,删除字段只能通过重新创建新表来实现。

alter 的语法如下:

alter table 表名 { rename to newname | add column 新的字段名 };

alter table 之后是要操作的表名,然后在 rename to 和 add column 命令之间二选一。rename to 是将表名重命名,add column 是添加字段。

例如,要将 students 表重命名为 stu_table:

alter table students rename to stu_name;

若要在 students 表中添加一个代表年龄的 age 字段:

alter table students add column age integer default 0;

若想要删除 age 这个字段,就比较麻烦了,需要创建一个新表,然后将 students 表中数据导入到新表,最后删除 students 表,然后再将新表命名为 students 表。例如:

create table stu_temp (
id integer primary key autoincrement,
name vachar(20) check(length(name) > 3),
tel_no varchar(11) not null,
cls_id integer not null
);

insert into stu_temp select id, name, tel_no, cls_id from students;

drop table students;

alter table stu_temp rename to students;

8. 创建索引

索引是用于加速查询的结构。索引就像是一本书前面的目录,它能够为指定的列创建一个索引表,每个索引指向特定的记录,这样就能加快数据库的查询速度。默认情况下,当我们按照指定的条件查询表中的数据时会扫描所有的行来找到匹配的数据。数据量比较大的时候,如果这个查询被使用的频率比较高,就可以为这个查询条件指定的列创建索引。

创建索引的语法为:

create index [unique] index_name on table_name (column_list)

index_name 代表索引名,table_name 表示要在哪个表上创建索引。如果指定了 unique 关键字,那么该索引中的所有字段值必须是唯一的。

下面为 students 中的 name 创建索引:

create index stu_name_index on students (name collate nocase);

collate nocase 代表排序规则与大小写无关。

使用索引能够增加查询速度,但是它也会增加数据库的体积,并且会减慢 insert、update、delete 操作。因此,要谨慎使用索引。

我们不是在索引上操作,我们操作的仍是表,当我们操作表时,SQLite 会根据条件来选择是否使用索引。当查询条件与索引的字段相等时,数据库则使用索引来加速;如果有多个索引字段,那么出现第一个不相等的逻辑之后,后续的字段就不会使用索引。下面举个例子来理解一下:

// 为 test 表的 a,b,c 字段创建索引
create index test_index on test (a, b, c);

// 只有 a 会使用索引,c 则不会,因为他们中间的 b 索引断了。
select * from test where a = 1 and c = 3;

// 此时只有 a,b 会使用索引,因为 b 的条件为大于,
// 所以后续的字段将不使用索引。当 b 的条件为等于时,a,b,c
// 三个字段才会都使用索引。
select * from test where a = 1 and b > 1 and c = 3;

9. 创建视图

视图是动态生成的虚拟表,它不会被存储到数据库文件中。它常用来将某些查询结果简化为一个视图,主要用于简化 SQL 语句。

创建视图的语法:

create view view_name as select-stmt;

view_name 为视图名,select-stmt 是该视图代表的 select 语句,当我们使用这个虚拟表时,就相当于执行了这条 select-stmt。
例如,需要经常使用如下 SQL 语句:

select * from students, classes where students.cls_id = classes.id 
and cls_id > 2;

为这条查询创建一个视图:

create view student_view as 
select * from students, classes 
where students.cls_id = classes.id and cls_id > 2;

然后通过这个视图来查询数据:

select * from student_view;

使用视图能够方便查询条件复杂的 SQL 语句。因为它是动态生成的虚拟表,因此,在视图上执行除了 select 之外的语句是无效的。

10. 创建触发器

触发器的作用是当特定的表发生特定的操作时进行预定义的操作。
创建触发器的一般命令为:

create [temp | temporary] trigger trigger_name 
[before | after] [insert | select | delete | update] on table
begin
action;
end;

名称、表名、行为是触发器的三大要素。

下面举个例子,当删除学生时向 delete_log 表中添加一条记录。

// 首先创建 delete_log 表
create table delete_log (
stu_id int not null,
stu_name text not null,
time text
);

// 创建 delete_trig 触发器
// 学生 id,名字分别用 old.id,old.name 表示
create trigger delete_trig after delete
on students
begin
insert into delete_log(stu_id, stu_name, time) 
values (old.id, old.name, datetime('now'));
end;

下面再来看另一个例子,当向 students 表中插入一条数据时,向 new_log 表中插入一条记录。

// 将 delete_log 表重命名为 new_log
alter table delete_log rename to new_log;


// 创建 new_trig 触发器
// 学生 id,名字分别用 new.id,new.name 表示
create trigger new_trig after insert
on students
begin
insert into new_log(stu_id, stu_name, time) 
values (new.id, new.name, datetime('now'));
end;

需要注意的是,插入时新纪录使用 new,而删除时则使用 old。

11. drop 命令

drop 命令用来删除物理存储介质。例如删除表、视图、索引、触发器等。

命令格式为:

drop [table | view | index | trigger] name;

例如删除 students 表:

drop table students;

12. 数据库事务

事务是一个数据库操作的执行单元。这些语句要么全部被执行,要么全部不执行。很大程度保证了数据库操作的安全性。在 Android 中使用事务,也会提高 SQL 的执行效率。

事务有 begin(开始一个事务)、commit(表示整个事务操作成功)、rollback(回滚到 begin 之前)。格式为:

begin;
// sql 语句
[commit | rollback];

下面来看一个示例:

begin;
delete from students where cls_id = 2;
rollback;

上述 SQL 中,我们删除了 cls_id = 2 的数据,然后又回滚,因此,delete 语句没有执行。换成 commit 就会。

你可能感兴趣的:(Android SQLite 数据库探索(三)— SQLite 中的 SQL 语句(下))