oracle重点
来源:互联网 发布:linux root 查看密码 编辑:程序博客网 时间:2024/05/22 17:33
一. 实例
1.使用plsql打印9*9乘法表
declare
x number:=1;
y number:=1;
begin
for x in 1..9 loop
for y in 1..9 loop
if y<x+1 then
dbms_output.put(x||'*'||y||'='||x*y||' ');
end if;
end loop;
dbms_output.put_line(' ');
end loop;
end;
2.使用plsq输出 1-1000中所有的质数 (只能被1和自己整除的数)
declare
flag boolean;
begin
for i in 2..1000 loop
flag:=true;
for j in 2..trunc(i/2)loop
if(mod(i,j)=0)then
flag:=false;
exit;
end if;
end loop;
if (flag)then
dbms_output.put_line(i);
end if;
end loop;
end;
3.使用数组添加元素后 排序输出
declare type myTable is TABLE OF number INDEX BY BINARY_INTEGER;
arr myTable;
x number;
begin
arr(1):=5;
arr(2):=3;
arr(3):=7;
arr(4):=4;
for i in 1..4 loop
for j in i+1..4 loop
if(arr(i)>arr(j))then
x:=arr(i);
arr(i):=arr(j);
arr(j):=x;
end if;
end loop;
end loop;
for i in 1..4 loop
dbms_output.put_line(arr(i));
end loop;
end;
题目一 在plsql中创建表cc 插入数据如下(列 c1,c2):
c1 c2
1 西
1 安
1 的
2 天
2 气
3 好
转换为
1 西安的
2 天气 输出
3 好 输出
create table cc(
c1 number,
c2 varchar2(20)
)
insert into cc values(1,'西');
insert into cc values(1,'安');
insert into cc values(1,'的');
insert into cc values(2,'天');
insert into cc values(2,'气');
insert into cc values(3,'好');
commit;
--wm_concat()
select c1,replace(wm_concat(c2),',','') from cc group by c1;
--plsql语句
declare mystr varchar2(20):='';
begin
for i in(select c1 from cc group by c1) loop
mystr:='';
for j in(select c2 from cc where c1=i.c1) loop
mystr:=mystr||j.c2;
end loop;
dbms_output.put_line(i.c1||' '||mystr);
end loop;
end;
------------- -- ------
begin
execute immediate 'create table cc(
c1 number(3),
c2 varchar2(20)
)';
end;
insert into cc (c1,c2) values(1,'西');
insert into cc (c1,c2) values(1,'安');
insert into cc (c1,c2) values(1,'的');
insert into cc (c1,c2) values(2,'天');
insert into cc (c1,c2) values(2,'气');
insert into cc (c1,c2) values(3,'好');
commit;
declare s1 varchar2(20);
s2 varchar2(20);
s3 varchar2(20);
begin
for i in(select * from cc) loop
if(i.c1=1) then
s1:=s1||i.c2;
end if;
if(i.c1=2) then
s2:=s2||i.c2;
end if;
if(i.c1=3) then
s3:=s3||i.c2;
end if;
end loop;
dbms_output.put_line(s1);
dbms_output.put_line(s2);
dbms_output.put_line(s3);
end;
题目二
查找出输入的用户下,每张表的记录数,(提示:使用 tab表)
以scott用户为例,
结果应如下:
DEPT...................................4
EMP...................................14
BONUS.................................0
SALGRADE.............................5
select * from tab;--有权限查询的表
select * from user_tables;
select * from all_tables where owner='SCOTT';
--第一种
declare vsql varchar2(200);
rtrNumber number;
begin
for i in(select * from user_tables ) loop
--select count(rowid) from 表名
vsql:='select count(rowid) from '||i.table_name;
execute immediate vsql into rtrNumber;
dbms_output.put_line(i.table_name||'...................'||rtrNumber);
end loop;
end;
--第二种
declare
type tab_names is table of varchar2(20) index by binary_integer;
tab_name tab_names;
coun number;
str varchar2(200);
begin
select table_name bulk collect into tab_name from user_tables;
for i in tab_name.first..tab_name.last loop
str:='select count(*) from '||tab_name(i);
execute immediate str into coun;
dbms_output.put_line(tab_name(i)||'......'||coun);
end loop;
end;
题目 三
加载在c盘存在一个文件 a.txt
内容如下
100|金融部|深圳
110|财务部|东莞
使用plsql读取该文件 并将 每行的 数据插入到dept表中 (读取一行 按|切割)
读取文件的代码
declare vInHandle utl_file.file_type ; --定义文件类型
vNewLine VARCHAR2(250); --定义变量获取当前行数据
BEGIN
vInHandle := utl_file.fopen ('目录', '文件名 ', 'R');
utl_file.get_line (vInHandle, vNewLine); --调用一次 读取一行
declare vInHandle utl_file.file_type ; --定义文件类型
vNewLine VARCHAR2(250); --定义变量获取当前行数据
begin
vInHandle := utl_file.fopen ('MYDIR', 'a.txt ', 'R');
loop
utl_file.get_line (vInHandle, vNewLine); --调用一次 读取一行
--dbms_output.put_line(vNewLine);
--100|金融部|深圳
declare a1 varchar2(20);
a2 varchar2(20);
a3 varchar2(20);
beginIdx number:=1;
begin
beginIdx:=instr(vNewLine,'|');
--1号位置开始到找到一个| 的位置结束的字符转
a1:=substr(vNewLine,1,instr(vNewLine,'|')-1);
--从第一个|的下一个位置开始
a2:=substr(vNewLine,beginIdx+1,instr(vnewLine,'|',beginIdx+1)-beginIdx-1);
beginIdx:=instr(vNewLIne,'|',beginIdx+1);
a3:=substr(vNewLine,beginIdx+1);
dbms_output.put_line(a1||' '||a2||' '||a3);
insert into dept values(a1,a2,a3);
end;
end loop;
exception when others then
utl_file.fclose(vInHandle);
commit;
end;
二。--步骤定义 经过5步骤的 显示游标 没有5步骤的 隐示游标
1.定义获取数据的变量
2.声明游标,并制定查询
3.打开游标
4.抓取数据
5.关闭游标
begin
--存放select 语句返回的查询 隐示游标 oravle负责操作5步骤
for i in(select ename,empno from emp) loop
dbms_output.put_line(i.ename||' '||i.empno);
end loop;
end;
--显示游标 分为 :自然游标,普通游标
--1定义获取数据变量
declare rowobj emp%rowtype;
--2声明游标,并指出查询
cursor mycursor is select * from emp;
begin
--3打开游标
open mycursor;
--4抓取数据
loop
fetch mycursor into rowobj;
exit when mycursor%NOTFOUND;
dbms_output.put_line(rowobj.ename || rowobj.sal);
end loop;
--5关闭游标
close mycursor;
end;
--(一)动态游标
enamevar =null;
enamebar='SMITH';
if(enamevar is null)
sql='select * from emp';
else
sql='select * from emp where ename=enamevar';
--1定义获取数据变量
declare rowobj emp%rowtype;
enameVar varchar2(20):='SMITH';
sqlVar varchar2(200):='select * from emp';
--2声明游标,并指出查询
mycursor sys_refcursor;
begin
if(enameVar is not null) then
sqlVar:=sqlVar ||' where ename=''' ||enameVar|| '''';
end if;
dbms_output.put_line(sqlVar);
if(not mycursor%isopen) then
dbms_output.put_line('未打开游标');
end if;
--3打开游标
open mycursor for sqlVar;
--4抓取数据
loop
fetch mycursor into rowobj;
exit when mycursor%NOTFOUND; --抓取之后,才能判断是否有数据
dbms_output.put_line(rowobj.ename || rowobj.sal);
end loop;
--5关闭游标
close mycursor;
end;
--异常处理
declare myVar number;
begin
select sal into myVar from emp where ename='a';
--myVar:=5/0;
exception
when NO_DATA_FOUND then
dbms_output.put_line('没有找到');
when ZERO_DIVIDE then
dbms_output.put_line('除数为0');
when others then
dbms_output.put_line('未知异常');
end;
--异常捕获
declare myVar number;
begin
begin
select sal into myVar from emp where ename='aa';
exception when NO_DATA_FOUND then
dbms_output.put_line('没有数据');
end;
myVar:=5/0;
exception
when ZERO_DIVIDE then
dbms_output.put_line('除数为0');
when others then
dbms_output.put_line('未知异常');
end;
--自定义异常
declare myexe exception;
sex varchar2(3):='&请输入性别';
begin
if(sex not in ('男','女')) then
raise myexe;
end if;
exception
when myexe then
dbms_output.put_line('未知性别');
when others then
dbms_output.put_line('未知异常');
end;
--存储过程
定义 不能直接返回值,间接返回
create or replace procedure syso(mystr varchar2)
as
begin
dbms_output.put_line(mystr);
end;
--调用begin end中 exec(sal命令) call(sal语句) 三种方式
begin
syso('hello world');
mul(123,456);
end;
--默认传入的参数在存储过程中只读 默认in;
create or replace procedure mul(p number,p2 number)
as
begin
syso(p*p2);
end;
-- out表示参数值,可以修改的 可以用户简介返回值
create or replace procedure mula(a1 in number,a2 in number,a3 out number)
as
begin
a3:=(a1*a2);
end;
declare a3 number;
begin
mula(345,789,a3);
syso(a3);
end;
--函数
create or replace function fun(p1 number,p2 number)
return number
as
begin
return p1*p2;
end;
declare result number;
begin
result:=fun(123,456);
syso(result);
end;
3、要求定义两个function 分别实现NVL和NVL2的功能
create or replace function myNvl(str varchar2,value1 varchar2)
return varchar2
as
begin
if str is null then
return value1;
else
return str;
end if;
end;
create or replace function myNvl2(str varchar2,value1 varchar2,value2 varchar2)
return varchar2
as
begin
if str is null then
return value2;
else
return value1;
end if;
end;
--存储过程和函数
1.存储过程使用关键字 procedure 函数function
2.存储过程 只能使用out间接返回值 , 函数必须要有一个返回值
3.函数是一个特殊的存储过程 存储过程能使用的技术 函数都能使用 存储过程是预编译
(一次编译多次执行)的,速度快于sal与plsal
4.存储过程只能在plsal中调用 函数可以在任何地方调用
---
函数:有返回值。执行的时候 是作为表达式用的。如select 函数 from dual;
存储过程:无返回值。执行的时候是exec 过程名。
包:将自定义的功能,如变量,函数,过程,触发器等划分到一个自包含的单元中,
调用功能是,用包名.功能名
--oracle常用优化方式有哪些
有物理优化和逻辑优化:
物理优化——升级硬件,提高网速,使用合适的优化器,修改合适的数据库连接数量,禁止回收站,
合理使用索引,索引和数据分开,不同数据放到不同磁盘上管理等等
逻辑优化:编写sql语句不要使用*号,列不要经过计算会不使用索引,
不要使用is null和not is null,用exits和not exits替换in和not in,
使用占位符,设置合理的隔离级别,编写数据做好分类。
--触发器
触发器(trigger):当特定的DML语句(INSERT,UPDATE或DELETE)运行时,由数据库自动运行的过程。
触发器可以在DML语句运行之前和之后激活。
触发器可以在DML语句作用的每一行上都运行一次,也可能只在所有的行上运行一次。
--第一种
create or replace trigger trg_emp
before insert or delete or update on emp --去掉 行级触发器 for each row
for each row --行级触发器 一次sal中如果影响多行,执行多次
begin
--新旧值 :new :old
--insert 插入 new 值
--delete 删除old值
--更新 将old 改为 new 值
if(inserting) then
syso('正在插入'||:new.ename);
if(:new.comm is null) then
:new.comm:=0;
end if;
end if;
if(deleting) then
syso('正在删除'||:old.ename||:old.sal);
end if;
if(updating) then
syso('正在更新');
end if;
end;
delete from emp;
delete from emp where ename='za';
update emp set sal=100 where ename='aa';
insert into emp(empno,ename) values(145,'za');
select * from emp;
--第二种
create or replace trigger trg_emp
before insert or delete or update on emp --去掉 行级触发器 for each row
begin
--新旧值 :new :old
--insert 插入 new 值
--delete 删除old值
--更新 将old 改为 new 值
if(inserting) then
syso('正在插入');
end if;
if(deleting) then
syso('正在删除');
end if;
if(updating) then
syso('正在更新');
end if;
end;
Delete from aa where rowid != all(select max(rowid) from aa group by name,age);
三.1 使用游标输出 scott中所有的雇员名称,部门名称,年薪
第一种
declare v_emp_ename emp.ename%type;
v_dept_dname dept.dname%type;
v_emp_sal emp.sal%type;
cursor v_curosr is select e.ename,d.dname,(nvl(sal,0)+nvl(comm,0))*12 from emp e inner join dept d on e.deptno=d.deptno;
begin
open v_curosr;
loop
fetch v_curosr into v_emp_ename,v_dept_dname,v_emp_sal;
exit when v_curosr%notfound;
dbms_output.put_line('ename='||v_emp_ename||' '||'dname='||v_dept_dname||' '||'sal='||v_emp_sal);
end loop;
close v_curosr;
end;
第二种
declare v_emp_ename emp.ename%type;
v_dept_dname dept.dname%type;
v_emp_sal emp.sal%type;
sqlvar varchar2(200):='select e.ename,d.dname,(nvl(sal,0)+nvl(comm,0))*12 from emp e inner join dept d on e.deptno=d.deptno';
mycursor sys_refcursor;
begin
dbms_output.put_line(sqlvar);
sqlvar:='select e.ename,d.dname,(nvl(sal,0)+nvl(comm,0))*12 from emp e inner join dept d on e.deptno=d.deptno';
open mycursor for sqlvar;
loop
fetch mycursor into v_emp_ename,v_dept_dname,v_emp_sal;
exit when mycursor%NOTFOUND;
dbms_output.put_line('ename:'||v_emp_ename||' '||'dname:'||v_dept_dname||' '||'sal:'||v_emp_sal);
end loop;
close mycursor;
end;
2 定义存储过程 可以传入以下参数
query(ename,job,sal)
如果传入了某几个参数 以参数组合的形式查询结果
比如调用过程如下
query('Cleck',null,null);
查询的sql为
select * from emp where ename like '%Cleck%';
query('Cleck','Manager',null);
查询的sql为
select * from emp where ename like '%Cleck%' and job like '%Manager%'
要求输出查询的结果
create or replace procedure queryEmp(ename varchar2,job varchar2,sal number)
as
vsql varchar2(200) :='select * from emp where 1=1';
begin
if(ename is not null) then
vsql:=vsql||'and ename'' '||ename||'''';
end if;
if(job is not null) then
vsql:=vsql||'and job'' '||job||'''';
end if;
if(sal is not null) then
vsql:=vsql||'and sal'' '||sal||'''';
end if;
end;
` begin
queryEmp('SMITH',null,null);
end;
select * from emp where ename like '%SMITH%';
begin
queryEmp('BLAKE','MANAGER',null);
end;
select * from emp where ename like '%BLAKE%' and job like '%MANAGER%'
select * from emp;
3 写出一个分页的存储过程
定义如下
tablePager(tableName,curPage,pageSize)
调用
tablePager('Emp',2,10)
查询emp表中 第二页的数据(每页显示10条 第二页就是 10-20条)
curPage*pageSize-(pageSize-1) curPage*pageSize
curPage*pageSize-pageSize*1+1=(curPage-1)*pageSize+
create or replace procedure tablepager(tableName varchar2,curPage number,pageSize number)
as
starIndex number:=(curPage-1)*pageSize+1;
endIndex number:=curPage*pageSize;
vSql varchar2(200):='';
colSql varchar2(200):='';
mycursor sys_refcursor;
myResult varchar2(200);
begin
dbms_output.put_line(starIndex);
select replace(wm_concat(column_name),',','||'' ''||') into colSql from user_tab_cols where table_name=tableName;
vSql:='select '||colSql||' from (select t.*,rownum rn from '||tableName||' t) where rn>='||starIndex||' and rn<='||endIndex;
open mycursor for vSql;
loop
fetch mycursor into myResult;
exit when mycursor%notfound;
dbms_output.put_line(myResult);
end loop;
close mycursor;
end;
begin
tablepager('DEPT',2,3);
end;
4 定义一个存储过程 传入表名
删除该表中的重复记录
比如 deleteMul(tableName)
调用 deleteMul('emp'); 必须删除表emp的重复数据 (execute immediate using )
create or replace procedure deleteMul(tableName varchar2)
as
colSql varchar2(2000):='';
begin
select wm_concat(column_name) into colSql from user_tab_cols where table_name=upper(tableName);
execute immediate 'delete from '||tableName||' where rowid not in(select max(rowid) from
'||tableName||' group by '||colSql||')';
end;
begin
deleteMul('sc');
end;
select * from sc;
四.实例
select * from dept;
-- 1.新增用户 orderUser 给予超级管理员(DBA)
create user orderUser identified by orderUser;
grant dba to orderUser;
-- 2.使用orderuser登陆 并且查询scott账户下 所有雇员的雇员名称和部门名称
select ename from emp;
select deptno from dept;
select e.ename,d.dname from scott.emp e inner join scott.dept d on e.deptno=d.deptno ;
-- 3.回收orderUser的超级管理员权限(DBA) 使用orderuser登陆 查询第二题
revoke dba from orderUser;
select * from scott.emp;
grant select on scott.emp to orderUser;
-- 4.使用orderuser 导出scott账户下的所有表
grant EXP_FULL_DATABASE to orderUser;
exp orderUser/orderUser@ORCL file=f:\scott.dmp owner=scott
-- 5.使用plsqldeveloper导出orderuser账户下的所有表的sql 使用sqlplus命令删除用户下所有的表 并且导入
-- 6.锁定orderuser账号后 删除orderuser账号
alter user orderUser account lock;
drop user orderUser;
-- 7.使用客户端备份(exp) 只备份scott用户下的emp表 其他表不备份
exp scott/scott@ORCL file=e:\app.dmp tables(emp)
-- 8.新增一个用户不给于dba角色权限(考虑赋予其他权限) 尝试备份scott用户下的所有表
create user manger identifide by manger;
grant create session to manger;
grant EXP_FULL_DATABASE TO manger
exp scott/scott@ORCL file=c:\scott.dmp owner=scott;
-- 9.在scott用户下 复制emp表 emp1 使用exp备份 所有emp开头的所有表
create table emp1 as select * from emp
exp scott/scott@ORCL file=e:\sco.dmp tables(emp%)
10.尝试在plsqldeveloper中进行客户端备份和还原
11.假设在c:/test目录下 有两个dmp文件 a.dmp b.dmp 通过一个还原命令将两个文件中所有 emp开头的表导入到scott用户下
FOR /R C:\test %%i IN (*.dmp) DO(
echo %%i
imp scott/scott@ORCL file=%%i full=y ignore=y
)
pause
-- 12.给orderUser只能访问emp表ename和sal列更改的权限 其他的列不允许orderUser修改权限
比如orderUser 发起sql update scott.emp set ename='a',sal=123 where empno='1234' 有权限
update scott.emp set comm=123 where empno='1234' 无权限
grant update(ename,sal) on scott.emp to orderUser;
update scott.emp set ename='a',sal=123 where empno='1234'
update scott.emp set comm=123 where empno='1234'
select * from emp;
-- 13.请自己通过工具 比较 sys和system用户的不同
sys:超级管理员,在系统中权限最多的用户 sysem普通管理员 相对比较少
-- 14.查看当前用户的所有系统权限和对象权限和角色权限
select * from user_role_privs;--角色权限
select * from user_sys_privs;--系统权限
select * from user_tab_privs_made;--对象权限
- oracle重点
- Oracle复习重点
- oracle重点内容
- oracle的内连接(重点)
- oracle的外连接(重点)
- oracle,重点处理数据语句
- Oracle数据库优化(重点)
- ORACLE网络的几个重点概念
- ORACLE网络的几个重点概念
- ORACLE网络的几个重点概念
- ORACLE网络的几个重点概念
- 2011 将重点研究 Oracle 云计算...
- Oracle 学习笔记 复杂 查询(重点)
- Oracle数据库的几个重点优化
- 重点
- 重点
- 重点
- Oracle之组函数及分组统计(重点)
- 老板的两分钱
- VTK学习(十二)图像切面提取
- MAGIX Movie Edit Pro Premium 2018官方版下载地址附安装教程
- JAVA 对象引用,以及对象赋值
- 继续写写博客吧
- oracle重点
- rabbitMQ消息服务器学习笔记(java)5exchange之模糊匹配topice
- Eclipse常用快捷键
- 从尾到头打印链表每个节点的值
- LeetCode刷题(33)
- 第11周项目5
- 迅为Exynos4412开发板例程及注释——QT环境配置与HelloWorld
- 机器学习系列(9)_机器学习算法一览(附Python和R代码)
- Tensorflow基础:TensorBoard可视化