1、DML(数据操纵语言)即增删改查,对于我们JAVA程序员来说,最频繁做的就是利用数据库做数据的统计和分析以及持久化,这些行为都是以DML作为基础,并且在实际项目中,80%以上的业务就是以增删改查作为基础(注意只是基础),因此本章内容非常重要。Select:查询 insert:添加 update:修改 delete:删除。
2、添加数据:
语法:insert into 表名 (列名列表) values (值列表);
多个列和多个值之间要用逗号分隔开 插入的值和被插入的列必须一一对应相匹配,关于匹配代表着顺序匹配和类型匹配,需要注意的是当类型不匹配的时候很多RDBMS会自动尝试。调用内部的一些函数(如oracle的to_number to_char)帮助开发者做正确的类型转换,比如如果在int类型这列上插入类似“22”的字符串,是能够被转换为整数22的,但是一旦出现想要将类似“abc”转化为整数的情况则会出错,因此我们通常情况下都避免让DBMS帮我们转换,要做到插入的值和列的类型完全匹配。
对于sqlserver来说,timestamp(时间戳)类型的列会被DBMS自动插入值,对于插入的语法,大部分情况下,如果我们需要向表的每一列都插入数据,并且也对表的结构掌握的很清楚时(知道有几列,每列的类型是什么),我们可以简化插入的语法,不需要指定要插入的列名:语法:insert into table 表名values(值列表); 注意插入的值的个数与类型必须和被插入列相匹配。
SQL不允许使用常量值一次添加多行。但是SQL允许使用从一个嵌入的SELECT查询中获取的值,来一次向表中添加多行,也就是将1张表的多条记录查询出来后1次性的插入另外一张表。语法:INSERT INTO 要插入的表名 [列名列表] SELECT *或列名列表 FROM 数据来源的表名; 注意不能有values关键字,插入的值的个数和类型必须和被插入的列相匹配。
2、修改数据:
和插入数据不一样,修改数据,如果要指定修改某列或某几列时 需要指定一个条件才能操作;
语法:update 表名 set 列名=? [where 条件];
如果不加条件的话,则会对整张表进行指定列的修改;需要注意的是,对于NULL值,我们使用where xx is null而不是where xx = null 不等于的话用is not,Where条件后也可以使用其他任意的逻辑运算符 > ,< ,=, !=,or,and,between,in。
事务即代表一段时间内的某个操作或者几个操作要么全部成功,要么全部失败,Sql2005标准所定义的TCL事务控制语句有commit,rollback,savepoint ,sqlserver支持commit和rollback,分别代表提交和回滚;
在sqlserver中默认的事务是自动提交的,要打开事务,我们需要使用begin transaction语句;当我们使用begin transaction自动开启一个事务后,在这个事务中(即事务结束之前)的增删改语句所影响到的数据并不会被直接写入数据文件,而是先保在数据缓冲区里(即内存里),直到我们使用commit命令提交后才会写入到数据文件。
使用commit会提交当前事务,使用rollback则回滚当前事务至事务开始时的状态,在sqlservcer中必须在开启了事务之后结束事务之前才能使用这2个命令,它们都会结束当前被开启的事务。也就是说,实际项目中,我们的某些业务需要对数据库做多次操作,我们要保证多次操作全部成功才将数据写入硬盘上的数据文件,而其中一个不成功则判定为全部失败并回复到最开始的状态。
3、删除数据:
删除的语法和修改差不多: delete [from] 表名 [where 条件];
不加where条件的话,代表删除表中所有的数据,效果和truncate table是一样的,需要注意的是delete和truncate的区别,2者都能达到删除表中所有数据的效果,在放入事务中后2者都能回滚(实际上在大部分的RDBMS如oracle中DDL语句是会自动提交事务而不能回滚的 即对对象的create/alter/drop/truncate都会自动提交事务),唯一的区别是速度上truncate比delete快一点。
4、简单查询数据:
语法:select *或者列名列表 from 表名 [where [筛选条件列表] order by 列名];
针对student表,要查询所有列的话select *和select s_id,s_name,s_age在结果上都是一样的,但是执行select *的时候RDBMS会检查表中列的名称和条数,因此性能消耗较大。实际项目中如果为了追求急致的性能的话,我们都会使用select 列名列表的形式查询所有列的信息,
除了直接通过对象.属性即表名.列名的形式引用列之外也可以给表取别名从而通过别名来引用,语法:select 列A as A,列B as B rom 表名 as T;注意不管是列别名还是表别名as都是可加可不加,而某些RDBMS如oracle的表别名不能加as,因此最好统一记忆都不加as。
我们查询返回的列不一定必须是表格中某列的值,可以通过一些计算得出,如:select name ‘n’,price ’p’,discount ’d’,(price*discount/10) ‘zk’ from 表名;
我们需要去除重复的价格记录可以使用distinct关键字: select distinct (列名) from 表;
不同的RDBMS,有不同的分页语句,mysql通过limit,oracle通过rownum伪列或row_number()函数,而sqlserver通过top关键字限制查询返回的行数;
分页查询的语法:select top 每页记录条数 *或列名列表 from 表名; 能够获得根据记录条数分页查询的第1页的数据。
带条件的查询参看之前的修改和删除语句,多个条件使用and(而且)/or(或者)来连接(类似JAVA的&&和||),其他逻辑运算符号>,<,=,!=,between,in参照之前的例子。
4、模糊查询:
我们做一些应用基本上都会有按关键字搜索功能,排除搜索引擎相关的知识如分词搜索等等,我们至少需要掌握如果在数据库中按关键字搜索,即模糊查询,like关键字+通配符;
语法:select 列A,列B from 表 where 列C like 模式;需要注意的是通配符%和_的区别:%表示的是0个或多个字符,而一个_表示的是一个字符,精度比%更高一些。
注意:sqlserver中模糊查询对大小写是不敏感的;模糊查询的表达式也会包含空格;通配符也是关键字,如果我们在模式中要将它们作为常规字符串使用的时候,要将其转义,sqlserver使用[]类似JAVA中的/;
4、排序操作:
语法:select 列A,列B from 表 order by 列A asc/desc;
我们在SQL中使用order by 列名 [asc/desc]能够对结果集合进行排序 asc表示升序,desc代表降序,不写排序方式的话,所有的RDBMS都默认为升序,我们可以在order by之后指定多列和多个排序方式来达到多次排序以满足复杂一点的业务需求。