第1章SQL语言基础与数据库的安装本章首先将介绍如何从数据库的表中提取、统计数据,这部分内容是我们在数据库应用开发和管理中使用到最多的内容也是我们学习下面内容的基础。数据维护语句(DML)部分介绍如何对表中的数据进行增、删、改。从而达到更改数据库表中值的目的,这些语句分别是INSERT,DELETE,UPDATE数据库为了保证业务的原子性,使用了事务的概念也将在这部分介绍。数据定义语句(DDL)主要用来建立及维护数据库对象,通过这部分的学习掌握如何建立数据库对象包括表、索引、视图等。数据控制语句(DCL)主要介绍如何建立及维护用户,并保证数据库的安全性,防止数据库中的数据被非法用户访问。包括数据库用户的建立,数据库对象的赋权,权限的回收等。本章中所有的语句都是基于ORACLE数据库自带的例子程序HR数据库来完成的,关于相关表的定义的详细说明可以参考附件Ⅳ中的内容。本章由以下内容组成:查询语句的使用数据操纵语句的使用(DML)数据定义语句的使用(DDL)数据控制语句的使用(DCL)1.1查询语句的使用本节主要包含了以下内容:单表数据的查询查询处理时用到的函数表查询分组查询1.1.1单表查询表是数据库中数据存储的逻辑单元,我们所需要得到的数据是从数据库中的表里得到的,因此对单一表的数据的查询是学习SQL语句更复杂功能的基础。在这一章里,首先介绍单表查询这个最基本SQL语句的语法,然后对这个语法的各种情况将举例描述。SELECT*|{[DISTINCT]column|expression[alias],………}FROMtable[WHEREcondition(s)][ORDERBY{column,expr,alias}[ASC|DESC]];语法3-1SELECT与FROM之间可以是表中的列,也可以是表达式,包括算术表达式、字符串、常数、函数等。(字符串用单引号定界)下面我们举例子说明这个语法每一项参数的具体意义。在本书的介绍语法的内容中使用的符号:[]代表该内容可选|竖线代表在几项内容中可以选择一项黑体的都是关键字,分别代表不同的功能。例1SELECT中的*指提取该表中的所有字段。SELECT*FROMemployees;说明:从员工信息表中提取所有数据(取所有字段)。例2SELECT中的column是指表的列。SELECTfirst_name,phone_numberFROMemployees;说明:从员工信息中提取员工姓名和联系电话(取字段COLUMN).例3SELECT中的expression是指一个表达式。SELECTsysdateCURRENTDATEFROMdual;说明:取一个表达式,该表达式可以是计算公式,该语句中的Dual是一个系统表,只有一条数据,用来满足只需一条数据的查询需求(例如上面例子中的计算一个值)。例4SELECT中的[alias]是为列或者表达式取的别名。SELECTsysdateCURRENTDATEFROMdual;说明:别名的目的是为了使提取的数据每一列有对应的名称,从而便于识别。本例提取当前的时间,为该字段的赋予的名称是“CURRENTDATE”从而使输出的数据更有实际意义,其中SYSDATE是一个函数,作用是得到系统当前时间。如果别名中间有空格或者别名中需要区分大小写则该别名需要使用两个双引号将其包含。例5SELECT中的[WHEREcondition(s)]为该数据提取语句设定条件。SELECTfirst_name,last_name,emailFROMemployeesWHEREemployee_id='123';说明:从用户信息中提取用户名称,邮件地址,提取条件为员工号是‘123’例6SELECT中的[ORDERBY]为提取的数据按照指定的列排序。SELECTfirst_name,emailFROMemployeesORDERBYlast_name;说明:从员工信息中提取员工名称、邮箱地址,按照姓排序,缺省的情况下是升序排列。例7SELECT中的[ASC|DESC]为该数据提取语句设定排序方式。SELECTfirst_name,emailFROMemployeesORDERBYlast_namedesc;说明:从员工信息中提取员工名称、邮箱地址、按照姓降序排列。也可以是对一个语句中的多个列进行排序,对每个列后面都可以增加升降序的选项。同时排序的列可以不用出现在选择列当中。例8SELECT中的DISTINCT是指对提取的数据进行压缩显示。SELECTDISTINCTsalaryFROMemployeesWHEREjob_id='IT_PROG';说明:提取工作职位是‘IT_PROG的所用员工的不同的工资数额。如果没有DISTINCT语句,则可能会提取出来大量的重复的数据。WHERE子句中的condition(s)是用来设定常用的查询条件这些条件主要有:条件说明=,,,=,=,!=,,!,!;NOT比较运算符BETWEENAND,NOTBETWEENAND范围运算符IN,NOTIN集合运算符LIKE,NOTLIKE字符匹配ISNULL,ISNOTNULL空值运算AND,OR多重条件例9在CONDITION子句中使用范围运算符:SELECTlast_name,phone_numberFROMemployeesWHEREemployee_idBETWEEN1AND150;说明:相当于使用大于等于某数并且小于等于某数。等同于=与=的结合使用。例10AND与OR的使用及使用括号来解决优先级别的问题。SELECTfirst_name,last_name,salaryFROMemployeesWHEREjob_id='IT_PROG'AND(hire_dateto_date('20050101','yyyymmdd')ORsalary5000);说明:提取员工信息中工作岗位是‘IT_PROG’并且入公司时间晚于2005年或者目前的薪资少于5000元的员工的姓名和目前的工资水平。注意当查询条件涉及到多个时,可以用逻辑运算符AND和OR来关联多个查询条件,其优先级顺序与其它开发语言相同,AND的优先级高于OR但是用户可以用括号改变优先级。例11使用IN运算符。SELECT*FROMdepartmentsWHEREdepartment_idIN(10,20,30);说明:IN谓词实际上是多个OR运算的缩写。例12表中字段别名的使用。SELECTlast_nameMyname,department_id,salaryFROMemployeesORDERBYMyname,department_id;说明:ORDERBY后面可以使用字段别名的方式,可以使用多个字段进行排序。例13空值的使用。SELECT*FROMemployeesWHEREcommission_pctISNOTNULL;说明:涉及空值条件查询时必须使用ISNULL,ISNOTNULL来判断,这里的IS不能用=替代。空值不能等同于0或者空格。排序时空值总是比任何值大。空值与其它数值的运算结果仍然是空值。例14使用LIKE时%与_的用法。SELECTfirst_name,last_name,salaryFROMemployeesWHEREphone_numberLIKE'01%'ANDlast_nameLIKE'_a___'ORDERBYsalary;说明:从员工信息中提取用户名称和薪水,提取条件为电话号码是01开头的号码并且员工名称第2位是a的员工,在使用%时,注意%在前面与%在后面时所代表的不同的意义,另外WHERE条件中的字符类型和时间类型的数据必须使用单引号包含,并且WHERE条件中的字符类型是大小写敏感的。例15LIKE的条件中有关键字时的处理方法。SELECTemployee_id,last_name,job_idFROMemployeesWHEREjob_idLIKE'%SA\_%'ESCAPE'\';说明:如果在LIKE的内容中包含了_或者%则使用ESCAPE关键词。1.1.2函数在上面的SQL语法中,无论是对列还是对表达式,都可以使用SQL函数,这些函数在不同的数据库厂家产品中的名称、用法、参数可能是不同的,ORACLE中函数的用法为:Function_name[(arg1,arg2,…………)]语法3-2根据调用函数时的输入数据是一行还是多行,SQL函数可以分为单行函数和多行函数。单行函数处理每一行并对该行产生一条结果数据例如函数LOWER.多行函数按组处理多条数据,一般每一组产生一条数据例如函数MAX.多行函数一般用于分组运算中。如下图所示:图3-1我们在下面的章节中首先介绍单行函数,单行函数按照其处理的数据类型不同,可以分为5类1.字符类2.数值类3.日期时间类4.数值转换类5.其它。在下面分别进行介绍。函数名称函数说名字符串函数LOWER(COL|EXP)将列或者表达式取小写UPPER(COL|EXP)将列或者表达式取大写INITCAP(COL|EXP)将列或者表达式第一个字母大写FFuunnccttiioonnssSSiinnggllee--rroowwffuunnccttiioonnssMMuullttiippllee--rroowwffuunnccttiioonnssCONCAT(COL|EXP,COL|EXP)连接两个字符串作用相当于符号’||’SUBSTR(COL|EXP,m,n)从一字符串(列值)中得到始于M结于N的子串LENGTH(COL|EXP)得到列值或表达式的长度INISTR(COL|EXP,’string’,[m],[n])得到一个’string’子串在列值或表达式中的位置LPAD(COL|EXP,N,’string’)在列值或表达式的左边补’string’字母RPAD(COL|EXP,N,’string’)在列值或表达式的右边补’string’字母TRIM(leading|trailing|bothtrim_characterFROMtrim_source)去掉’trim_source’中头(leading)或尾(trailing)的trim_character字母REPLACE(text,serch_string,replacement_string)将字符串中的serch_string子串替换成为replacement_string子串数值函数ROUND(col|exp,n)对列值或表达式的值进行四舍五入Trunc(col|exp,n)对列值或表达式的值舍去Mod(m,n)对列值或表达式的值取余日期函数MONTHS_BETWEEN(d1,d2)两个日期之间的月数ADD_MONTHS(d1,n)向D1日期加上月份nD1-d2,d1+n,d1+n2个日期相减得到中间的天数,日期加减天数LAST_DAY(d1)指定时间所属月的最后一天ROUND(D1,fmt)将给定时间在指定的时间范围内进行四舍五入TRUNC(D1,fmt)将给定时间在指定的时间范围内进行取整转换函数to_char(number|date,[fmt])将数值型、日期型的数据类型转换成为字符类型,参数中的fmt为转换格式,将在下面介绍to_number(char,[fmt])将字符型转化为数字型to_date(char,[fmt])将字符型转化为日期型其它函数NVL(EXPR1,EXPR2)如果EXPR1为空值,则返回值为EXPR2NVL2(EXPR1,EXPR2,EXPR3)如果exp1非空返回exp2,否则返回exp3NULLIF(EXPR1,EXPR2)如果exp1=exp2返回NULL否则返回exp1DECODE(COL/EXPR,SERCH1,RESULT1,[serch2,result2],[default])可以实现IF-TEN-ELSE的功能,如果字段值或表达式的值等于SERCH1则返回RESULT1,否则判断是否等于SER2,都不相等返回DEFALUT例1字符串函数的应用。SE