Startup open; 启动数据库实例

select name from v$database;

增加数据库用户:createuser test11 identified by test default tablespace users Temporary TABLESPACETemp;

用户授权: grantconnect,resource,dba to test11; grant sysdba to test11;
commit;
更改数据库用户的密码:(syssystem的密码改为test.)
alter user sys indentified by test;
alter user system indentified by test;

alter user scott account unlock

子查询:

-----查询工资比scott高的员工信息

Select*

From emp

Where sal > (select sal

fromemp

where ename = ‘scott’)

子查询所要解决的问题是:问题不能一步解决

子查询类型:单行子查询(只返回单行记录)和多行子查询

子查询在主查询前一次执行完成,子查询的结果被主查询使用

--注意的问题

1、子查询必须在(),采用一个合理的书写风格,可以在主查询的whereselect from having后面放置子查询。Select 后面只能是单行子查询

2group by后面不可以放置子查询

3、强调from后面放置子查询,这种情况用的最多最重要。

4、主查询和子查询可以不是同一张表,只要子查询返回的结果,主查询可以使用即可

5、一般不在子查询中使用order by。只在一种情况下使用order by :在top-N问题分析中,必须要使用order by

6、一般先执行子查询,但是相关子查询除外。

7、单行子查询只能使用单行操作符,多行子查询只能使用多行操作符。

8、如果子查询返回的结果中含有null,则不可以使用not in (子查询),

Select ename,sal,(select job from emp whereempno = 7893) from emp

Select * from (select ename,sal from emp)

SQl优化:如果子查询和多表查询都可以解决问题,理论上尽量使用多表查询

多行子查询:

In:等于列表中的任何一个

Any:和子查询返回的任意一个值比较

//查询比30号部门任意一个员工高的员工信息

Select* from emp where sal any(select sal

from emp where deptno=30)

All:和子查询返回的所有值比较



查询不是老板的员工信息not in (...,null)问题

Select * from emp where empno notin (select mgr from emp

Wheremgr is not null)

如果结果集中含有null,不可以使用not in,但是可以使用in,因为所有金额null值比较的值都会为nullnot in 等同于<>all ,in == any

A not in(10,20,null)==A!=10and a!=20 and a!=null

A =20,A in (20,10,null)==a=20 or a=10 or a=null


集合运算

--查询 1020号部门的员工

交集:intersect

差集:minus

并集unionunion all

Select *from emp where deptno = 10

Union

Select *from emp where deptno = 20

1、参与运算的各个集合必须列数相同并且类型一致

2、采用第一个集合的表头作为最后的表头

3、如果要排序必须在每个集合后使用相同的order by

4、可以使用括号

Selectdeptno,job,sum(sal) from emp group by rollup(deptno,job)

Select deptno, job,sum(sal) from emp group by deptno,job

Union

Selectdeptno,to_char(null),sum(sal) from emp group by deptno

Union

Selectto_number(null),to_char(null),sum(sal) from emp;


/---------------------------------------------------------------/

DML语句:(dml就是增删改查,在sql中没有人叫crud(可以rollback)

DDL语句:Create/alter/drop/truncate/table

Create/dropview

Create/dropindex(sequence)(不可以rollback)

DCL语句:commit/rollback

隐式插入null值:执行insert语句,有些咧没有指定,则默认为其默认值或者null

显示插入nullvalues(null)

--地址符 & ,类似于PrepareStatement,可以防SQl注入等问题

Insert into emp(empno,sal) values(‘&empno’,&sal)---输入 --/

地址符可以用在任意的DML语句中

Select &condi from emp---sal

数据的批量拷贝插入

Create table emp2 as select * from emp where1=2;

一次性奖emp中所有20号部门的员工插入到emp2表中

Insert into emp2 select * from emp wheredeptno = 20;



Updatetable set column = value,[..] where condition

需要注意更新中的数据完整性错误,也即是约束问题

Delete[from] table [where condition] / Truncate table

Deletetruncate的区别:

1、deleteDML语句,truncateDDL语句,delete可以rollback

2、truncate先摧毁表在重建,delete逐条删除

3、从理论上讲truncate性能比delete,但实际上在oracledelete性能比truncate性能好。

4、理论上讲Delete逐条删除会产生碎片,truncate不会

5、Delete不会释放空间,但是truncate


Oracle数据库事务:原子性、一致性、隔离性、

1、事务的起始标志:DML语句

2、事务的结束标志:显示提交commitrollback

隐式提交 DDL语句(insert-update delete这些除了自身的基本功能外,还含有隐式的提交功能)

正常退出 exit

事务的控制:

Commit – delete – 保存点A – insert – update – 保存点b – insert(出现错误)

Insertinto ...

SavepointA

Insertinto ...(错误)

Rollbackto savepoint A


Sql99事务的隔离级别:

Read uncommited read commited repeatable readserializable

Oracle支持的sql 99中的2个隔离级别:read commited(默认)serializableoracle一共有3个隔离级别,还有一个read only


DDL语句创建和管理表:

常见的数据库对象:

表:基本的数据存储集合,由行和列组成

视图:从表中抽出的逻辑上相关的数据集合

序列:提供有规律的数值

索引:提高查询的效率

同义词:给对象起别名

表名和列名必须在1-30个字符之间,oracle默认的存储时为大写,数据库名称必须是1-8位和

Create table:必须有权限、存储空间 // 使用子查询创建表,如果子查询中有表达式,就必须给表达式去个别名

Create table emp2

As

Select empno,ename,sal*12 ‘年薪’ from emp where empno > 5000;

Varchar2(size)可变长字符数据

Char(size)定长字符数据

Number(p,s)可变长数据类型

Data日期类型

Long可变长字符数据,最大可达到2G

CLob字符数据,最大可达4G

Raw and long raw 原始的二进制数据

Blob二进制数据,最大可达4G

Bfile存储外部文件的二进制数据,最大可达4G

Rowid行地址

上述数据类型除了rowid其余的都是作用在列上面的数据类型

Select rowid ,empno from emp;//rowid就相当于一个指针

索引就相当于rowid

修改表:追加新列、修改列、删除列、重命名列

Alter table emp2 add photoUrl blob;

Alter table emp2 modify ename varchar2(40);

Alter table emp2 drop column photoUrl;

Alter table emp2 rname column photoUrl tophoto;

Droptable emp2;//并没有实际的删除表

Oracle的回收站机制:

查看回收站:showrecyclebin

清空回收站:purge recyclebin

Droptable emp2 purge//删除表,不经过回收站,彻底的删除

并不是所有的用户都有回收站(管理员没有回收站,回收站只针对普通的用户)


约束:

约束是表一级的限制

如果存在依赖关系,约束可以防止错误的删除数据

类型:

Not null uniqueprimary keyforeign keycheck

Sex varchar2(4) check(sex in (‘’,’’))

Sal number check (sal > 0)

Frorign key:在字表中,定义一个表级的约束

References:指定表和附表中的列

On delete cascade:当删除父表时,级联删除子表记录(很危险,和他相关的有n张,但是只想删一张)

On delete set null:将字表的相关依赖记录的外建设置为null(常用)

Sal number(2) constraintemp_sal_min check(sal > 0)






Create table person(

Pidvarchar2(18) constraint person_Key primary key,

Pnamevarchar2(4) constraint person_name nut null,

Sexvarchar2(4)constraint person_sex check(sex in (‘’,’’))

Emailvarchar2(30) constraint person_email unique

Deptnonumber constraint peron_pk reference dept(deptno) on delete cascade

)


视图:(需要被授权grant create view to scott)

Create or replace view empView1(如果存在就替换)

As

Select empno,ename,sal,sal*12 annl fromemp;

With read only (屏蔽DML操作)

Select * from enpView1

优点:简化查询、限制数据的访问(银行用的最多)、同样的数据有不同的显示形式、

视图不能提高性能只能简化查询。

不建议通过视图对表进行修改,视图只能创建(create)和替换(replace)

Create view view1

As

Select * from emp where deptno =10

With check option

Insert into view1 values(...,10);

Insert into view1 values(...,20);

创建视图之前,写sql语句该怎么写就怎么写,


序列sequenceauto_increment(mysql),这两个功能一样

序列就是一个数组,如果在创建的时候不指定任何的参数,内存:[1,2,...20][21.. 40]

序列在内存中,如果停电(目前在4),恢复电后从21开始,这就造成序列不连续

什么是序列:

CreateSwquence sequence

Incrementby n,

Startwith n

Maxvaluen | nomaxvalue(min)

Cycle| nocycle

Cachen | nocache

序列是一个共有对象,A可用、b可用,这样也造成不连续

序列的属性:Nextvalcurrvalnextval应该在currval之前指定

Create sequence myseq;

Create table testSq(tid number,tnamevarchar2(20));

Select myseq.currval from dual;//error

Select myseq.nextval from dual;

Insert into testsq valus(myseq.nextval,’aa’)

回滚之前的操作也会造成序列的不连续

Alter|drop sequence mysq .... 修改序列只会影响以后的值



索引:

通过指针加速oracle服务器的速度

Create|drop index myindex on emp()

条件:

首先必须是大表

列数据值分布的特别散

列经常在where字句或链接条件中出现

表经常被访问而且数据量很大,访问的数量占据数据总量的2%4%


同义词:

Conn hr/hrshow user



PLSQL语法:过程语言的sql语句,是对sql语言的过程化扩展,指在sql命令中增加了过程处理语句(分支、循环等),使得sql语言具有过程处理能力,plsql是执行最快的。

Declare变量的说明

begin

dbms_output.put_line(‘helloworld’);Syso.println()

end ;

在默认情况下oracle输出开关是关闭的,set serveroutput on

/ 执行上一条sql

Descdbms_output

Declare说明部分(变量说明、光标声明)

Begin

语句序列

Exception

例外处理语句

End

说明变量:charvarchar2datenumberbooleanlong

Marriedboolean:=true

Psalnumber(7,2)

My_nameemp.ename%type;引用类型,emp表中列ename的类型

Emp_recemp%rowtype 记录性变量






--引用变量:打印7839的姓名和薪水

Declare

penameemp.ename%type;

psalemp.sal%type;

Begin

Selectename,sal into pename,psal from emp where empno=7839;

Dbms_output.put_line(pename||’薪水是’||psal)

End;


Emp_rec Emp%rowtype;代表一行的类型,如果有多列,引用Emp_rec.ename

Declare

Emp_rec Emp%rowtype;

Bigin

Select* intoemp_rec from emp where empno=7839

Dbms_output.put_line(emp_rec.ename||’的薪水是’emp_rec.sal)

End;


If语句:

If 条件 then 语句1;语句2;end if;

If 条件 then 语句1;else 语句2;end if;

If 条件 then 语句1;else if 语句2; else 语句3;end if;

判断用户输入的数字

Accept(sqlplus命令, 接收键盘输入) num prompt ‘请输入一个数字

按职工的职称张工资,总裁涨1000,经理800

Declarepjob varchar2(20);

Bigin

Selectjob into pjob from emp where empno = 7839;

Ifpjob=’ceo’ then update emp set sal=sal+1000 where enopno=7839

Elseif ..

End;















While

-while

While total<=2500

Loop

...

Total := total + sal;

End loop

--do while

Loop

Exit[when 条件]

...

End loop;

--for

For I in 1...2

Loop

语句序列

End loop

For pename in (select ename from emp)

Loop

End loop;

1、提示信息

2、接收键盘输入

3num是一个地址,存放数字

sql优化:num绑定变量

select * from emp where deptno = 10//执行计划

select * from emp where deptno = 20 //执行计划

这两句是不一样的,在执行前会生成一个执行计划,这两个执行计划一样,(参数不一样)

select * from emp where deptno = #//这样执行计划是一样的,会提高性能

accept num prompt '请输入一个数字'

declare

pnumber number := #

begin

loop

exit when pnumber > 10;

dbms_output.put_line(pnumber);

pnumber := pnumber + 1;

endloop;

end;


declare


光标:用于存储一个查询返回的结果集

Cursor 光标名[(参数类型)]Is select 语句

在使用一个光标之前要打开 open XX,就相当于执行一条sql语句

取一行光标的值:fetch c1 into pjobfetch作用是取出数据并且将光标移到下一项、行.光标打开后可以不关闭,但是oracle默认不关闭的最大光数300(show parameters cursor)

光标的三个属性:

Isopen 是否被打开truefalse

Rowcount 行数

Notfound是否有值

Declare

Cursorcemp is select ename,sal from emp;

Penameemp.ename%type;

Psalemp.sal%type;

Begin

Opencemp;

Loop

Fetchcemp into pename,psal;

Exitwhen cemp%notfound;//光标中没有值就退出

Dbms_output.put_line(pename||’薪水是’||psal);

Endloop;

Closecemp;

End;

按职工的职称张工资,总裁涨1000,经理800

Declare

Cursorcemp is select empno,type,sal,from emp;

pempnonumber;

ptypevarchar2(5);

psalnumber;

Begin

Opencemp;

Loop

Fetchcemp into pepno,ptype,psal;

Eixtwhen cemp%notfound;

Ifptype = ’总裁’ then update emp set sal = psal+1000 where empno = pempno;

Elseifptype = ’经理’ then update emp set sal = psal+800 where empno = pempno;

Elseupdate emp set sal = psal+400

Endloop;

Closecemp;

Commit;(原因是隔离级别(默认读已提交),不提交在另一个命令行看不到结果)

End;

带参数的光标:

查询某个部门的员工姓名(要带部门参数)

Declare

Cursorcemp(pdno number) is select ename from emp where deptno = pdno;

Opencemp(10);//10号部门

。。。。。。。。。省略


例外是用来增强程序的健壮性和容错性

系统例外:(oracle的命名规范,_、大写)

Not_data_found(没有找到数据)

Too_many_rows(select …into语句匹配多行)

Zero_divide(被零除)

Value_error(算数或转换错误)

Time_on_resource(在等待资源时发生超时(分布式))

declare n number;

begin

n := 1/0;

exception

when Zero_divide then dbms_output.put_line('0不能做被除数');

when value_error then dbms_output.put_line('转换异常');

when others then dbms_output.put_line('其他的异常');

end;

用户自定义的例外

这些例外需要用户处理,用户最好不要抛给数据库去处理when others

Declareno_data exception;//没有数据例外

Fetchc1 into job;

Ifc1%notfound then raise no_data;

Endif;

...

Exception

Whenno_data then insert into log values(‘..’);

End