书城计算机数据库原理及Oracle应用
18254100000009

第9章 Oracle数据库基础——SQL语言(4)

5.2.3.3 索引的删除

索引一经定义,就由系统使用和维护它,不需要用户干预。索引可以加快查询速度,但如果数据的增、删、改操作很频繁,系统会花许多时间来维护索引,导致系统开销增加。所以在适当的时候可以删除一些不必要的索引,或者先将索引删除,在插入、更新、删除操作完成后再重新建立索引。

1.删除索引的语法

DROP INDEX<索引名>;

删除索引时,系统会同时从数据字典中删除有关该索引的描述。删除索引不会影响表的使用,只会影响表的查询速度。不能修改索引,为了修改索引,必须首先删除索引,然后重新建立索引。只有索引的拥有者或拥有DROP ANY INDEX 权限的用户才能删除索引。

2.删除索引示例

例5-35 删除在emp表中定义的empename索引。

SQL>DROP INDEX empename;

5.3 Oracle SQL函数

Oracle提供了大量的函数在SQL或PL/SQL语句中调用,可大大地提高SQL语句的处理能力和灵活性。函数有零个或多个参数,并且返回单个值。函数的一般格式为:函数名(参数1,参数2……,参数n)。函数有两种类型:单行函数和组函数(也叫做聚组函数)。

单行函数只操作一行,并且每一行返回一个结果。单行函数从表中取出数据之前就知道要处理的参数个数。而聚组函数直到所有的数据从表中抽取出来并且组成一个分类时才知道要处理的参数个数。下面介绍各种单行函数、聚组函数的用法和使用规则。

5.3.1 单行函数

Oracle提供了许多种单行函数。根据函数值的数据类型可划分为:数值函数、字符函数、日期函数、转换函数、其他函数及程序员编写的存储函数。单行函数可以在SELECT语句的SELECT、WHERE、ORDER BY子句中使用。也可以出现在UPDATE语句的SET、WHERE子句中,还可以出现在INSERT 语句的VALUES子句中,或者在DELETE语句的WHERE子句中。

5.3.1.1 空值函数NVL

NULL值代表不知道的数据或者缺少数据。在一个NULL值上进行任何算术运算,结果都是NULL。NVL函数提供了对空值运算的正确操作方法。该函数也称空值函数:

各函数说明如下。

(1)CONCAT(<C1>,<C2>)

其中C1、C2是字符串。该函数将C2添加到C1后返回。假如C1是NULL,则返回C2。假如C2是NULL,则返回C1。假如C1、C2都是NULL,则返回NULL。CONCAT与联结运算符||返回相同的结果。

例5-37 将slobo和svoboda字符串拼接后输出。

SQL>SELECT CONCAT(′slobo′,′svoboda′)username FROM dual

(2)INSTR(<C1>,<C2>[,<I>[,<J>]])

其中C1、C2是字符串,而I、J是数字。该函数返回的是从C1的I位置开始搜索碰到第J次C2的位置。I表示在C1中开始搜索的位置,如果I是负数,则表示从右到左搜索,但位置仍然按从左到右计算的。J表示碰到第J次。I和J的默认值是1。

例5-38 返回mississipi字符串从第3个字符开始第3次出现字符i的位置。

SQL>SELECT INSTR(′mississippi′,′i′,3,3)FROM dual

返回结果是11。

例5-39 返回mississipi字符串从右边开始第3次出现字符i的位置。

SQL>SELECT INSTR(′mississippi′,′i′,-2,3)FROM dual

返回结果是2。

(3)LENGTH(〈C〉)

其中C是字符串,返回的是字符串C的长度。假如C是NULL,则返回NULL。

例5-40 返回字符串的长度。

SQL>SELECT LENGTH(′ipso facto′)ergo FROM dual

(4)LOWER(〈C〉)

其中C是字符串,返回的是字符串C的小写格式。此函数经常出现在WHERE子句中。

例5-41 查询emp表中ENAME等于小写的scott的雇员信息。

SQL>SELECT ename,job FROM emp WHERE LOWER(ename)′scott′

(5)SUBSTR(<C1>,<I>[,<J>])

其中C1是字符串,而I、J是整数。该函数返回C1字符串中从I位置开始长度为J的子串。假如J是负数,则位置从右到左计算。假如I是0或负数,则返回NULL。J的默认值是1。

例5-42 返回message字符串的前4位子串。

SQL>SELECT SUBSTR(′message′,1,4)sub FROM dual

(6)UPPER(<C>)

其中C是字符串。返回的是字符串C的大写格式。此函数经常出现在WHERE子句中。

例5-43 查询emp表中ename是以大写的KI开头的雇员信息。

SQL>SELECT ename,job,hiredate FROM emp

WHERE UPPER(ename)LIKE′KI%′;

5.3.1.3 单行数字函数

(1)ABS(<N>)

其中N是数字。此函数返回N的绝对值。

例5-44 返回-52和52的绝对值。

SQL>SELECT ABS(-52)negative,ABS(52)positive FROM dual;

(2)ROUND(〈N1〉,〈N2〉)

其中N1是数字,N2是整数。此函数返回N1的小数点右边按四舍五入截到N2位后的值。假如N2是负数,N1截到小数点左边。此函数类似TRUNC()。

例5-45 返回数字12345和12345.54321四舍五入后的结果。

SQL>SELECT ROUND(12345,-2),ROUND(12345.54321,2)FROM dual;

(3)SQRT(<N>)

其中N 是数字。此函数返回N的平方根。

例5-46 返回数字64和49的平方根。

SQL>SELECT SQRT(64),SQRT(49)FROM dual;

(4)TRUNC(<N1>,<N2>)

其中N1是数字,N2是整数。此函数对N1进行截断,截断到N1的小数点后面的N2位。假如N2是负数,N1截断到小数点的左边。

例5-47 返回数字123.456截断后的结果。

SQL>SELECT TRUNC(123.456,2)pos,TRUNC(123.456,-1)neg FROM dual;

5.3.1.4 单行日期函数

单行日期函数对日期型的数据进行运算。一般情况,日期函数有一个或多个日期型的参数,返回的结果多数是日期型的。日期可以进行算术运算,对日期进行加减运算,加减的单位是天。如果加减的单位不是天,必须将其进行换算,按一天24小时,一小时60分钟等进行换算。

date+number:表示给某一日期加多少天,返回的是日期。

date-number:表示给某一日期减多少天,返回的是日期。

date-date:表示两个日期相减,返回的是相差的天数。

date+number/24:表示给某一日期加多少小时,返回的是日期。

例5-48 查询每一个雇员的受雇日期,受雇日期的后7天,前7天的日期,以及当前系统日期与受雇日期之间相差的天数。

SQL>SELECT hiredate,hiredate+7 ADD,hiredate-7 SUBTRACT,

sysdate-hiredate DIFF

FROM emp

5.3.2 聚组函数

聚组函数返回的值是根据一组输入得到的,输入个数只有在执行完查询并且所有行都取出时才确定。这就是聚组函数与单行函数的区别,单行函数的输入个数在查询执行之前语法分析时就确定了。

类似单行函数,Oracle 提供了大量的聚组函数来完成一定的功能。这些函数可以出现在SELECT语句的SELECT子句或HAVING子句中。当在SELECT语句的SELECT子句中使用时,通常要求该语句带GROUP BY 子句。聚组函数的特点如下。

一般对一组行进行操作,而不是对单一行。每一组只给出一个结果,用于返回一组数据的汇总信息(求和、求平均值等)。

聚组函数的参数可以是数字型、字符型、日期型数据。

如果将单行函数和聚组函数一起使用,必须有相应的GROUP BY子句。

多数聚组函数可以使用DISTINCT和ALL选项:DISTINCT表示只考虑参数表达式的非重复值;ALL表示考虑包括重复值在内的参数表达式的所有值。默认值是ALL。

除了COUNT(*)以外的所有的聚组函数都忽略NULL值。通过使用NVL函数,可以用别的值替代NULL。

各函数说明如下。

(1)AVG([{DISTINCT|ALL}]<N>)

其中N是一个数字型的表达式。此函数返回表达式N的平均值。

例5-57 求出emp中所有雇员的总工资和平均工资。

SQL>SELECT SUM(sal),AVG(sal),AVG(distinct sal)FROM emp

(2)COUNT({*|[DISTINCT|ALL]<X>})

其中X是一个表达式。此函数返回查询中的行数。*号是特殊量,表示统计结果集中所有的行,不管是否是NULL。如果用表达式,则统计结果集中非空(NULL)的行。

例5-58 求出30号部门的人数,以及求出30号部门有奖金COMM的人数。

SQL>SELECT COUNT(*)FROM emp WHERE deptno30;

查询结果为6。

SQL>SELECT COUNT(comm)FROM emp WHERE deptno30;

查询结果为3。

(3)MAX([{DISTINCT|ALL}]<X>)

其中X是一个表达式。此函数返回表达式X的最高值。如果表达式是字符型,则返回VARCHAR2。如果表达式是日期型,则返回日期。如果表达式是数字型,则返回数字。对日期而言,最近的日期最大。对数字而言,最大的数最大。对字符串而言,基于数据库字符集中排序最高的最大。

例5-59 求出emp表中最高的工资和姓名,以及最低工资和姓名。

SQL>SELECT MAX(sal),MAX(ename),MIN(sal),MIN(ename)FROM emp;

(4)MIN([{DISTINCT|ALL}]<X>)

其中X是一个表达式。此函数返回表达式X的最小值。功能与MAX函数正好相反。

(5)SUM([{DISTINCT|ALL}]<X>)

其中X是一个数字表达式。此函数返回表达式X的和。

例5-60 求出emp表的总奖金comm

SQL>SELECT SUM(comm)FROM emp;

可以用GROUP BY 聚组,Oracle按照GROUP BY子句中指定的表达式的值分组查询结果(参见5.4节)。

5.3.3 函数的嵌套

前面介绍的各种函数可以相互嵌套,以便一个函数的输出作为另一个函数的输入。运算符有自己固有的优先执行顺序,但函数的优先执行顺序只基于它的位置。函数的执行从最里层开始执行直到最外层并且从左到右。

例5-61 函数嵌套举例,返回emp表中ename等于大写的JONES的雇员信息。

SQL>SELECT empno,ename,job,sal FROM emp

WHERE UPPER(RTRIM(ename))′JONES′;

第一步:执行内层函数rtrim(ename),将ename列的值右边的空格去掉。

第二步:执行外层函数UPPER(RESULT1),将去掉空格后的ENAME列的值转换成大写。

5.4 SQL的数据查询

SQL的核心操作是查询,SQL提供了SELECT语句进行数据库的查询,该语句具有灵活的使用方式和丰富的功能,可以构造各种各样的查询。其一般格式为:

SELECT[ALL|DISTINCT]<目标列表达式>[,<目标列表达式>]……

FROM<表名或视图名>[,<表名或视图名>]……

[WHERE<条件表达式>]

[GROUP BY<列名1>[HAVING<条件表达式>]]

[ORDER BY<列名2>[ASC|DESC]]

其中:

SELECT子句说明要查询的数据,ALL表示显示所有满足条件的元组,DISTINCT表示去掉重复元组。

FROM子句说明要查询的数据来源,可以基于单个表或多个表、或视图进行查询。

WHERE子句说明查询条件,即选择元组的条件。

GROUP BY子句用于对查询结果进行分组,可以利用它进行分组汇总。

HAVING子句必须跟随GROUP BY一起使用,它用来限定输出分组结果必须满足的条件。

ORDER BY子句对查询结果在输出时进行排序。

整个SELECT语句的含义是:根据WHERE子句的条件表达式,从FROM子句指定的基本表或视图中找出满足条件的元组,再按SELECT子句中的目标列表达式,选出元组中的属性值形成结果表。如果有GROUP子句,则将结果按<列名1>的值进行分组,该属性列值相等的元组为一个组,每个组产生结果表中的一条记录。通常会在每组中使用聚组函数。如果GROUP子句带HAVING短语,则只有满足指定条件的组才予输出。如果有ORDER子句,则结果表还要按<列名2>的值的升序或降序排序。

SELECT语句可以完成简单的单表查询、多表联结查询及嵌套查询(即子查询),下面分别介绍。仍然按5.2.1中介绍的学生选课数据库中的三个表为例说明SELECT功能。