Oracle sql语句集

  • Post author:
  • Post category:其他


/*

–Oracle体系结构

数据库:在oracle数据库中只有一个库

实例:由本地磁盘文件构建(控制文件,日志文件,数据库文件) 包含进程(服务)

用户;oracle管理面向使用用户。

表空间:存储数据逻辑单位。

数据文件:存储数据物理单位。表空间跟数据文件进行关联:表空间-数据文件:一对多

*/

—-=================================


在管理员用户system/orcl登陆

–表空间


表空间创建代表项目开始

/*

语法:

create tablespace 表空间名称

datafile ‘数据文件磁盘目录’

size 500m

autoextend on/off

next 50m;

*/

create tablespace demo

datafile ‘c:\lih.dbf’ –数据文件格式 dbf/ora

size 500m

autoextend on

next 50m;

–删除表空间(不建议)

drop tablespace demo including contents and datafiles;

—–用户

/*

语法:

create user 用户名 identified by 密码

default tablespace 表空间名称;

*/

–通过命令创建用户没有任何权限

create user root identified by root

default tablespace demo; –用户关联表空间。将来登陆此用户后,操作表空间中数据,真正数据改变在磁盘中数据文件\

/* TEMPORARY TABLESPACE temp;(这里临时表空间不能使用我们创建的db_test */

–给用户进行授权

/*

授予角色:connect,resource,dba

授予权限:create table,create session,create view…

角色是权限集合

*/

grant create session to root;

grant connect,resource to root;

–回收

revoke connect from root

–==============









使用自定义用户登陆









=

/*

DDL:数据定义语言 create drop alter

DML:数据操作语言 insert update delete

DCL:数据控制语言 grant revoke

DQL:数据查询语言 select

oracle数据类型:

数值:number(a,b) a代表数值长度 b代表小数位个数

*整数 number(3) 999

*小数 number(3,2) 9.99

字符串:

*char:定长度字符串类型 name char(10) 最大长度4000

*varchar:可变长度字符串类型 name vachar(10) 最大长度4000

*varchar2:可变长度字符串类型 oralce声明

日期:

date:年月日时分秒

timestamp:时间戳,精确到秒后9位

大数据类型:

clob:字符类型。存储字符最大4G

blob:字节数据类型。存储4G

创建表

对表进行字段更改操作

数据CURD

*/

create table person(

id number(9) primary key,

name varchar2(30),

gender char(1) default 1

)

– 单独设置主键 (id number(9) primary key)

alter table person

add primary key (id)

using index

tablespace demo

pctfree 10

initrans 2

maxtrans 255;

– 给表增加描述信息(***)

comment on table person is ‘这是一个测试的表’;

comment on column person.id is ‘这是测试表的id’;

comment on column person.name is ‘这是测试表的name’;

–新增默认为空的字段

–ALTER TABLE 表名 ADD COLUMN 字段名 字段类型 DEFAULT NULL;

–增加字段

alter table person add address varchar2(100);

–多列新增

alter table person add (c1 varchar2(30),c2 varchar2 (30));

–修改字段类型

alter table person modify address varchar2(200)

alter table test1 modify (c1 varchar2(50) , c2 varchar2 (50));

–重命名字段名称(修改列名)

–ALTER TABLE 表名 RENAME COLUMN 列名 TO 新列名

alter table person rename column address to address1;

–删除字段

alter table person drop column address1;

–新增数据

–oracle事务需要手动提交

insert into person values(1,‘jack’,0);

–commit;

rollback;

insert into person(id,name) values(2,‘rose’);

commit;

–删除数据

delete from person where id = ‘1’;

– 修改数据

update person set(name = ‘jack1’,gender = ‘女’) where id =‘1’

—-oracle数据库中如何实现主键值自动增长——–序列sequence

/*

序列跟表是两个独立对象,一般在主键值生成使用序列对象来实现。

创建语法:

create sequence 序列名称;

删除语法

DROP SEQUENCE 序列名称;

使用:

select 序列名称.nextval

select 序列名称.currval

*/

–创建序列

create sequence seq_person;

–删除序列

DROP SEQUENCE seq_person;

–使用序列(查询序列值,新增数据使用) 在oracle数据库中有伪表(虚表)dual ,补全oralce语法。有select 必须有from

select seq_person.nextval from dual;

–在新增数据使用序列对象

insert into person values(seq_person.nextval, ‘张三111’, 1);

commit;

select * from person;

select seq_person.currval from dual;

–查询oarcle服务器端编码 ***

select userenv(‘language’) from dual;

–在客户端所在服务器(本地)配置环境变量 key:NLS_LANG value:编码 AMERICAN_AMERICA.ZHS16GBK

–创建序列完整语法

create sequence seq_test

start with 1

increment by 5 –设置步长

maxvalue 50 –最大值 minvalue

cycle –循环

cache 20; –缓存 序列个数 默认就是20个

–新建序列必须先执行一次nextval属性获取下一值 之后才能调用currval获取当前值

select seq_test.nextval from dual;

select seq_test.currval from dual;

/*

– 外键

alter table 从表名

add foreign key (外键id)

references 主表名 (主表id) on delete cascade;

*/

–约束 :主键 外键 唯一 非空 检查约束

drop table person;

create table person(

id number(9) primary key,

name varchar2(30) not null unique,

gender char(1) default 1 check(gender in(0,1)) –检查约束

)

insert into person values(seq_person.nextval,‘jack’,1);

commit;

–班级表(一方)-学生表(多方):一对多:

create table t_class(

id number(9) primary key,

name varchar2(200) not null

)

–子表外键字段跟父表主键字段关联

create table t_student(

id number(9) primary key,

name varchar2(200) not null,

class_id number(9),

constraint fk_stu_cls foreign key(class_id) references t_class(id)

)

–序列

create sequence seq_class;

create sequence seq_stu;

insert into t_class values(seq_class.nextval,‘一年级三班’);

commit;

select * from t_class;

select * from t_student;

insert into t_student values(seq_stu.nextval,‘jack’,5);

commit;

———================================scott用户

–使用命令解锁用户 lock unlock

alter user scott account unlock;

–重置密码

alter user scott identified by tiger;

select empno,ename ,job,sal,comm,deptno,mgr,hiredate from emp;

select d.deptno,d.dname,loc from dept d;

–========================






函数







/*

单行函数:作用于一条记录得到一个结果

多行函数:作用于多条记录得到一个结果

*/

–单行函数

–字符串函数

–全大写

select upper(‘abc’) from dual;

–全小写

select lower(‘ABC’) from dual;

–拼接字符串

select concat(‘a’,‘b’) from dual;

select ‘a’||‘b’||‘c’ from dual;

–数值函数

–四舍五入

select round(15.66,1) from dual;

–日期函数

/*

日期-日期=天数

日期-天数=日期

*/

select sysdate from dual;

select ename,sysdate-e.hiredate from emp e

–间隔月份 months_between

select ename,round(months_between(sysdate,e.hiredate)) from emp e

–转换函数 to_char to_number to_date ***

select to_char(123),123 from dual;

select to_char(45434534554.16,‘L999,999,999,999.99’) from dual;

select to_number(‘123’) from dual;

–将字符串转为日期类型

select to_date(‘2019/12/5 12:45:20’,‘YYYY-MM-dd hh:mi:ss’) from dual;

select to_char(sysdate, ‘fmyyyy-mm-dd hh24:mi:ss’) from dual;

–通用函数 decode(val,v1,v11,v2,v22,vn)判断

–将员工工作展示位中文

select e.empno,

decode(e.job, ‘CLERK’, ‘店员’, ‘SALESMAN’, ‘销售’, ‘MANAGER’, ‘经理’, ‘ANALYST’, ‘分析师’, ‘资本家’) job

from emp e

–case when

/*

case val

when ‘’ then ‘’

when ‘’ then ‘’

else

‘’

end

*/

select e.ename,

case e.job

when ‘SALESMAN’ then ‘销售’

when ‘CLERK’ then ‘店员’

else

‘其他人员’

end job

from emp e;

–处理空值 null+数字=null 使用nvl(value, a)

–查询员工年薪

select nvl(‘b’, ‘a’) from dual;

select e.ename,e.sal*12+nvl(comm,0) from emp e;

–====多行函数

select count(*) from emp; –总个数

select sum(sal) from emp; –求和

select avg(sal) from emp; –平均数

select max(sal) from emp; –最大值

select min(sal) from emp; –最小值

—===============分组统计查询 group by

/*

select column… from tab1,tab2 where … group by column having …

*/

–总结:查询普通字段跟聚合函数一块使用,

–在select中出现普通字段必须在group by中出现

–group by中出现普通字段 不一定必须要在select中出现

–查询每个部门人数

select e.deptno, count(*)

from emp e

group by e.deptno;

–查询每个部门平均工资

select e.deptno,avg(sal)

from emp e

group by e.deptno;

–查询部门员工数量 以及 部门名称

–查询每个部门数量

select e.deptno, count(*) dcount

from emp e

group by e.deptno;

–将查询结果当成表使用

select d.dname,t.dcount

from (select e.deptno, count(*) dcount

from emp e

group by e.deptno) t,dept d

where d.deptno = t.deptno

–查询部门平均工资大于2000

–where 用于分组之前 having用户分组后结果进一步筛选

select e.deptno,avg(sal)

from emp e

group by e.deptno

having avg(sal)>2000;

—-================================多表查询

/*

内连接:关联查询如果条件不满足,关联记录不显示

外连接

子查询

*/

–查询员工表,部门表

select * from emp,dept; –笛卡尔积

–在笛卡尔积基础上进步设置关联条件得到内连接

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

select e.ename,d.dname from emp e inner join dept d on e.deptno = d.deptno;

–查询每个员工上级领导

select e1.

,e2.ename

from emp e1,emp e2

where e1.mgr = e2.empno

–在上面基础上查询员工部门信息

select e1.

,d.dname,e2.ename

from emp e1,emp e2,dept d

where e1.mgr = e2.empno

and e1.deptno = d.deptno

–查询员工工资等级,领导工资等级 引入工资登记表salgrade

select e1.*,d.dname,s1.grade ,e2.ename,s2.grade

from emp e1,emp e2,dept d,salgrade s1,salgrade s2

where e1.mgr = e2.empno

and e1.deptno = d.deptno

and e1.sal between s1.losal and s1.hisal

and e2.sal between s2.losal and s2.hisal;

select e1.*,d.dname,

decode(s1.grade,1,‘一级’,2,‘二级’,3,‘三级’,‘四级’) esalgrade

,e2.ename,s2.grade

from emp e1,emp e2,dept d,salgrade s1,salgrade s2

where e1.mgr = e2.empno

and e1.deptno = d.deptno

and e1.sal between s1.losal and s1.hisal

and e2.sal between s2.losal and s2.hisal;

–=====================外连接

/*

外连接:关联查询即使关联条件不成立,查询基础表对应记录也应该展示。

左外连接:select c… from tab1 left join tab2 on 条件。 tab1记录展示

右外连接:select c… from tab1 right join tab2 on 条件。 tab2记录展示

oracle特有外连接: 内连接语法上加 (+)

select … from tab1,tab2 where tab1.a = tab2.b(+)

*/

–即使员工没有上级领导。

select e1.*,e2.ename

from emp e1 left join emp e2 on e1.mgr = e2.empno

–(+)加在哪张表条件上,对面表记录全部展示

select e1.*,e2.ename

from emp e1,emp e2

where e2.empno(+) = e1.mgr

—-========================子查询

–查询比7654员工 工资高员工

select sal from emp where empno = 7654

select * from emp where sal >(select sal from emp where empno = 7654)

–查询每个部门最低工资员工信息

–查询每个部门最低工资

select e.deptno, min(sal) dminsal

from emp e

group by e.deptno;

–思想:将查询结果当成表使用

select e.*,d.dname,t1.dminsal

from (select e.deptno, min(sal) dminsal

from emp e

group by e.deptno) t1,dept d, emp e

where t1.deptno = d.deptno

and e.sal = t1.dminsal

and e.deptno = t1.deptno;

—================================分页查询

/*

rownum:是伪列,查询结果每条记录都会分配行号

rowid:是伪列,是记录唯一标识

*/

select * from emp where rowid = ‘AAAMfPAAEAAAAAgAAD’

select rownum,rowid,e.* from emp e where sal>1500;

–pageNum,pageSize:3

select rownum,e.* from emp e where rownum<=3

–第二页 问题:rownum不能使用大于号。记录不显示

select rownum,e.* from emp e where rownum<=6 and rownum>3

–rownum生成时机:查询结果一条条加载展示,没加载一条记录给记录分配行号

–没有排序字段

select * from (select rownum r,e.* from emp e) t1 where t1.r>3 and t1.r<=6

–加入排序字段-数据错乱

select * from (select rownum r,e.* from emp e order by e.sal) t1 where t1.r>3 and t1.r<=6

–先排序,再分配行号,使用行号

select * from (select rownum dr ,t1.* from (select * from emp e order by e.sal)t1)t2 where t2.dr>3 and t2.dr<=6

–公式

select * from (select rownum dr ,t1.* from (select * from emp e order by e.sal)t1)t2 where t2.dr>(pageNum-1)

pagesize and t2.dr<=pageNum

pageSize

select * from emp;

select * from dept;

select * from salgrade;

—===================exists & not exists 存在/不存在

/*

语法:select … from tab where exists (查询)

条件boolean类型:如果查询有结果返回true ,结果全部展示 。如果查询null,返回false,结果不展示

*/

select * from emp where exists(select * from dept)

select * from emp where 1=2

–查询有员工部门记录(如果部门编号在员工表中出现(存在),说明该部门有员工)

select * from emp;

select * from dept;

select * from dept d where exists(select * from emp e where d.deptno = e.deptno)

–================================视图

–查询当前用户权限

select * from session_privs;

select * from session_roles;

–注意:需要使用system用户给scott用户授权

grant dba to scott;

/*

视图:是一张虚拟表,视图本身不存放数据,数据来源于原始表。视图跟表是映射关系

语法:create [or replace] view 视图名称 as select 语句;

应用:1、封装一条复杂查询语句。

2、隐藏一些敏感数据

3、设置只读

*/

create or replace view v_emp20 as select * from emp where deptno = 20;

create or replace view v_emp as select empno,ename,job,hiredate from emp;

–使用视图(跟使用表基本一样)

select * from v_emp20;

select * from v_emp;

update v_emp20 set ename = ‘jack’ where empno = 7369;

–创建只读视图

create or replace view v_emp as select * from emp with read only;

update v_emp set ename = ‘jack’ where empno = 7369;

commit;

–=============================索引

/*

索引:为了提高检索效率。

语法:create index 索引名称 on 表名(列名1,列名2)

*/

create table person(

id number(8) primary key,

name varchar2(30) not null

)

alter table person modify name varchar2(100);

–模拟添加百万数据

select sys_guid() from dual;

declare

vname varchar2(100);

begin

for i in 1…1000000 loop

select sys_guid() into vname from dual;

insert into person values(i,vname);

end loop;

commit;

end;

select * from person where name = ‘943C452F14774AEDA2C1DBC78FEBEB92’; –没有创建索引查询–0.64s

–创建索引

create index idx_person_name on person(name);

–再次在有索引表中查询

select * from person where name = ‘4308BDBBA2E34BB0AA8E5F5258EB2160’; –0.015

/*

索引使用:

1、在数据量大的表上使用序列。

2、在表中经常用于查询列上使用索引。

3、复合索引(给多列创建索引)列最好不要超过四个。

*/

–======================sql/sql

/*

pl/sql:过程化语言/结构化查询语言-编程

plsql结构:

[declare]

–定义部分

begin

–函数体

[exception]

–处理异常

end;

*/

–定义变量/常量

declare

i constant number(3) := 1; – :=赋值

–pname varchar2(2); –定义变量

pname emp.ename%type; –定义引用型变量-引用某种表中某一列类型

pemp emp%rowtype; –记录型变量-通过变量保存某张表中一条记录

begin

–i:=2; 常量不能重新赋值

dbms_output.put_line(‘i的值:’||i); –在控制台输出打印

–将查询得到结果给某个变量赋值

select ename into pname from emp where empno = 7369; –查询得到结果 通过into关键字赋值

dbms_output.put_line(‘7369姓名为:’||pname);

select * into pemp from emp where empno = 7654; –给记录型变量赋值

dbms_output.put_line(‘7654的姓名:’||pemp.ename||’,工作:’||pemp.job);

end;

–==================================if 判断

/*

语法:

if 条件 then

逻辑

elsif 条件 then

逻辑

else

逻辑

end if;

*/

–判断变量值

declare

i number(4) := &pnum; –&变量名称(任意) 从控制录入

begin

if i = 1 then

dbms_output.put_line(‘我是1’);

else

dbms_output.put_line(‘其他’);

end if;

end;

–判断值

declare

score number(3) := &score;

begin

if score <= 20 then

dbms_output.put_line(‘青铜’);

elsif score > 20 and score <= 50 then

dbms_output.put_line(‘白银’);

else

dbms_output.put_line(‘王者’);

end if;

end;

–==============================循环—-

/*

语法一: while循环

while 循环条件 loop

循环体;

end loop;

语法二: loop循环

loop

循环体

exit when 退出条件;

end loop;

语法三: for循环

for i in 1.。10 loop

循环体

end loop;

*/



declare

i number(3):=1;

begin

while i <=10 loop

dbms_output.put_line(i);

i:=i+1;

end loop;

end;



declare

i number(3):=1;

begin

loop

dbms_output.put_line(‘loop’||i);

i:=i+1;

exit when i>10; –退出条件

end loop;

end;



declare

begin

for i in 1…10 loop

dbms_output.put_line(‘for ‘||i);

end loop;

end;

–===================游标 cursor

/*

游标:存放结果集,返回多条记录存放到游标中。

游标定义在declare部分定义:

cursor 游标名称 is 查询语句;

*/

–将20号部门员工存放到游标中,打印每个员工信息

declare

pemp emp%rowtype;

cursor pc is select * from emp where deptno = 20;

begin

open pc;

loop

fetch pc into pemp; –从游标中取数据

exit when pc%notfound; –游标中数据全部提取完毕 退出循环

dbms_output.put_line(‘姓名:’||pemp.ename||’,工作:’||pemp.job);

end loop;

close pc;

end;

–给员工进行涨工资 销售加500 经理加300 总裁加100

declare

addsal number(3):=0; –定义动态加工资金额

cursor pc is select * from emp;

pemp emp%rowtype; –记录型变量用于存放遍历过程中获取到的员工记录

begin

open pc;

loop

fetch pc into pemp;

exit when pc%notfound;

if pemp.job = ‘SALESMAN’ then

addsal:=500;

elsif pemp.job = ‘MANAGER’ then

addsal:=300;

elsif pemp.job = ‘PRESIDENT’ then

addsal:=100;

else

addsal:=0;

end if;

update emp set sal=sal+addsal where empno = pemp.empno;

end loop;

commit;

close pc;

end;

select * from emp;

–==============================存储过程

/*

存储过程:实现编译好一组sql语句集,为了完成特定功能一组业务逻辑。

实现编译好存放在数据库服务器端。应用程序通过过程名称进行调用进而完成某个业务功能

好处:效率高(提前编译好)

弊端:维护成本高

语法:

create [or replace] procedure 过程名称(参数1 in|out 类型,。。。。)

as|is –定义变量

begin

– 程序体

end;

*/

–使用过程实现helloworld

create or replace procedure pro_helloworld

is

a varchar2(30):=‘hello world procedure’;

begin

dbms_output.put_line(a);

end;

–执行过程,进行编译。如果有语法错误没有提示

–调用(自测)

–方式一:

call pro_helloworld();

–方式二:可以定义变量存放过程返回结果

declare

begin

pro_helloworld();

end;

–过程实现:给某个员工进行涨工资,输出涨前跟涨后工资。

create or replace procedure pro_add_sal(pno in number,money in number)

is

oldsal emp.sal%type;

newsal emp.sal%type;

begin

select sal into oldsal from emp where empno = pno;

dbms_output.put_line(‘涨前工资:’||oldsal);

update emp set sal=sal+money where empno = pno;

commit;

select sal into newsal from emp where empno = pno;

dbms_output.put_line(‘涨后工资:’||newsal);

end;

–调用

call pro_add_sal(7369, 50);

–使用过程查询某个员工年薪

create or replace procedure pro_total_sal(pno number, total out number)

is

begin

–查询结果给输出参数赋值

select sal*12+nvl(comm,0) into total from emp where empno = pno;

end;



declare

t number;

begin

pro_total_sal(7369, t);

dbms_output.put_line(‘年薪:’||t);

end;

—==================================存储函数

/*

实现编译好一组sql语句集,为了完成特定功能一组业务逻辑。

实现编译好存放在数据库服务器端。应用程序通过过程名称进行调用进而完成某个业务功能

语法:

create or replace function 函数名称(参数1 in|out 类型,。。。。) return 类型

is

begin

return 变量; –该变量类型一定要跟函数指定返回值类型一致

end;

*/

–查询某个员工年薪

create or replace function fun_total_sal(pno number) return number

is

totalsal number(9);

begin

select sal*12+nvl(comm,0) into totalsal from emp where empno = pno;

return totalsal;

end;

–调用

declare

total number;

begin

total:=fun_total_sal(7369);

dbms_output.put_line(total);

end;

/*

函数过程区别:

相同:从完成特定功能来说,函数能实现过程也可以实现。

不同:语法不一样,函数必须有返回值。 函数可以用在select部分部分

*/

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

–需求:根据部门编号返回部门名称

create function fun_dname(dno number) return varchar2

is

dname dept.dname%type;

begin

select dname into dname from dept where deptno = dno;

return dname;

end;



declare

d varchar2(20);

begin

d:=fun_dname(10);

dbms_output.put_line(d);

end;

–将函数用在select

select ename,fun_dname(deptno) dname from emp;

—===========================触发器 trigger

/*

理解:给某张表安装监视器监控表中数据,一旦外部对表中记录做操作(增删改)触发 触发器逻辑。符合规则后方可提交

数据库触发器是一个与表相关联的、存储的 PL/SQL 程序。每当一个特定的数据操作语句

(Insert,update,delete)在指定的表上发出时, Oracle 自动地执行触发器中定义的语句序列。

语法:

create or replace trigger 触发器名称

after|before

insert|update|delete

on 表

declare

begin

–程序体

end;

*/

–新增用户后,在控制台输出‘新员工入职’

create or replace trigger tri_after_emp

after

insert

on emp

declare

begin

dbms_output.put_line(‘新员工入职’);

end;

insert into emp(empno,ename) values(5555,‘rose’);

commit;

–在周末不能办理入职

create or replace trigger tri_before_emp

before

insert

on emp

declare

weekend varchar2(10);

begin

select trim(to_char(sysdate,‘day’)) into weekend from dual; –查询触发器执行当前系统日期获取星期数

if weekend in(‘sunday’,‘saturday’) then

raise_application_error(-20001,‘周末不能办理入职’);–抛出异常 参数一:异常返回编号取值:-20001~ -20999 参数:提示字符串

end if;

end;

–不能给员工降薪

create or replace trigger tri_before_sal_emp

before

update

on emp

for each row –行级触发器(每条记录操作都会触发) 如果使用:old :new获取旧记录,新记录需要加for each row

declare

begin

if :old.sal>:new.sal then –sal值不能减少

raise_application_error(-20002,‘不能给员工降薪’);

end if;

end;

update emp set sal = sal-1 where empno = 7369;

commit;

insert into emp(empno,ename) values(6666,‘zhangsan’);

commit;

select * from emp;



版权声明:本文为weixin_45542377原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。