SQLite中的高级SQL

来源:互联网 发布:手机淘宝全屏海报尺寸 编辑:程序博客网 时间:2024/06/06 02:22

插入记录

使用insert插入记录。insert在表单上工作,使用insert命令可以一次插入一条记录,使用select命令可以一次插入多条记录。insert语句的一般格式为:

[sql] view plain copy
print?
  1. insert into table(column list) values(value_list);  

例如:

[sql] view plain copy
print?
  1. insert into foods (name, type_id) values ('Cinnamon Bobka', 1);  

如果在insert语句中为表的所有字段提供值,可以省略字段列表。例如:

[sql] view plain copy
print?
  1. sqlite> insert into foods values (NULL, 1, 'Blueberry Bobka');  

插入一组行

子查询可以用在insert语句中,既可以作为值列表的一部分,也可以完全替代整个值列表。

[sql] view plain copy
print?
  1. sqlite> insert into foods  
  2.    ...> select last_insert_rowid()+1, type_id, name from foods  
  3.    ...> where name = 'Chocolate Bobka';  
  4. sqlite> select * from foods where name like '%Bobka';  
  5. id          type_id     name             
  6. ----------  ----------  ---------------  
  7. 10          1           Chocolate Bobka  
  8. 13          1           Cinnamon Bobka   
  9. 413         1           Cinnamon Bobka   
  10. 414         1           Blueberry Bobka  
  11. 415         1           Chocolate Bobka  

插入多行

使用select形式的insert可以一次插入多行,例如:

[sql] view plain copy
print?
  1. sqlite> create table foods2 (id int, type_id intname text);  
  2. sqlite> insert into foods2 select * from foods;  
  3. sqlite> select count(*) from foods2;  
  4. count(*)    
  5. ----------  
  6. 415         
上述语句表示创建一个新表foods,并插入表foods的所有记录。

还有另一种形式:

[sql] view plain copy
print?
  1. sqlite> create table foods3 as select * from foods;  

create table与从foods表选择数据插入表两步并为一步。这对创建临时表特别有用:

[sql] view plain copy
print?
  1. sqlite> select f.name food, t.name name,  
  2.    ...> (select count(episode_id) from foods_episodes where food_id = f.id) episodes  
  3.    ...> from foods f, food_types t  
  4.    ...> where f.type_id = t.id;  

更新记录

update命令用于更新表中的记录,update语句的一般格式为:

[sql] view plain copy
print?
  1. update table set update_list where predicate  

例如:

[sql] view plain copy
print?
  1. sqlite> insert into foods values (415, 1, 'Chocolate Bobka');  
  2. Error: UNIQUE constraint failed: foods.id  
  3. sqlite> update foods set name = 'CHOCOLATE BOBKA'  
  4.    ...> where name = 'Chocolate Bobka';  
  5. sqlite> select * from foods where name like 'CHOCOLATE%';  
  6. id          type_id     name             
  7. ----------  ----------  ---------------  
  8. 10          1           CHOCOLATE BOBKA  
  9. 11          1           Chocolate Eclai  
  10. 12          1           Chocolate Cream  
  11. 222         9           Chocolates, box  
  12. 223         9           Chocolate Chip   
  13. 224         9           Chocolate Cover  
  14. 415         1           CHOCOLATE BOBKA  

删除记录

使用delete命令可以删除表中的记录。一般格式为:

[sql] view plain copy
print?
  1. delete from table where predicate  

实体完整性

数据库的所有域都是唯一的、可以定位的。域要可寻址,它相应的行必须是可以寻址的。因此,行必须在某种方式是唯一的。这就是主键的功能。

主键由至少带有unique约束的一个或一组字段组成。

唯一性约束

唯一性(unique)约束是主键的基础。

[sql] view plain copy
print?
  1. sqlite> create table contacts (  
  2.    ...> id integer primary key,  
  3.    ...> name text not null collate nocase,  
  4.    ...> phone text not null default 'UNKNOWN',  
  5.    ...> unique (name, phone));  
  6. sqlite> insert into contacts (name,phone) values ('Jerry''UNKNOWN');  
  7. sqlite> insert into contacts (namevalues ('Jerry');  
  8. Error: UNIQUE constraint failed: contacts.name, contacts.phone  
  9. sqlite> insert into contacts (name, phone) values ('Jerry''555-1212');  
在contacts表中,对name和phone的联合有唯一性约束。字段值的联合必须是唯一的。

NULL和UNIQUE:注意NULL不等于任何值,甚至不等于其他NULL.理论上,您可以放入任意多个NULL。

主键约束

在SQLite中,不管你有没有定义主键,都有一个64-bit整型字段,称为rowid。它还有两个别名——_rowid_和oid。SQLite为主键字段提供自动增长特性。如果定义字段类型为integer primary key,SQLite将为该字段创建默认值,该默认值确保整数值是唯一的。实际上,该字段就是rowid的别名。

新创建的rowid不一定是按照严格顺序增长的。如果想要SQLite使用唯一的自动主键值,可以加入关键值autoincrement。

[sql] view plain copy
print?
  1. sqlite> select rowid,oid,_rowid_,id,name, phone from contacts;  
  2. id          id          id          id          name        phone       
  3. ----------  ----------  ----------  ----------  ----------  ----------  
  4. 1           1           1           1           Jerry       UNKNOWN     
  5. 2           2           2           2           Jerry       555-1212    

域完整性

默认值

default为字段提供一个默认值。例如,contacts的name字段默认值为'UNKNOWN'。

default还可以接受3中预定义格式的ANSI/ISO保留字,用于生产日期和时间值。current_time格式为(HH:MM:SS),current_date格式为(YYYY-MM-DD),current_timestamp会生成一个日期时间的组合,格式为(YYYY-MM-DD HH:MM:SS).例如:

[sql] view plain copy
print?
  1. sqlite> create table times (id int,  
  2.    ...> date not null default current_date,  
  3.    ...> time not null default current_time,  
  4.    ...> timestamp not null default current_timestamp);  
  5. sqlite> insert into times (id) values (1);  
  6. sqlite> insert into times (id) values (2);  
  7. sqlite> select * from times;  
  8. id          date        time        timestamp            
  9. ----------  ----------  ----------  -------------------  
  10. 1           2015-01-25  09:10:01    2015-01-25 09:10:01  
  11. 2           2015-01-25  09:10:16    2015-01-25 09:10:16  

NOT NULL约束

NOT NULL约束可以确保字段部位NULL.


check约束

check约束允许定义表达式来测试要插入或者更新的字段值。例如,check约束可能确保电话号码字段的值至少是7位字符长度。

[sql] view plain copy
print?
  1. sqlite> create table contacts2  
  2.    ...> (id integer primary key,  
  3.    ...> name text not null collate nocase,  
  4.    ...> phone text not null default 'UNKNOWN',  
  5.    ...> unique(name, phone),  
  6.    ...> check (length(phone) >=7));  

外键约束

SQLite支持关系理论中的关系完整性概念。关系完整性也叫外键,它确保了一个表中的关键值必须从另一个表中引用,且该数据必须在另一个表中实际存在。经典的例子就是父子关系、主从关系。SQLite支持在创建表时使用外键,可以使用如下语法:

[sql] view plain copy
print?
  1. create table table_name  
  2. (column_definition references foreign_table (column_name)   
  3. on {delete|update} integrity_action   
  4. [not] deferrable [initially {deferred|immediate},] ...);   

例如,foods表和food_types表当前的定义如下:

[sql] view plain copy
print?
  1. CREATE TABLE foods(  
  2.   id integer primary key,  
  3.   type_id integer,  
  4.   name text );  
[sql] view plain copy
print?
  1. CREATE TABLE food_types(  
  2.   id integer primary key,  
  3.   name text );  

可以看出foods表使用了type_id字段,引用自表food_types。如果想要引用完整性确保SQLite保护您的数据,确保foods表的type_id值都存在于food_types的id字段,可以使用如下方式定义foods表:

[sql] view plain copy
print?
  1. sqlite> create table foods(  
  2.    ...> id integer primary key,  
  3.    ...> type_id integer references food_types(id)  
  4.    ...> on delete restrict  
  5.    ...> deferrable initially deferred,  
  6.    ...> name text);  

type_id引用自表food_types的id字段。使用了delete restrict, 该命令告诉SQLite阻止任何这样的删除行为,如果从表food_types中删除某行,将导致foods表的id没有父id的存在。完整的规则定义如下:

  • set null:如果父值被删除或者不存在了,剩余的子值将该为null
  • set default:如果父值被删除或者不存在了,剩余的子值修改为默认值
  • cascade:更新父值时,更新所有匹配的子值。删除父值时,删除所有的子值。要特别注意该选项,cascade的删除功能可能会出现意想不到的效果
  • restrict:更新或者删除父值可能会出现孤立的子值,从而阻止(终止)事物。
  • no action:使用一种松弛的方法,不干涉操作执行,只是观察变化。在整个语句(如果约束定义为deferred的事物也一样)的结尾报出错误。
SQLite支持deferrable子句,该子句控制定义的约束是立即强制实施还是延迟到整个事务结束时。


排序规则

排序规则涉及文本值如何比较。三种排序规则:

  • memcmp()逐字比较文本值
  • nocase:非大小写敏感排序算法
  • reverse:与二进制排序规则相反。reverse更多地用来测试。

存储类

SQLite有5个原始的数据类型。integer,real,text,blob,NULL。SQLite函数typeof()根据值的表示法返回其存储类。

[sql] view plain copy
print?
  1. sqlite> select typeof(3.14), typeof('3.14'),typeof(314), typeof(x'3142'),typeof(NULL);  
  2. typeof(3.14)  typeof('3.14')  typeof(314)  typeof(x'3142')  typeof(NULL)  
  3. ------------  --------------  -----------  ---------------  ------------  
  4. real          text            integer      blob             null          

视图

视图即虚拟表,也称为派生表,因为它们的内容都派生自其他表的查询结果。虽然视图看起来感觉就像基本表一样,但是它们不是基本表。基本表的内容是持久的,而视图的内容是在使用时动态产生的。创建视图的语法如下:

[sql] view plain copy
print?
  1. create view name as select-stmt;  
[sql] view plain copy
print?
  1. sqlite> create view details as  
  2.    ...> select f.name as fd, ft.name as tp, e.name as ep, e.season as ssn  
  3.    ...> from foods f  
  4.    ...> inner join food_types ft on f.type_id = ft.id  
  5.    ...> inner join foods_episodes fe on f.id = fe.food_id  
  6.    ...> inner join episodes e on fe.episodes_id = e.id;  

使用drop view删除视图

[sql] view plain copy
print?
  1. drop view name;  


索引

索引是一种用来在某种条件下加速查询的结构。创建索引的命令如下:

[sql] view plain copy
print?
  1. create index [unique] index_name on table_name (columns)  

如果使用关键字unique,将会在索引上添加约束,索引中的所有值必须是唯一的。这不仅适用于索引,也适用于索引所在字段。unqiue关键字覆盖index中的所有字段,不管是联合值还是单个值:

[sql] view plain copy
print?
  1. sqlite> create table foo (a text, b text);  
  2. sqlite> create unique index foo_idx on foo(a, b);  
  3. sqlite> insert into foo values ('unique''value');  
  4. sqlite> insert into foo values ('unique''value');  
  5. Error: UNIQUE constraint failed: foo.a, foo.b  

若要删除索引,可使用drop index命令

[sql] view plain copy
print?
  1. drop index index_name;  

排序规则

索引中的每个字段都有相关的排序规则。例如,要在foods.name上创建大小写不敏感的索引,可以使用如下命令:

[sql] view plain copy
print?
  1. create index foods_name_idx on foods (name collate nocase);  

.indices列出表中索引。也可以使用.schema命令查看更多的信息。


触发器

当具体的表发生特定的数据库事件时,触发器执行对应的SQL命令。命令格式如下:

[sql] view plain copy
print?
  1. create [temp|temporarytrigger name [before|after] [insert|delete|update|update of colums] on table action  
可以通过关键字before或after来制定这些操作是在事件发生前还是发生后执行。事件包括在具体的表中执行的delete、insert和update命令。

更新触发器

与insert和delete触发器不同,update触发器可以在表的执行字段上定义,这种触发器的一般格式如下:

[sql] view plain copy
print?
  1. create trigger name [before|afterupdate of column on table action  


事物

事务由3个命令控制:begin、commit和rollback.begin开始一个事务,begin之后的所有操作都可以取消,如果连接终止前没有发出commit,也会被取消。commit提交事物开始后所执行的所有操作。类似地,rollback还原begin之后的所有操作。例如:

[sql] view plain copy
print?
  1. sqlite> begin;  
  2. sqlite> delete from foods;  
  3. sqlite> rollback;  
  4. sqlite> select count(*) from foods;  

原创粉丝点击