以下全属个人学习oracle的学习记录,仅供参考,有不对的地方欢迎交流。
我的学习oracle的目录大致如下:
一:Oracle基础
1.sql/plus用法详解
2.基本增删改查语句
3.列类型与建表语句
4.正确的查询模型
5.查询子句详解
6.约束
7.连接查询
8.子查询
9.视图
二:Oracle进阶
1.索引
2.序列
3.同义词
4.事务
5.函数
6.触发器
7.pl/sql编程
• 匿名块
• 控制结构
• 过程与函数
• 存储过程与存储函数
• 游标
三:实际操作
1.sql/plus连接服务器
连接并登陆
sqlplus "用户名/密码[@主机名 as 身份]"
先连接再登陆
sqlplus/nolog
conn 用户名/密码[@主机名 as 身份]
退出:
quit
如图所示:
2.sqlplus做最简单的查询
select 3+2 from dual;
注意dual是Oracle中的一个伪表,利用这个伪表可以设置或查看序列,或者是调用一些内置的函数,方便操作。
3.sqlplus的缓冲区
我们输入的sql命令,会被sqlplus储存在缓冲区里,
熟练利用缓冲区,可以提高我们书写sql的效率
因为缓冲区的内容 可以 修改/删除,再执行
用list/l 查看缓冲区内容
4.列类型
5.建表语句
create table 表名 (
列名 列类型,
...
);
create table 表名
as
select 列1,列2...列N from othoretable;
create table 表名
as
select 列1 as 新列1, 列2 as 新列2 ...列N as 新列N
from othertable
6.修改表的语句-add 列
alter table cxb add(
address varchar2(60)
);
7.修改表的语句-drop列
作用:删除表中的列
语法: alter table 表名 drop column 列名
关于删除列的注意事项:
原则上,列都可以删
但,如果一个列作为主键出现
或者作为另1张表的外键,则不能删除
8.修改表的语句-modify 列
作用:修改表中的列
语法: alter table 表名 modify (
列1 新数据类型 [非空属性]
..
);
关于修改列的注意事项:
如果表中没有数据,则列的长度可增加或减小
如果已有数据,则只能增大,不能减小.
9.修改表的语句-修改列名
作用:修改表中的列名
语法: alter table 表名 rename column 旧列名 to 新列
10.关于表的其他DDL语句
删除表: drop table 表名
改表名: rename table 旧名 to 新名
清空表: truncate table 表名
truncate清空表数据,且不可恢复,慎重.
11.约束
约束概念:
约束是加在表上的一种强制性的规则 ,是保证数据完整性的一种重要手段 .
当向表中插入或修改数据时,必须满足约束所规定的条件.
如性别必须是"男/女",部门号必须是已存在的部门号等等.
一般而言,保证数据完整性大致有3种方法
程序代码,触发器,约束.
约束类型:
NOT NULL 非空约束
UNIQUE 唯一性约束
PRIMARY KEY 主键约束
FOREIGN KEY 外键约束
CHECK 检查约束
11.1:约束的创建(1)
建表时创建约束
create table 表名 (
列1 数据类型 constraint 约束名1 约束类型,
列2 数据类型 constraint 约束名2 约束类型,
...
);
11.2:约束的创建(2)
11.3:外键的声明
外键的声明稍复杂一点,因为牵涉到另一张表
create table 表名 (
列1 列类型
contraint 约束名 foreign key (列名) references 其他表(列名)
注意: 另一张表被引用的列需是主键或Unique
11.4:建表后添加约束
在需要批量导入数据时,约束会影响导入速度,
可以先不要约束,导入完毕后,再添加约束.
alter table 表名 add (
constraint 约束名 约束类型(列名),
constraint 约束名 约束类型(列名)
);
alter table 表名 modify (
列名 constraint 约束名 not null
) ; // 因为not null 类型必须声明在列上,无法声明在表上,所以必须用modify方式来写
11.5:约束的删除与禁用
想改一个约束类型,只能先删除约束再添加新的约束
语法:
alter table 表名 drop constraint 约束名;
如 alter table student drop constraint gen_check
注意:如果删除主键约束时,该主键是另一表的外键,则该主键不能直接删除.
除非连带把外键约束也删除.
如 alter table dept drop constraint pk_dept cascade;
也可以临时禁用1个约束
alter table 表名 disable consstaint 约束名
注意:如果禁用约束后加了一些非法数据,再开启约束是会失败的
12.序列 sequence
序列是一种数据库对象,用来自动生成一组唯一的序号.
序列是一种共享式的对象,多个用户可以共同使用序列中的序号.
一般将序列应用于表的主键列,这样,当向表中插入数据时,主键列就使用了序列的序号,从而保证主键不会重复.
用序列来产生主键,可以获得可靠的主键值.
一句话: 序列就是序号生成器!
12.1:序列 sequence 的创建
create sequence 序列名 increment by n
start with n
maxvalue n | nomaxvalue
minvalue n | nominvalue
cycle | nocycle
cache n | nocache
上图创建了名称为mm的序列,每次增长1,从1开始,没有最大值,没有最小值,不循环,系统先缓存20个序列。
12.2:序列 sequence 的使用
序列的作用就是为我们提供序号,
序列提供了2个伪列, nextval, currval
很明显,分别是"下个值", "当前值"
select seq1.nextval from dual;
insert into xx表(col1,col2) values (seq1.nextavl,yy);
12.3:序列 sequence 的修改和删除
alter sequence 序列名
选项 新值
如
alter sqquence 序列名
maxvalue 5
注意:
1:不能修改开始值
2:修改只影响新产生的值,不影响已产生的值
drop sequence 序列名
13.同义词
同义词就是别名,外号
create [public] synonym 同义词 for 用户名.对象名
drop synonym 同义词
public 是所有用户可用的同义词,一般由DBA创建
注:scott用户默认没有创建synonym的权限
需要授权:
grant create synonym to scott
14.增删改查
14.1:select 子句介绍
Where 条件查询
group by 分组
having 筛选
order by 排序
14.2:select 子句 之group与统计函数
max : 求最大
min : 求最小
sum : 求总和
avg : 求平均
count:求总行数
14.3:select 子句 之group介绍
group by
作用:把行 按 字段 分组
语法:group by col1,col2,...colN
运用场合
常见于统计场合,如按栏目计算帖子数,
统计每个人的平均成绩等.
14.4:select 子句 之having介绍
14.5:子查询
子查询就是在原有的查询语句中,
嵌入新的查询,来得到我们想要的结果集。
一般根据子查询的嵌入位置分为,
where型子查询,from型子查询
14.5.1:where型子查询
where型子查询即是:把内层sql语句查询的结果作为外层sql查询的条件
典型语法:
select * from tableName
where colName = (select colName from tbName where ....)
{where colName in (select colName from tbName where ..)}
14.5.2:exists型子查询
exists即:外层sql查询所查到的行代入内层sql查询,要使内层查询能够成立
查询可以与in型子查询互换,但效率要高.
典型语法:
select * from tablename
where exists(select * from tableName where ...)
14.5.3:from型子查询
from型子查询即:把内层sql语句查询的结果作为临时表供外层sql语句再次查询.
典型语法:
select * from (select * from tableName where ...) where....
15.连接查询 之连接查询语法
左连接的语法.
Select Ltable.* ,Rtable.* from
Ltable left join Rltable
on Ltable.colName = Rtable.colName
典型的例子:学生表,科目表,学生选科目id学习,查询学生的时候联查科目表,学生表里存的有科目表的id,查询出学生信息带科目的信息。如图:
内连接的语法.
Select Ltable.* ,Rtable.* from
Ltable inner join Rltable
on Ltable.colName = Rtable.colName
16.视图 view
视图是一种虚拟表,本身不保存数据,而是从表中取得的数据。
可以理解为表的映射,或更简单的理解为一个查询结果。
比如,我们频繁的查询如下语句:
select empno,ename,sal from emp where sal > (select avg(sal) from emp);
如果把这个语句定义为视图,并从视图查询数据
16.1:视图 view的用途
1:视图可以帮我们简化查询
如上页中的复杂查询,如果不用视图,则需要子查询才能达到效果
2:视图可以帮我更精细的控制权限
比如一张表,有工资列,密码列,等,
我们可以选择列生成视图,开放给不同的用户,
达到列级的权限控制
16.2:视图 view的操作语法
创建视图:
Create or replace view 视图名
As select 语句
With read only --是否只读
With check option –是否执行约束检查
删除视图:
Drop view 视图名
16.3:复杂视图
如果select 语句中只针对单表进行列的查询,且没有对列进行表达式运算或函数运算,
这种称为简单视图。
如果对多个表进行查询,或列经过运算,或分组等,这种称为复杂视图。
复杂视图不能进行DML操作
本质区别:数学上是否一一对应。
即任意一行视图的记录,能对应表中唯一的一行,就是简单视图
17.索引 index
索引就像字典前的“按拼音/偏旁查询目录”,
可以提高查询效率,降低了增删改的效率。
*数据库内部常用哈希索引,和btree索引
17.1:索引 index 的创建与查询
create [unique] index 索引名
on 表名(列1,列2...)
建1个列上称为单列索引
否则称复合索引
索引信息存放在 user_indexes ,user_ind_columns表
删除索引
Drop index 索引名
17.2:索引 index 的注意事项
在where子句中经常使用的列上创建索引
大量重复的值加索引意义不大
具有唯一值的列是建索引的好的选择,但具体还要看是否经常用他查询。
如果where经常用某N个列一些查询,考虑建复合索引
索引是有代价的--降低了增删改的速度,并不是加的越多越好。
18.事务
原子性(Atomicity):原子意为最小的粒子,或者说不能再分的事物。
数据库事务的不可再分的原则即为原子性。
组成事务的所有查询必须:
要么全部执行,要么全部取消(就像上面的银行例子)。
一致性(Consistency):指数据的规则,在事务前/后应保持一致
隔离性(Isolation):简单点说,某个事务的操作对其他事务不可见的.
持久性(Durability):当事务完成后,其影响应该保留下来,不能撤消
18.1:事务 之事务的用法
开启事务(第1条dml语句即进入事务)
执行sql操作(普通sql操作)
设置保存点(savepoint 保存点)
提交/回滚(commit/rollback)
部分回滚(rollback to 保存点)
18.2:事务的隐式提交
事务可以显式的提交,也可以隐式的提交
显式:commit
隐式: 遇到DDL或DCL语句,或退出系统时
会隐式提交
四:PL/sql编程
1.PL/sql概念
Procedural language
sql是一种标准的数据库访问语言,但无法编程,
PL/SQL是Oracle公司开发的“方言”,允许编程,
是对SQL的一种补充。
2.PL/sql的结构
declare
变量声明部分
begin
执行部分
exception
异常处理部分
End
*:declare 和 exception部分是可选的
默认:调用一个匿名块/存储过程后,只执行不输出
学习调试时: set serveroutput on
3.PL/sql中变量的定义
变量 的定义有2种格式
变量名 变量类型 [约束] default 默认值
变量名 变量类型 [约束] [:=初始值]
-------
变量名 表名%rowtype
变量名 表名.列%type
变量名 另一变量%type
4.PL/sql块中流程控制
5.PL/sql访问数据库
PL/SQL的主要目的是对数据库进行操作,
因此,在PL/SQL块中可以包含select语句,DML语句,
还可以包含DCL语句.
但不能包含DDL语句.
通过SQL语句及流程控制,可以编写复杂的PL/SQL块,
对数据库进行复杂的访问.
注意,PL/SQL一般是在应用程序中调用.
6.附录:PL/sql预定义异常
NO_DATA_FOUND 在使用SELECT INTO 结构,并且语句返回NULL值的时候;访问嵌套表中已经删除的表或者是访问INDEX BY表(联合数组)中的未初始化元素就会出现该异常
TOO_MANY_ROWS 常见错误,在使用SELECT INTO 并且查询返回多个行时引发。如果子查询返回多行,而比较运算符为相等的时候也会引发该异常。
ZERO_DIVIDE 将某个数字除以0的时候,会发生该异常
ACCESS_INTO_NULL 试图访问未初始化对象的时候出现
CASE_NOT_FOUND 如果定义了一个没有ELSE子句的CASE语句,而且没有CASE语句满足运行时条件时出现该异常
COLLECTION_IS_NULL 当程序去访问一个没有进行初始化的NESTED TABLE或者是VARRAY的时候,会出现该异常
CURSOR_ALREADY_OPEN 游标已经被OPEN,如果再次尝试打开该游标的时候,会出现该异常
DUP_VAL_ON_INDEX 如果插入一列被唯一索引约束的重复值的时候,就会引发该异常(该值被INDEX认定为冲突的)
INVALID_CURSOR 不允许的游标操作,比如关闭一个已经被关闭的游标,就会引发
INVALID_NUMBER 给数字值赋非数字值的时候,该异常就会发生,这个异常也会发生在批读取时候LIMIT子句返回非正数的时候
LOGIN_DENIED 程序中,使用错误的用户名和密码登录的时候,就会抛出这个异常
NOT_LOGGED_ON 当程序发出数据库调用,但是没有连接的时候(通常,在实际与会话断开连接之后)
PROGRAM_ERROR 当Oracle还未正式捕获的错误发生时常会发生,这是因为数据库大量的Object功能而发生
ROWTYPE_MISMATCH 如果游标结构不适合PL/SQL游标变量或者是实际的游标参数不同于游标形参的时候发生该异常
SELF_IS_NULL 调用一个对象类型非静态成员方法(其中没有初始化对象类型实例)的时候发生该异常
STORAGE_ERROR 当内存不够分配SGA的足够配额或者是被破坏的时候,引发该异常
SUBSCRIPT_BEYOND_COUNT 当分配给NESTED TABLE或者VARRAY的空间小于使用的下标的时候,发生该异常(类似于java的ArrayIndexOutOfBoundsException)
SUBSCRIPT_OUTSIDE_LIMIT 使用非法的索引值来访问NESTED TABLE或者VARRAY的时候引发
SYS_INVALID_ROWID 将无效的字符串转化为ROWID的时候引发
TIMEOUT_ON_RESOURCE 当数据库不能安全锁定资源的时候引发
USERENV_COMMITSCN_ERROR 只可使用函数USERENV('COMMITSCN')作为INSERT语句的VALUES子句中的顶级表达式或者作为UPDATE语句的SET子句中的右操作数
VALUE_ERROR 将一个变量赋给另一个不能容纳该变量的变量时引发
7.存储过程与存储函数
前面用到的过程和函数都是写在PL/SQL块中,
放在缓冲区里.没有进行保存,
下次要使用了再次声明,调用.
我们可以把过程和函数建立并保存在数据库中,形成一个对象.
这种存储后的过程和函数,称为:
存储过程 存储函数
7.1:存储过程与存储函数创建语法
create or replace procedure 名称[(参数)]
authid current_user|definer --以定义者还是调用者的身份运行
is[不要加declare]
变量声明部分
begin
主体部分
exception
异常部分
end;
7.2:存储过程与存储函数的删除
drop procedure 存储过程名
drop function 函数名
8.游标-cursor
游标是一种私有的工作区,用于保存sql语句的执行结果.
在执行一条sql语句时,数据库服务区工作区,
这里保存了sql语句执行的相关信息
工作区有2种形式的游标,隐式的和显式的.
隐式游标由数据库自动定义,显示游标由用户自己定义.
游标-cursor 简单例子:
begin
delete from student where sid=9;
if SQL%ROWCOUNT>0 then
dbms_output.put_line('影响了');
else
dbms_output.put_line('没影响');
end if;
end;
9.触发器
个人粗暴的解释,就是当某个动作发生之后或者之前触发执行。
9.1:触发器创建语法
u创建触发器的语法
create trigger 触发器名称
after/before/instead of(触发时间)
insert/update/delete [of列名] (监视事件)
on 表名 (监视地址)
[for each row [when条件]]
begin
sql1;
..
sqlN;
end
9.2:触发器的删除
drop trigger triggerName
10.创建用户与删除用户
create user 用户名 identified by “密码"
default tablespace users
temporary tablespace temp
quota 20M on users
password expire
account unlock;
drop user 用户名
如果用户名已经有表,视图等,则不允许删除。
11.修改用户密码
后续附上个人练习一些片段,瞌睡来兮了,偷个懒,很多都是截图了,嘻嘻。。。。。。
Microsoft Windows [版本 10.0.17134.165]
(c) 2018 Microsoft Corporation。保留所有权利。
C:\Users\81046>sqlplus
SQL*Plus: Release 11.2.0.1.0 Production on Thu Aug 16 13:53:36 2018
Copyright (c) 1982, 2010, Oracle. All rights reserved.
Enter user-name:
ERROR:
ORA-01017: invalid username/password; logon denied
Enter user-name: sys
Enter password:
ERROR:
ORA-28009: connection as SYS should be as SYSDBA or SYSOPER
Enter user-name: system
Enter password:
Connected to:
Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options
SQL> select 3
2 select 3 from dual;
select 3 from dual
*
ERROR at line 2:
ORA-00923: FROM keyword not found where expected
SQL> select 3 from dual;
3
----------
3
SQL> create table student(
2 sid number not null,
3 sname char(10)
4 );
Table created.
SQL> insert into student values (1,'wangwu');
1 row created.
SQL> select * from student;
SID SNAME
---------- ------------------------------
1 wangwu
SQL> alert table student add(
SP2-0734: unknown command beginning "alert tabl..." - rest of line ignored.
SQL> alter table student add(
2 area varchar2(20),
3 age number(3,1),
4 height number(3,2)
5 );
Table altered.
SQL> desc student;
Name Null? Type
----------------------------------------- -------- ----------------------------
SID NOT NULL NUMBER
SNAME CHAR(10)
AREA VARCHAR2(20)
AGE NUMBER(3,1)
HEIGHT NUMBER(3,2)
SQL> alter table drop column height;
alter table drop column height
*
ERROR at line 1:
ORA-00903: invalid table name
SQL> alter table student drop column height;
Table altered.
SQL> alter table student modify age number(5,0);
Table altered.
SQL> des
declare
i int :=9;
begin
i:=i*2;
dbms_output.put_line('now i is:'||i);
end;
/
declare
age number default 90;
height number := 175;
gender char(2) := 'mile';
begin
if gender='mile' then
dbms_output.put_line('you can mary with femile');
end if;
if height>170 then
dbms_output.put_line('can play basketebool');
else
dbms_output.put_line('can play footbool');
end if;
if age<20 then
dbms_output.put_line('younth');
elsif age <= 50 then
dbms_output.put_line('seccuss');
elsif age <=70 then
dbms_output.put_line('happniess');
else
dbms_output.put_line('subject');
end if;
end;
存储过程一个没有返回值的函数
create or replace procedure p1(dpnum number) is
cnt number;
sals number;
begin
select count(*),sum(sal) into cnt,sals from emp where deptno=dpnum;
dbms_output.put_line('has '||cnt||'worker,sals is'||sals);
end;
/
create or replace procedure p1(dpnum number) is
cnt number;
sals number;
dn varchar2(14);
dl varchar2(13);
begin
select dname,loc into dn,dl from dept where deptno=dpnum;
select count(*),sum(sal) into cnt,sals from emp where deptno=dpnum;
dbms_output.put_line('localtion:'||dl||'company:'||dn||'has '||cnt||'worker,sals is'||sals);
end;
/
create or replace procedure p1(dpnum number) is
cnt number;
sals number;
dn varchar2(14);
dl varchar2(13);
begin
select dname,loc into dn,dl from dept where deptno=dpnum;
select count(*),sum(sal) into cnt,sals from emp where deptno=dpnum;
dbms_output.put_line('localtion:'||dl||' company:'||dn||'has '||cnt||'worker,sals is'||sals);
end;
/
create or replace procedure p12(dpnum int) is
type dpinfo is record
(
dname varchar2(14),
loc varchar2(13),
cnt int,
sal number
);
dp dpinfo;
begin
select dname,loc into dp.dname,dp.loc from dept where deptno=dpnum;
select count(*),sum(sal) into dp.cnt,dp.sal from emp where deptno=dpnum;
dbms_output.put_line(dp.dname||'--'||dp.loc||'--'||dp.cnt||'--'||dp.sal);
end;
/
create or replace procedure p12(dpnum int) is
type dpinfo is record
(
dname varchar2(14),
loc varchar2(13),
cnt int,
sal number,
);
dp dpinfo;
begin
select dname, loc into dp.dname, dp.loc from dept where deptno=dpnum;
select count(*), sum(sal) into dp.cnt, dp.sal from emp where deptno=dpnum;
dbms_output.put_line(dp.dname||'--'||dp.loc||'--'||dp.cnt||'--'||dp.sal);
end;
/
create or replace procedure p12(dpnum int) is
type dpinfo is record
(
dname varchar2(14),
loc varchar2(13),
cnt int,
sal number,
);
dp dpinfo;
begin
select dname, loc into dp.dname, dp.loc from dept where deptno=dpnum;
select count(*), sum(sal) into dp.cnt, dp.sal from emp where deptno=dpnum;
dbms_output.put_line(dp.dname||'__'||dp.loc||'__'||dp.cnt||'__'||dp.sal);
end;
/
create or replace procedure p13(dpnum int) is
dp dept%rowtype;
dn dept.dname%type;
begin
select deptno,dname,loc into dp.deptno,dn,dp.loc from dept
where deptno=dpnum;
dbms_output.put_line(dp.deptno||'__'||dn||'__'||dp.loc);
exception
when NO_DATA_FOUND then
dbms_output.put_line('sorry NO_DATA_FOUND');
end;
/
以上是表级触发器
监听到表里的数据有更改则触发
create trigger tg1
after insert
on o
begin
dbms_output.put_line('has somone pay goods');
end;
/
create or replace trigger tg2
after insert
on o for each row
begin
update g set cnt=cnt-:new.much where gid=:new.gid;
end;
/
create or replace trigger tg2
after insert
on o for each row
begin
update g set cnt=cnt-:new.much where gid=:new.gid;
dbms_output.put_line('update number');
end;
/
create or replace trigger tg3
before insert on o
for each row
declare
curr number;
begin
select cnt into curr from g where gid=:new.gid;
if curr<:new.much then
:new.much :=curr;
end if;
update g set cnt=cnt-:new.much where gid=:new.gid;
end;
/
create or replace trigger tg3
before insert on o
for each row
declare
curr number;
begin
select cnt into curr from g where gid=:new.gid;
if curr<:new.much then
:new.much :=curr;
end if;
update g set cnt=cnt-:new.much where gid=:new.gid;
end;
/
Microsoft Windows [版本 10.0.17134.228]
(c) 2018 Microsoft Corporation。保留所有权利。
C:\Users\81046>sqlplus sys/root123456 as sysdba;
SQL*Plus: Release 11.2.0.1.0 Production on Fri Aug 17 09:00:03 2018
Copyright (c) 1982, 2010, Oracle. All rights reserved.
Connected to:
Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options
SQL> conn scott/tiger;
Connected.
SQL> show user
USER is "SCOTT"
SQL> select seq1.nextval from dual;
NEXTVAL
----------
21
SQL> create view newgoods as select * from goods where doods_id>1;
create view newgoods as select * from goods where doods_id>1
*
ERROR at line 1:
ORA-00904: "DOODS_ID": invalid identifier
SQL> select * from goods;
GOODS_ID CAT_ID
---------- ----------
GOODS_NAME
--------------------------------------------------------------------------------
1 8
nokia
7 8
fengtian
8 8
food8
GOODS_ID CAT_ID
---------- ----------
GOODS_NAME
--------------------------------------------------------------------------------
9 5
book9
10 5
book10
11 5
book11
6 rows selected.
SQL> create view newgoods as select * from goods where goods_id>1;
View created.
SQL> select * from newgoods;
GOODS_ID CAT_ID
---------- ----------
GOODS_NAME
--------------------------------------------------------------------------------
7 8
fengtian
8 8
food8
9 5
book9
GOODS_ID CAT_ID
---------- ----------
GOODS_NAME
--------------------------------------------------------------------------------
10 5
book10
11 5
book11
SQL> set linesize 2000
SQL> select * from newgoods;
GOODS_ID CAT_ID GOODS_NAME
---------- ---------- ------------------------------------------------------------------------------------------
7