您的位置:首页 > 数据库 > Oracle

Oracle

2016-04-15 22:42 411 查看


Oracle(一)


转载▼

这三天我们一直在学Oracle,这个课程是王治国老师讲的,大概课程内容为一下的几个方面:

Oracle的基本使用

1.安装 卸载 内存机构 物理结构

2.用户管理 , 权限管理

3.网络配置 客户端的建立 监听的建立

4.Sql初级

增删改查 内外连接 子查询

5.Sql中级

事务 函数 序列 同义词 视图

6.Sql高级

PL/Sql ,存储过程,自定义函数,触发器

7.实用技巧

索引

首先是Oracle的安装卸载等等,这些,要跟着安装步骤进行安装即可,安装的详细步骤其他地方一定有更详细的教程的,就不用多说了!

Oracle数据库用户:

1、三个常用的系统用户:

Scott(一个数据库的普通用户)

Connect scott/tiger

Manager(数据库管理员)

Connect system/mangaer

Sys(数据库对象的拥有者权限最高)

Connect sys/change_on_install as sysdba;

用户管理:

每个想使用Oracle的用户都必须得到一个合法的用户名、口令和相应的权限,才能进入Oracle系统进行相应的操作。在访问Oracle的对象时,必须使用一个用户和口令连接数据库,只有连接成功才能操作数据库对象。

Oracle的帐户是管理员建立的,对于不同的用户,可以授予不同等级的权限,每个用户只能在自己的权限范围内活动,任何超越权限的操作都视为非法,系统将不理睬或拒绝。

一、建立用户

1.格式:

Create User 用户名 Identified By 口令 [Externally]

[Default TableSpace 表空间名]

[Temporary TableSpace 表空间名]

[Quota 整数 K|M|Unlimited On 表空间]

举例:creater user itcast idenfified by itcast;---用户创建.

2、说明:

(1)Identified By:在SQL*PLUS中建立时,要输入一个以字母开头的口令, 在企业管理器中可以用任意。

(2)Default TableSpace:指定缺省表空间;

(3)Temporary TableSpace:指定临时表空间;

(4)Quota:指定表空间的配额。

3、实例:(必须具有DBA权限)

Create User Student01

Identified By Student

Default TableSpace Student

Temporary TableSpace TempStudent

Quota 5M On Student

Quota 3M On tempStudent

4、注意事项:用户的密码是以十六进制字符串格式保存在数据库中的,若忘记数据库管理员从这十六进制也难以获得当前的密码(编程除外),最好的方法是直接赋予新密码。

权限管理:

一、授权

1、方式:通过授予权限的命令实现对用户或角色权限的授予。

2、格式:Grant [系统特权名] [角色] To [用户名列表] [Public] [with Admin Option]

3、说明:

(1)系统特权名:指表中所给出的特权名;

(2)角色:具有相应权限的一种代号;

(3)Public:授予全部用户;

(4)With Admin Option:使用户能将其得到的权限授予其他用户。

4、实例:

(1)Grant Create Session,Create Table To Student01;

(2)Grant Insert,Update,Select,Delete On Student To Student01 With Admin Option;

(3)Grant All On Stuent To Public;

二、查看存在的系统权限

1、用到的数据字典:User_Sys_Privs;

2、实例:Select * From User_Sys_Privs;

三、权限的回收

1、格式:Revoke [系统特权名] [角色] From [用户名列表] [Public]

2、功能:将分配给用户或角色的权限收回来。

3、实例:

(1) Revoke Insert On Student From Student01;

(2) Revoke All On Student From Public;

(3) Revoke Create Table From Student01;

角色管理:

角色定义: 角色是将系统权限分配给用户的中间的类用户或权限装载容器,可以给某些角色一定的权限,当某个用户需要一定权限时,把一个具有和他所要的权限相同的角色赋予他就可,这样省时高效。

一、建立角色

1、格式:Create Role 角色名 [Not Identified |Identified By 口令 |Externally]

2、说明:Not Identified:指出授予该角色的用户在使用时不需要检验;

Identified By:指出授予该角色的用户在使用Set Role命令时需检验。

检验的方式:

a) 口令

b) Externally:有操作系统检验的口令;

3、实例:

Create Role StudentRole 或 Create Role StudentRole Identified By Studentrole

二、查看角色

1、使用数据字典:Role Sys Privs; 角色的系统权限

2、实例:Select * From Role_Sys_Privs WhereRole=‘STUDENTROLE’;

三、修改角色

1、格式:Alter Role角色名 [Not Identified | Identified By 口令 |Externally]

2、实例:Alter Role StudentRole Not Identified;

四、使用角色为用户赋予权限

1、功能:使用角色为用户赋予权限便于用户的区分,而DBA也不用每个用户都重新赋予某些权限,快!

2、实现过程:先给角色赋予相应的权限,然后再把角色像赋予权限一样赋予用户,用户就具有和角色一样的权限了。

3、实例:

(1) Create Role StudentRole;

(2) Grant Create Session,Create Table, Create View,Create Procedure To StudentRole;

(3) Grant StudentRole To Student01 或 Public;

4、角色权限的回收:

Revoke 权限 From角色;

五、删除角色

1、格式:Drop Role角色名

2、实例:Drop Role StudentRole; 不影响用它已经授予的用户的权限

数据库角色:

角色相当于一个windows中的组,比如我们属于administrators组,我们就拥有administrator的所有权限,oracle为了方便管理也预定义了很多的组:

比如:

connect 连上Oracle,做最基本操作

resource 具有程序开发最基本的权限

dba 数据库管理员所有权限

exp-full-database 可把数据库整个备份输出的权限

imp-full-datsabase 可把数据库整个备份恢复输入的权限

给用户分配角色:

Connect system/manager;

Grant connect to tea;

Grant resource to tea;

系统权限:

Oracle把权限进行了细分,在Oracle 9i系统中,可用的系统权限共有116个,主要的系统权限如下所示:

CREATE PROCEDURE

CREATE ROLE

CREATE SEQUENCE

CREATE SESSION

CREATE TABLE

CREATE TABLESPACE

CREATE TRIGGER

CREATE USER

CREATE VIEW

DROP TABLESPACE

DROP USER

给用户分配系统权限:

1.给用户创建触发器的权限:

Grant create trigger to tea;

2.给用户更改表的权限。

Grant alter table to tea;

对象权限:

我们想让tea可以访问scott用户的emp表,我们需要给tea赋予对象权限,一定要注意:scott是表的拥有者,因此只有scott用户才可以把访问该表的权限给别人;

表对象权限包括(七个)Insert ,update, delete, select, index ,alter ,reference.

存储过程的有:exec

给用户分配对象权限:

1、把对emp表的select权限分配给tea用户:

Connect scott/tiger;

Grant select on emp to tea;

Connect tea/123;

Select * from scott.emp;

2、 把对emp表的所有权限分配给tea用户:

Connect scott/tiger;

Grant select on emp to tea;

管理权限:

Tea虽然拥有对表的所有权限,但是tea并不能把他所拥有的这些权限给其他用户,如果需要它必须具备管理权限能力。语法如下:

Connect scott/tiger;

Grant select on emp to tea with grant option;

grant update(loc) on dept to a;

这样tea用户就可以把对scott的emp表的select权限赋给其他用户了。

收回权限:

收回部分权限:

Connect scott/tiger;

Revoke select on emp from tea;

收回所有权限:

Connect scott/tiger;

Revoke all on emp from tea;

下面是对上面的总结:

sys 网络管理员

system 本地管理员

scott 普通用户 ----- tiger

用sys用户登陆,对scott解锁。

alter user scott account unlock;

alter user scott account lock;

第一次用scott登陆的时候,需要立刻修改密码。

sqlplus sys/sys as sysdba

sqlplus / as sysdba

sqlplus scott/tiger

对象权限

系统权限

oracle三种验证方式

数据库验证 scott system

操作系统验证 sys

密码文件验证

lsnrctl start //启动监听

sqlplus /nolog

conn sys/oracle as sysdba 用sys连接oracle

startup 启动数据库

disconn

exit

lsnrctl start

oradim -startup -sid orcl //启动实例

1到3点的基本内容其实也没有什么,就知道这些的话,也算是入门了!而3以后才是最重要的,值得我们去慢慢体会的!虽然今天的内容不是很难,但是一些理论知识一定

要掌握的,特别是权限的使用是非常重要的,有了这些权限之后就可以对下面进行增删改查.不过还要先启动监听和实例!

SQL基础

这些写SQL语句的一些注意点:

1.SQL 语句不是大小写敏感的。

2.建议关键字用大写,其他用小写。

3.SQL 语句可以分布在一行或者多行中。

4.关键字不能进行缩写,也不能分布在两行。

5.一般地,不同的子句写在不同的行为宜。

.经常用跳格键或者缩进来增强可读性.

例子:

SELECT * FROM dept;

SELECT deptn,loc FROM dept;

缺省的对齐方式

左部对齐:日期、字符数据

右部对齐:数字格式数据

缺省的显示方式: 大写

可以用下述的数学符号,将日期或者数字数据组合起来形成数学表达式:+,-,*,/;

SELECT ename,sal,sal+300 FROM emp;

乘和除操作的优先级高于加和减。相同优先级的操作符自左向右进行计算。圆括号"("")",用来重新组合表达式的优先级

SELECT ename,sal,12*sal+100 FROM emp; SELECT ename,sal,12*(sal+100) FROM emp;

空值是一个表达不可用、未分配、未知、或者不适用等意义的值。

空值与零和空格的概念不同,应当严格区分。

SELECT ename,job,sal,comm FROM emp;

如果数学表达式中包含了一个空值,那么该数学表达式计算的结果为空值

SELECT ename,12*sal+comm FROM emp WHERE ename='KING';

重新命名一个列的名字有时很有用。

可以用AS关键字为列名取一个别名。如果别名中包含空格,或者其他特殊自符,则需要用引号("")将别名包含起来

SELECT ename AS name,sal salary FROM emp;

SELECT ename "NAME",sal*12 "Annual Salary" FROM emp;

可以将一些列连接起来,也可以将一些列和一些字符串连接起来。 串接操作符用两个竖杠 (||)表示。可以用这种方法创建一个由字符串组成的结果列。

SELECT ename||job AS "Employees" FROM emp;

文字字符串是包含在一个Select语句中的字符串、数字、或者日期。文字字符串必须用单引号('')括起来。对于返回的每一行,文字字符串都显示一次。在生成报表时非常有用。

SELECT ename||'is a'||job AS "Employee Details" FROM emp;

查询语句执行的结果,缺省的显示方法是显示所有的行,包括重复的行。

SELECT deptno FROM emp;

在SELECT语句中用 DISTINCT关键字来消除所有重复的行。

SELECT DISTINCT deptno FROM emp;

PL/SQL、SQL和SQL*Plus间的关系

SQL Structured Query Language(结构化查询语言)

PL/SQL procedure language

SQL*Plus 一个工具

SQL

一种语言,符合ANSI 标准,关键字不可以缩写,语句可以操纵数据和定义在数据库中的表。

SQL*Plus

一个环境,符合Oracle属性,关键字可以缩写,命令不能操作数据库中的数据

选择查询出的行:

用where子句限定查询出的行.Where子句紧跟在From子句之后.

SELECT ename, job, deptno FROM emp WHERE job='CLERK';

字符串和日期

字符串和日期值应当用单引号括起来.字符串值大小写敏感,日期值对于日期的格式敏感。缺省的日期值格式: DD-MON-YY.

例如:23-9月-02.为02年9月23日

SELECT ename, job, deptno FROM emp WHERE ename='JAMES';

使用比较操作符

SELECT ename, sal, comm FROM emp WHERE sal<=comm;

用BETEEN操作符:用BETEEN操作符来查询出在某一范围内的行

SELECT ename, sal FROM emp WHERE sal BETWEEN 1000 AND 1500;

使用IN操作符:用IN操作符来检验一个值是否在一个列表中.

SELECT empno, ename, sal, mgr FROM emp WHERE mgr IN (7902, 7566, 7788);

使用LIKE操作符

用LIKE进行某个字符串值的通配符匹配,来选出某些行.查询条件中既可以包含字符,也可以包含数字.% 代表0个或者多个字符. _ 代表一个字符.

SELECT ename FROM emp WHERE ename LIKE 'S%';

可以混合使用模式字符串.

SELECT ename FROM emp WHERE ename LIKE '_A%';

如果要匹配%这个字符,可以用\%来表示

SELECT * FROM dept WHERE dname like 'itc*%%' ESCAPE‘*';.

使用IS NULL操作符

用 IS NULL操作符来检查有无空值

SELECT ename, mgr FROM emp WHERE mgr IS NULL;

使用AND操作符

AND 需要所有的条件都为TRUE.

SELECT empno, ename, job, sal FROM emp WHERE sal>=1100 AND job='CLERK';

使用OR操作符

OR操作符只需任意条件为TRUE即可

SELECT empno, ename, job, sal FROM emp WHERE sal>=1100 OR job='CLERK';

使用NOT操作符

SELECT ename, job FROM emp WHERE job NOT IN ('CLERK','MANAGER','ANALYST');

优先级规则

SELECT ename, job, sal FROM emp WHERE job='SALESMAN' OR job='PRESIDENT' AND sal>1500;//这里是先AND后OR;

用圆括号强制改变操作符的优先级次序。

SELECT ename, job, sal FROM emp WHERE (job='SALESMAN' OR job='PRESIDENT') AND sal>1500;

ORDER BY子句

用 ORDER BY子句进行行的排序

ASC: 升序, 缺省

DESC: 降序

ORDER BY子句跟在SELECT 语句之后

SELECT ename, job, deptno, hiredate FROM emp ORDER BY hiredate;

采用降序排序

SELECT ename, job, deptno, hiredate FROM emp ORDER BY hiredate DESC;

按照列的别名来进行排序

SELECT empno, ename, sal*12 annsal FROM emp ORDER BY annsal;

按照多个列进行排序

ORDER BY 后的列的顺序既排序的顺序.

SELECT ename, deptno, sal FROM emp ORDER By deptno, sal DESC;//先按照部门升序排序,部门相同的员工按照工资降序排序

集合操作符

Union 联合两个结果集(去除掉重复记录)

Union all 联合两个结果集(不去除掉重复记录)

Intersect 取两个结果集的交集

Minus 取两个结果集不同但属于第一个结果集的记录

下面是段举例:

查找所有10部门的经理和 20部门的办事员

SELECT * FROM emp WHERE (deptno=10 and job='MANAGER') OR (DEPTNO=20 AND JOB='CLERK');

可以使用集合操作符等效查询:

SELECT * FROM emp WHERE (deptno=10 and job='MANAGER')

UNION

SELECT * FROM emp WHERE (DEPTNO=20 AND JOB='CLERK');

查找所有10部门的经理

SELECT * FROM emp WHERE deptno=10 and job='MANAGER;

可以使用集合操作符等效查询:

SELECT * FROM emp WHERE deptno=10

INTERSECT

SELECT * FROM emp WHERE AND JOB=‘MANAGER');

注意啦,下面的内容相当重要的了,前面的内容说白了,其实很简单的,只要知道语法即可,而后面的是需要通过思考才能够完成的,一般企业招聘大多都考后面的内容。

聚合函数:

求和 Sum()

平均 Avg()

最小 Min()

最大 Max()

行数 Count()

语法:

Select …..from … where …

Group by ….having… order by….

聚合函数的作用

查找公司的工资总和:

SELECT sum(sal) FROM emp;

查找公司的总人数:

SELECT count(*) FROM emp;

查找公司的平均工资:

SELECT avg(sal) FROM emp;

查找公司的最高工资:

SELECT min(sal) FROM emp;

查找公司的最低工资:

SELECT max(sal) FROM emp;

Group by的含义

查看每个部门的总工资:

SQL> SELECT deptno,sum(sal) FROM emp GROUD BY deptno;

DEPTNO SUM(SAL)

------ ----------

10 8750

20 10875

30 9400

我们会按照deptno给emp表分成3个组,来对每个组进行聚合。

Having和where的区别

一、Having用来筛选聚合之后的结果集,比如我们要对刚才查询的结果进行筛选:我们只察看那些部门总工资高于10000的部门:

SQL> SELECT deptno,sum(sal) FROM emp GROUD BY deptno HAVING sum(sal)<10000;

DEPTNO SUM(SAL)

------ ----------

10 8750

30 9400

二、Where用来筛选表中的记录,比如我们查找每个部门工资高于2000的员工的总工资,注意:这其中我们要让工资低于2000的记录不参加聚合,所以我们使用where来筛选表中的记录。

SQL> SELECT deptno,sum(sal) FROM emp WHERE sal>2000 GROUD BY deptno;

DEPTNO SUM(SAL)

------ ----------

10 7450

20 8975

30 2850

Where 分组前执行条件筛选,having 分组后执行。

Having可以使用聚合函数

两个隐藏列

Rowid

Rownum

SELECT * FROM (SELECT * FROM dept ODER BY deptno DESC) WHERE rownum <=3;

综合实例

查找每个部门工资高于2000的员工的总工资,要求只显示总工资高于5000的部门,按总工资降序排列:

SQL> SELECT deptno,sum(sal) FROM emp WHERE sal>2000 GROUD BY deptno HAVING sum(sal)>5000

ORDER BY sum(sal) desc;

DEPTNO SUM(SAL)

------ ----------

20 8975

10 7450

这个事某企业的面试题目,课上老师讲到,所以在这里拿出来与大家分享的.

姓名 科目 分数

张三 数学 71

张三 语文 80

李四 数学 86

李四 语文 90

王五 数学 100

王五 语文 91

王五 英语 60

1 用一条SQL语句,查出每门科目成绩都大于85分的学生的姓名?

Select 姓名 from table group by 姓名 having min(分数)>85;

2用一条SQL语句,查出平均分大于85分的学生的姓名。

Select 姓名 , count(*) from table where 分数<85 group by 姓名

Having count(*)=0;

其实地一题比第二题难理解的,第一题的思路是找出最低的分数高于85 即可,这里考查的是逆向思维。

通过上面知识的梳理,SQL初级的知识基本解决了,明天将写些初级知识的高级应用。高级应用的知识还是非常重要的,只要这些只是会了,一般的企业SQL面试80%是过了。

初级知识的高级应用

大概的内容如下:从多个表中获取数据,分组函数,子查询。

而这里以子查询为最重要。

1.内联接——等联接

内连接实际上就是利用where子句对两张表形成的笛卡尔积进行筛选等连接(用=条件进行筛选)比如:

Select * from tab1 t,tab2 r where t.aa=r.bb;

select * from emp e,dept d where e.deptno=d.deptno

2.内联接——非等联接

内连接实际上就是利用where子句对两张表形成的笛卡尔积进行筛选非等连接(用=以外的条件进行筛选)一个基本的案例:

Select * from tab1 t,tab2 r where t.aa>r.bb;

来看一个实际的例子:察看员工的工资级别

select empno,sal,s.* from emp e,salgrade s where sal between s.losal and s.hisal;

3.外联接

我们会注意到两个事情,tab1和tab2两个标做内联接的时候有些记录没有办法显示出来,原因是另一个表没有匹配的条件:我们发出

select * from emp e,dept d where e.deptno=d.deptno;的时候40部门不会被显示,原因是40部门没有员工,所以在员工表中没有记录,因此不满足联接的筛选条件所以显示不出来。

4.Oracle的外联接语法

外连接:

a和b进行连接,如果要完全显示a,就在b条件上加一个(+),也就是说不带+的表完全显示

select * from emp e,dept d where e.deptno(+)=d.deptno;

因为我们给e.deptno带上一个(+),所以d表将会被完全显示也就是dept表会被完全显示,如果左侧的表完全显示我们就说是左外联接。比如:

Select * from tab1 t,tab2 r where t.aa=r.bb(+);

如果右侧的表完全显示我们就说是右外联接。比如:

Select * from tab1 t,tab2 r where t.aa(+)=r.bb;

左外联接:

左连接(左侧的表完全显示)

SQL> Select * from tab1 t left join tab2 r on t.aa=r.bb;

AA BB CC

---------- ---------- --------------------

2 2 a

3 3 b

1

必须显示所有的员工

select * from emp e left join dept d on e.deptno=d.deptno;

右外联接:

右连接(右侧的表完全显示)

SQL> Select * from tab1 t right join tab2 r on t.aa=r.bb;

AA BB CC

---------- ---------- --------------------

2 2 a

3 3 b

4 c

要求必须显示所有的部门

select * from emp e right join dept d on e.deptno=d.deptno;

完全外联接:

完全显示两个表,没有匹配的记录置为空:

SQL> Select * from tab1 t full outer join tab2 r on t.aa=r.bb;

AA BB CC

---------- ---------- --------------------

2 2 a

3 3 b

1

4 c

Char varchar2 nchar nvarchar2 date blob clob number(3,1)

内联接:

自连接(一个特殊的内连接,自己连接自己的一个副本)比如:

select * from tab1 a,tab1 b;

就是自己联接自己的笛卡尔积

我们分析emp表,该表中有一个字段叫作mgr,它的具体含义是该员工领导的empno,如果我们要查找一个员工领导的姓名怎么办呢?

我们想到把emp表形成2个副本,连接后我们使用如下条件,a.mgr=b.empno就可以了,查询如下:

select e.empno,e.ename,e.mgr,b.empno,b.ename from emp e,emp b where e.mgr=b.empno;

再一次注意了,一般大企业考数据库专考下面的内容,为什么,看了下面的内容就知道了。

相关联子查询

一个查询如下:查找所有工资高于公司平均工资的人:

select * from emp where sal>(select avg(sal) from emp);

查询如何进行呢?系统找到emp的所有的纪录,从中分别拿出每一行来求解where子句,也就是说我们的emp表有14行,自查询也会执行14次。

我们来看一个新的查询要求:

1.查找所有工资高于自己本部门平均工资的人。

看起来和刚才的很像,但是这样一行记录是否能保存下来就依赖于他的工资是否高于他所在部门的平均工资既然查询是逐行来求解where子句,我们是否可以让

where子句求解当前行员工所在部门的平均工资呢,也就是说我们要在自查询中获得主查询当前行的值:具体如法如下:用主表的别名.列名,代表主查询当前行得值

我们发出查询如下:select * from emp e where sal>(select avg(sal) from emp where deptno=e.deptno);

注意:e.deptno代表的就是主查询当前行的deptno的值

2.查找每个部门工资最高的人的详细资料

思路:得到所有的员工,进行筛选,每拿到一个员工,判断该员工的工资是否是他们部门的最高工资

select * from emp e where sal=(select max(sal) from emp where deptno=e.deptno);

select max(sal) from emp where deptno=e.deptno就是求解当前员工所在部门的最高工资

3.显示每个部门的信息和人员数量

思路:查询获得所有的部门信息,没获得一个部门,我们就查询该部门的人数,保存为一个新的列

select d.*,(select count(*) from emp where deptno=d.deptno) tot from dept d;

4.创建表myemp和emp拥有相同的记录和结构

给myemp 增加一个列 no_of_sal(该员工的工资在公司的排名)和no_of_per(该员工工资在他所在部门的排名)

思路:每拿到一个员工判断它的工资在公司和部门排名第几

可是如何确定排名呢?

思路:查找工资比当前员工工资高的人数,工资比当前高的有10个的话,该员工排第11

现在更新no_of_sal为该员工工资在公司的排名

update myemp m set no_of_sal=(select count(*)+1 from myemp where sal>m.sal);

现在更新no_of_per为该员工工资在本部门的排名

update myemp m set no_of_sal=(select count(*)+1 from myemp where sal>m.sal and deptno=m.deptno);

相关联子查询 总结

什么是关联自查询?

在子查询中需要利用“主查询表别名.列名”来引用主查询当前行的值

他的用途非常广泛,比如:

查找入职日期早于其直接上级的员工:

select * from emp e where hiredate<(select hiredate from emp where empno=e.mgr);

这道也是一家企业的SQL面试题目:

给出这四个名称:id country region population,为下面的内容写段SQL语句:

查询出哪个 国家的人口比他周边国家的人口的平均值大3倍的国家。

Select * from table t1 population>(

Select avg(popylation) from table t2

Where t2.region=t1.region and country nto in(t1.country))*3;

通过这题可以看出相关子查询的重要性。

事务和SQL函数

课程目标

1.数据库的事务命令

2.描述在 SQL语句中可能用到的各种函数。

3.在SELECT 语句中使用字符串、数字、日期的函数。

4.描述转换函数的用法

(一)

Oracle的默认事务模型

oracle所有的dml语句只有提交后其他用户才能看到,未提交的结果只在会话期间可见

而DDL语句不用提交,系统会自动提交

事务命令:

Commit

使用commit可以提交所有没提交的事务

可以把上次提交以来的事务提交

企业管理器中的操作和ddl语句将自动提交

Rollback

可以回滚所有没提交的事务

已经提交的事务不能再回滚

Savepoint

使用rollback命令回滚到一个指定的保存点

举例:

Insert into dept values(11,null,null);

Insert into dept values(12,null,null);

Savepoint p1;

Insert into dept values(13,null,null);

Insert into dept values(14,null,null);

Savepoint p2;

Insert into dept values(15,null,null);

Insert into dept values(16,null,null);

rollback to p2;

Select * from dept;

Rollback to p1;

Select * from dept;

Rollabck;

Select * from dept;

oracle中,只有增删改查 是手动提交。其他是自动提交。

各种可能用到的函数:

1.字符函数

大小写转换函数

LOWER,UPPER,INITCAP

字符操作函数

CONCAT,SUBSTR,LENGTH,INSTR,LPAD,TRIM

使用大小写转换函数:

查出员工Blake的号码、名字、部门号

SQL> SELECT empno, ename, deptno

2 FROM emp

3 WHERE ename = 'blake';

no rows selected

SQL> SELECT empno, ename, deptno

2 FROM emp

3 WHERE ename = UPPER('blake');

EMPNO ENAME DEPTNO

--------- ---------- ---------

7698 BLAKE 30

使用字符操作函数:

SQL> SELECT ename, CONCAT (ename, job), LENGTH(ename),

2 INSTR(ename, 'A')

3 FROM emp

4 WHERE SUBSTR(job,1,5) = 'SALES';

ENAME CONCAT(ENAME,JOB) LENGTH(ENAME) INSTR(ENAME,'A')

---------- ------------------- ------------- ----------------

MARTIN MARTINSALESMAN 6 2

ALLEN ALLENSALESMAN 5 1

TURNER TURNERSALESMAN 6 0

WARD WARDSALESMAN 4 2

2.使用ROUND函数

SQL> SELECT ROUND(45.923,2), ROUND(45.923,0),

2 ROUND(45.923,-1)

3 FROM DUAL;

ROUND(45.923,2) ROUND(45.923,0) ROUND(45.923,-1)

--------------- -------------- -----------------

45.92 46 50

3.使用TRUNC函数

SQL> SELECT TRUNC(45.923,2), TRUNC(45.923),

2 TRUNC(45.923,-1)

3 FROM DUAL;

TRUNC(45.923,2) TRUNC(45.923) TRUNC(45.923,-1)

--------------- ------------- ---------------

45.92 45 40

4.使用MOD函数

计算工作为 salesman的员工的工资(Sal),除以COMM后的余数。

SQL> SELECT ename, sal, comm, MOD(sal, comm)

2 FROM emp

3 WHERE job = 'SALESMAN';

ENAME SAL COMM MOD(SAL,COMM)

---------- --------- --------- -------------

MARTIN 1250 1400 1250

ALLEN 1600 300 100

TURNER 1500 0 1500

WARD 1250 500 250

5.使用日期

Oracle 以一种内部的格式来保存日期: 世纪,年,月,日,小时,分钟,秒.

缺省的格式:DD-MON-YY.例如:23-JAN-02

SYSDATE 是一个返回日期和时间的函数.

DUAL 是一个显示 SYSDATE的虚拟表.

用数学运算符对日期计算

SQL> SELECT ename, (SYSDATE-hiredate)/7 WEEKS

2 FROM emp

3 WHERE deptno = 10;

ENAME WEEKS

---------- ---------

KING 830.93709

CLARK 853.93709

MILLER 821.36566

6.TO_char函数

TO_CHAR(date, 'fmt')

必须用单引号括起来,并且是大小写敏感的

日期格式必须是可用的

前面加上 fm字符以压缩掉开始和结束的空格

同日期值用逗号隔开

使用TO_CHAR函数

SQL> SELECT ename,

2 TO_CHAR(hiredate, 'fmDD Month YYYY') HIREDATE

3 FROM emp;

ENAME HIREDATE

---------- -----------------

KING 17 November 1981

BLAKE 1 May 1981

CLARK 9 June 1981

JONES 2 April 1981

MARTIN 28 September 1981

ALLEN 20 February 1981

...

14 rows selected.

7.TO_DATE函数

TO_DATE(‘STR', 'fmt')

第一个参数是我们需要转换为日期的字符串

第二个参数是我们要转换为日期的字符串的格式描述

使用TO_DATE函数

SQL> insertinto emp(empno,hiredate,deptno) values(2222,

2 to_date(‘1999-05-21 15:21:20’,’yyyy-mm-dd hh24:mi:ss’),

3 20);

SQL> SELECT TO_DATE(‘1998-09-01’,’YYYY-MM-DD’) FROM DUAL;

SQL> SELECT TO_DATE(’01-9月-05’,’yy-mon-dd’) FROM DUAL;

select to_char(hiredate,'yyyy-mm-dd hh24:mi:ss') from demo;

(二)

过程和函数

存储过程

一个预编译的pl/sql语句的集合

语法:

CREATE or REPLACE PROCEDURE <Proc_name> [parameter list]

IS|AS

<local declarations>;

BEGIN

(executable statements)

END

其中,Proc_name 是过程的名称,parameter list 是参数列表,local declarations 是局部声明,executable statements 是可执行语句。

创建一个简单的存储过程

功能:传入一个员工号打印他的工资

create or replace procedure myproc1(eno number)

as

i number;

--可执行部分(必需的)

begin

select sal into i from emp where empno=eno;

dbms_output.put_line(i);

--异常处理部分(可选的)

exception

when no_data_found then

dbms_output.put_line('没有这个员工!');

end;

/

参数模式

参数模式

IN

传入参数,类似于按值传递

默认模式

OUT

传出参数,将值返回给子程序的调用程序

相当于 空变量进入,带值传出

IN OUT

接受值并返回已更新的值,类似于安地址传递

执行和删除过程

select * from user_source;

执行过程

SQL>EXECUTE myproc (7369);



Begin

Myproc(7369);

End;

删除过程

Drop procedure myproc;

函数

函数和过程的区别在于函数有返回值

使用 CREATE FUNCTION 语句进行创建

语法

CREATE or REPLACE FUNCTION <function_name> [argument list]

RETURN datatype IS|AS

(local declaration)

BEGIN

(executable statements)END

其中,function_name 是函数名称,argument list 是参数列表,datatype 是数据类型,local declaration 是局部声明,executable statements 是可执行语句。

调用函数

访问函数

用两种方式进行访问

使用 PL/SQL 块

declare

p varchar2(20);

begin

p:=myfunc(7777);

dbms_output.put_line(p);

end;

/

使用 SQL 语句

Select myfunc(‘7369’) from dual;

Select * from emp where ename=myfunc(‘7369’);

Show errors;

Desc user_errors;

Select * from user_errors;

过程和函数:

1.作为 PL/SQL 语句执行 作为表达式的一部分调用

2.在规格说明中不包含RETURN 子句 必须在规格说明中包含 RETURN 子句

3.可以返回任何值 必须返回单个值

4.可以包含 RETURN 语句,但是与函数不同,

它不能用于返回值 必须包含至少一条 RETURN 语句

PL/SQL

PL/SQL(procedure language SQL)

是oracle开发的一种面向过程的数据库语言

Pl/SQL块结构

PL/SQL添加了变量

PL/SQL添加了循环语句

PL/SQL添加了分支语句

PL/SQL块

Pl/sql块的结构:

Declare

声明部分(可选部分)

Begin

执行部分(必须部分)

Exception

异常处理部分(可选部分)

End;

/

注意:“/”才是pl/sql执行的标志

声明变量

1、一般变量声明:

eno number;

myname varchar2(10);

2、直接引用表的列类型声明变量:

eno emp.ename%type;

该声明表示eno的类型是emp表的empno列的数据类型

2、行类型声明:

emprow emp%rowtype;

行类型声明是oracle一种特殊的声明,声明的eee变量可以装载emp标的一行记录

给变量赋值

1、直接赋值

eno:=7369;

myname:=‘SCOTT’;

2、用户交互赋值

eno:=&empno;

运行时系统会提示用户输入empno,用户输入的值将存入eno变量。

3、利用查询返回的结果赋值

Select ename into myname from emp where empno=eno;

注意只有在该查询返回一行的时候该语句才可以成功否则就会抛出异常。

举个例子:

declare

a number;

b varchar2(15);

c emp.sal%type;

d number;

begin

a:=7369;

b:='&ename';

d:=&deptno;

select sal into c from emp where deptno=d;

--输出

dbms_output.put_line('empno is '||a);

dbms_output.put_line('input ename is '||b);

dbms_output.put_line('the emp sal is '||c);

dbms_output.put_line('in put empno is '||d);

EXCEPTION

--针对查询返回多行返回的异常

when too_many_rows then

dbms_output.put_line('toooooooooo many!!!');

--针对查询返回的数据为空的异常

when no_data_found then

dbms_output.put_line('nooooooooooo data!!!');

end;

/

循环

Oracle提供了4种循环:

1、Loop循环

Loop

…..

Exit when…

End loop;

2、while循环

While(..)

Loop



End loop;

3、for循环

For i in lowbound..highhound

Loop

End loop;

4、for reverse循环

For i in reverse lowbound..highhound

Loop

End loop;

举例说明

declare

id int:=1;

name dept.dname%type;

begin

loop

id:=id+1;

dbms_output.put_line(id);

exit when id=10;

end loop;

end;

/

declare

id int:=1;

name dept.dname%type;

begin

while(id<10)

loop

id:=id+1;

dbms_output.put_line(id)

end loop;

end;

begin

for i in 1..10

loop

dbms_output.put_line(i);

end loop;

end;

/

declare

id int:=10;

num int:=11;

begin

if(num>id) then

dbms_output.put_line('num>id')

else

dbms_output.put_line('num<=id')

endif;

end;

这样,Oracle的初高级内容大致就这些,其实Oracle有很多更高级的,比如优化,之类等等。学习它不是几天就可以都学明白的东西的。不过载一般的企业,掌握这几天的内容也完全可以应付了。即使在企业用到不会的,只要想想老师给的学习方法,一切问题也很容易解决的。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: