Oracle复习总结
Oracle操作要点:
在pl\sql中进行增删改查要commit数据才能显示在cmd窗口
显示数据库名称:show parameter db_name;
查表的数据类型:describe 表名;(获取函数的信息:describe 函数名)
/=run:再执行一次SQL语句,但是SQL语句块一定要搭配/,以;为执行标志
Edit:可以把刚才出错的代码在笔记本修改后保存再敲/重新执行
List:显示缓冲区内容,需要事前给目标语句标好序号,然后输入对应的行号,通常与append搭配:输入行号后输入append+追加内容
Input:可以追加多行内容,用法与append相似,但是输入input不带参数的,在行号变为ni时即可添加所需内容。结束时需要两次回车。用list显示已修改的缓冲区的内容。
Change:修改目标行的语句,change/旧语句/新语句,与list搭配。
Del:del 1 4(删除第一行和地4行之间的内容) del *结束行号(删除当前行可结束行之间)
对文件的读写:
start=@+文件路径\文件名 (可以执行文件的内容)
Get +文件路径\文件名(文件只能有一句话而且不能有分号):显示文本内容但不执行,用/执行。
Save+文件路径+选项(create/replace/append):保存缓冲区内容
生成报表:spool 文件路径+文件名(A).txt
Select 语句
Spool off;
即可在当前目录下生A.txt文件
输入参数查询:SELECT * from &变量名1(任取)from &变量名2
SELECT * from &&变量名1(任取)from &&变量名2(输入的变量值一直保存,不需要重复输入)
赋值:define+变量名=值,使用时,select * from &变量1 where 列名=变量2,删除:undefine 变量名
define col_name=ename
define salary=2000
select &col_name from emp where sal>&salary;
文件操作是输入参数:
建立txt文件
Select * from 表名 where 列名1=&变量名1 and 列名2 =&变量名2
select ename from emp where deptno=&1 and sal>&2;
执行:
@ 文件路径\文件名 参数1 参数2.。。。
@ D:\temp\my_5 30 2000;
Prompt +字符串:打印字符串
prompt i am good;
accept 变量名 变量类型 prompt 提示信息 选项(default 0)
SQL> accept d number prompt 请输入d的值 default 0;
请输入d的值100
Pause+文本:代码运行到这一句停止,需要再敲回车键继续执行。
记事本:select ename from emp where deptno=&1 and sal>&2;
SQL> @ D:\temp\my_6.sql;
工资统计现在开始
请输入部门号:30
请输入回车键开始统计。。。
设置报表格式:
Ttitle 给每一页设置头标题
Btitle 给每一页设置尾标题
Set pagesize
Set newpage
Set linesize
Column {列名} format An(显示A5)、,(千位符)、.(小数点位置)、)、L(显示本地货币符号)
Break on 列名:以该列名分组
Compute 函数名 of 列名1 列名2 on 列名
两者必须同时存在
break on deptno
compute avg sum of sal on deptno
select deptno,ename,sal from emp
where deptno=30
order by deptno,sal;
创建表空间:
永久的:
Create tablespace 表空间名
Datafile ‘路径+新数据库文件名’
Size
Extent management local (本地管理)
Uniform size xxxk;
create tablespace myspace
datafile 'D:\temp\my_tb01
size 20m
extent management local;
临时的:
Create temporary tablespace 表空间名
Tempfile ‘文件路径+文件名’
Size
Extent management local
create tablespace myspace
datafile 'D:\temp\my_tb01
size 20m
extent management local;
撤销表(可以存放已经删除的数据,便于恢复数据)
Create undo tablespace 表空间名
Datafile ‘文件路径+文件名’
Size
create tablespace myspace
datafile 'D:\temp\my_tb01
size 20m
extent management local;
维护表空间
重命名表空间名:alter tablespace 旧名 rename to 新名
重命名数据文件:alter tablespace 表空间名 rename datafile ‘文件路径+文件名’to‘文件路径+新文件名’
将表空间脱机:alter tablespace 表空间 offline
向表空间添加文件:
alter tablespace myspace1
add datafile ‘D:\temp\mydd.DBF’
SIZE 5M
(不用先创建mydd.dbf文件)
SELECT FILE_NAME,TABLESPACE_NAME
FROM DBA_DATA_FILES
WHERE TABLESPACE_NAME=‘MYSPACE1’;
表的操作:
查询所创建的表位置:
Select * from user_tables where table_name=’新建的表名’
需要重启窗口才有结果
创建于已存在的表结构一样的表:
create table emp1 as select * from scott.emp;
移动表的位置:
Alter table 新建表名 move tablespace 空间名
创建约束:(查询约束:select* from user_constraints)
在表创建语句中的列名的数据类型后面加上constraint 约束名 约束条件
非空约束:
CREATE TABLE student_2 (
sno CHAR(10) ,
sname VARCHAR2(30) constraint sname_notnull NOT NULL,
ssex CHAR(2),
sbirthday DATE,
semail VARCHAR2 (25) ,
sdept VARCHAR2 (30)
)
Tablespace 表空间名(自定义表存在哪里);
to_date(‘1995-10-12’,‘yyyy-mm-dd’)显示年月日
唯一性约束:
单个:
CREATE TABLE student_2 (
sno CHAR(10) ,
sname VARCHAR2(30),
ssex CHAR(2),
sbirthday DATE,
semail VARCHAR2 (25) constraint weiyi unique,
sdept VARCHAR2 (30)
);
多个:
CREATE TABLE student_2 (
sno CHAR(10) ,
sname VARCHAR2(30),
ssex CHAR(2),
sbirthday DATE,
semail VARCHAR2 (25),
sdept VARCHAR2 (30),
constraint weiyi unique(stelephone,semail)
);
创建主键:在建表时在相应的列名后面加上primary key
CREATE TABLE student_5 (
sno CHAR(10) PRIMARY KEY,
sname VARCHAR2(30),
ssex CHAR(2),
sbirthday DATE,
semail VARCHAR2 (25),
sdept VARCHAR2 (30)
);
创建外键:
Constraint 约束名 foreign key(需要外键的列名) references 主键表(数据来源的列名)
CONSTRAINT student_7_class FOREIGN KEY ( classid )
REFERENCES clazz ( classid )
CONSTRAINT student_8_class FOREIGN KEY ( classid )
REFERENCES class ( classid ) on delete CASCADE(主键的数据被删外键的也会被删)
更改约束条件状态:
Alter table 表名 enable\disable constraint 约束名
插入视图数据要符合子查询条件:在创建视图下面语句加上with check constraint 约束名;
系统查询语句汇总:
select table_name,tablespace_name from user_tables(在创建表空间的用户下执行)
创建序列:
Create sequence 序列名
Start with 目标数字
Increment by 增长幅度
Nocycle
Order
Nocache(不缓存序列)
使用:
Insert into 表名 values (序列名.nextval,值1,值2、、、);
查看序列当前值:
Select 序列名.currval from dual;
创建同义词(别名):
Create public、replace synonym 别名 for 用户.表名
使用:
Select * from 别名
To_date 用法:
To_date(‘具体日期’,‘yy-mm-dd’)
Dml操作:列名 like‘%%%’:表示列名有%的字符
Savepoint 节点名
Dml语句
Rollback;
(Dml语句没有执行)
函数:
Initcap(string):首字母大写
ASCII(string):返回字符对应的十进制数值
Char(数值):返回数值对应的字符
Round(数值,小数位位数):按精度四舍五入
Current_timestamp:获取当前日期
Last_day(目标日期):获取当前日期的所在月的最后一天
Months_between(date1,date2):date1与date2相隔天数
Media(x):返回x的中间值
有别名的列不能直接用函数
连接:
两个表查询(笛卡尔积)(与交叉连接结果一样):select * from 表A,表B
两个表加where(与内连接结果一样)(结果是根据前一个表的数值在后一个表找出该数值对应的行):
Select * from 表A,表B where 条件
自然连接(结果是把两个表的同名列只写一个):select * from 表A natural join 表B
不等连接:
Select * from 表A inner join 表B on +条件
结果集操作:
Union(把两个结果合并):select 列名n from 表A union(all)select 列名N from表A(要求列名n个数,列名相同)
Intersect(把两个结果交集):select 列名n from 表A intersect select 列名N from表A(要求列名n个数,列名相同)
Minus(删除两个结果集都有的值):elect 列名n from 表A minus select 列名N from表A(要求列名n个数,列名相同)A集合减去B的集合的与a集合相等的值
使用any的子查询:将一个值与列表中所有值比较,满足列表其中一个值就返回
Select * from 表 where 列名 +运算符 any(子查询);
使用all的子查询:将一个值与列表中所有值比较,满足列表所有值就返回
Select * from 表 where 列名 +运算符 all(子查询);
多列查询:
Select ename,sal,comm,deptno from emp where (sal ,(nvl(comm.-1) in (select sal,nvl(comm.-1) from emp where deptno=30)
查询部门编号为30的工资和奖金相同的员工信息。
编程:
Dbms_output.put_line(‘…’);需要先执行set serveroutput on执行然后要写在begin 和end中间。
特殊运算符:
A:=B 把B值给A
1…5 操作范围从一到五
%type:新列名 列名%type:新列名与列名同一类型
%rowtype :新表名 旧表%rowtype 新表与旧表格式一样
特别功能:
1、 求出每天是星期几
Declare
V_date date :=to_date(‘输入日期’,‘yyyy-mm-dd’);
V_day varchar2(20);
Begin
V_day:=trim(to_char(v_Date,’day’));
If v_day in(‘星期六’,‘星期日’) then
DBMs_output.put_line(‘周末’);
Else
DBMs_output.put_line(‘不是周末’);
End if
End;
定义变量:
变量名 数据类型 ($输入变量名)
选择结构:
Declare
变量
Begin
If 条件 then
执行语句
Else
执行语句
End if
End
Case结构:
Declare
变量
Begin
Case when 条件 then
Case when 条件 then
End case
End
循环结构
Declare
变量
Begin
Loop
执行语句(循环体)
If 条件 then
执行语句
End loop
End;
实现1+2+3…+100
declare
counter number(3):=0;
sumresult number:=0;
begin
loop
counter:=counter+1;
sumresult:=sumresult+counter;
if counter>=100 then
exit;
end if;
end loop;
dbms_output.put_line(‘result is’||to_char(sumresult));
end;
while循环:
declare
变量
Begin
While 条件 loop
执行语句(循环体)
End loop;
End;
–while 循环实现1~100的和
declare
counter number(3):=0;
sumresult number:=0;
begin
while counter<100 loop
counter:=counter+1;
sumresult:=sumresult+counter;
end loop;
dbms_output.put_line(‘result is’||to_char(sumresult));
end;
for循环:
for counter in 循环次数下限…循环次数上限 loop
执行语句(循环体)
End loop;
End;
declare
countt number(3):=0;
sumresult number:=0;
begin
for counter in 1…100 loop
countt:=countt+1;
sumresult:=sumresult+countt;
end loop;
dbms_output.put_line(‘result is’||to_char(sumresult));
end;
游标:
Declare
(表,变量)
Cursor 游标名 is
SQL 语句
Begin
Open 游标名
Fetch 游标名
Close 游标名
End
declare
emp_rec emp%rowtype;
cursor emp_cursor is
select * from scott.emp where deptno=20;
begin
open emp_cursor;
fetch emp_cursor into emp_rec;
dbms_output.put_line(‘员工编号:’||emp_rec.empno||‘姓名是:’||emp_rec.ename||‘工作是’||emp_rec.job);
close emp_cursor;
end;
游标属性:
%found:游标名 %found 游标用fetch函数取到数值则返回true
declare
emp_rec emp%rowtype;
cursor emp_cursor is
select * from scott.emp where deptno=20;
begin
open emp_cursor;
fetch emp_cursor into emp_rec;
if emp_cursor %found then
dbms_output.put_line(‘员工编号:’||emp_rec.empno||‘姓名是:’||emp_rec.ename||‘工作是’||emp_rec.job);
else
dbms_output.put_line(‘weiqudao’);
end if;
end;
%notfound :与之相反
%isopen :判断游标是否开了
declare
cursor emp_cursor
is
select * from emp order by empno desc;
begin
open emp_cursor;
if emp_cursor %isopen
then
dbms_output.put_line(‘dakai’);
else
dbms_output.put_line(‘weidakai’);
end if ;
end;
%rowcount:计算游标取到多少个数
declare
cursor emp_cursor
is
select * from emp order by empno desc;
emprow emp%rowtype;
begin
open emp_cursor;
loop
fetch emp_cursor into emprow;
exit when emp_cursor %notfound;
dbms_output.put_line(‘empno is’||emprow.empno);
end loop;
dbms_output.put_line(emp_cursor%rowcount);
close emp_cursor;
end;
用for循环来取代open、fetch、close:
Declare
Cursor 游标名 is
SQL语句
Begin
For 变量 in 游标名
Loop
执行语句
Exit then 条件
执行语句
End loop;
End;
declare
cursor emp_cursor
is
select * from emp order by empno desc;
begin
for emprow in emp_cursor loop
dbms_output.put_line(‘empno is’||emprow.empno);
end loop;
end;
游标for循环:
1、带参数的游标:
declare cursor emp_cursor(no number)
is
select sname from student where sid=no;
begin
for emp_record in emp_cursor(&no)
loop
dbms_output.put_line('名字是'||emp_record.sname);
end loop;
end;
2、 利用游标更改数据:
declare
cursor st_cursor is
select * from student FOR update of tel ;
begin
for c in st_cursor loop
update student set tel=120 where current of st_cursor;
end loop;
end;
综合应用:
declare
cursor workday is
select ename,hiredate,
trunc(months_between(sysdate,hiredate)/12) as years,
(先通过month_between函数求出两个日期相差的月份再除以12求出相差多少年,再用trunc函数对上面的商进行取整,默认是0位小数)
trunc(mod(months_between(sysdate,hiredate),12)) as yue,
求第几个月
trunc(mod(mod(sysdate-hiredate,365),12))as days from emp1;
求第几天
r_workday workday%rowtype;
begin
for r_workday in workday loop
r_woekday的元素在该游标中
dbms_output.put_line(r_workday.ename||‘已经工作了’
||r_workday.years||
‘年,零’||r_workday.yue||‘月,零’||r_workday.days||‘天’);
end loop;
end;
trunc(sysdate,‘yyyy’) --返回当年第一天.
trunc(sysdate,‘mm’) --返回当月第一天.
trunc(sysdate,‘d’) --返回当前星期的第一天.
select trunc(sysdate,‘YYYY’)from dual;
select trunc(sysdate,‘MM’)from dual;
select trunc(sysdate,‘D’)from dual;
MONTHS_BETWEEN函数返回两个日期之间的月份数
--------8.8.4
declare cursor crs_testavg is
select empno,ename,job,sal,deptno,avg(sal) over(partition by deptno) as dep_avg from emp1 for update of sal;
r_testavg crs_testavg%rowtype;
salinfo emp1.sal%type;
begin
for r_testavg in crs_testavg loop
if r_testavg.sal>r_testavg.dep_avg then
salinfo:=r_testavg.sal-50;
dbms_output.put_line(r_testavg.ename);
end if;
update emp1 set sal=salinfo where current of crs_testavg;
end loop;
end;
聚合函数 over(partition by 要分组的列名):该聚合函数结果分别显示在每个要分组列名前。
存储过程:注意 数据表不能用别名
1、建立:Crete or replace procedure 存储过程名 is
Begin
Sql语句
End
1-1执行:
在pl\sql只能用call 存储名();
或者begin
存储名;
End;
2、 创建带输入参数过程
Create or replace procedure 过程名
(输入参数变量名1 in 目标表.列名1%type,输入参数变量名2 in 目标表.列名2%type)
Is
Begin
Sql语句
End
End 过程名;
Create Or Replace Procedure updateemp_in
(emp_num In emp1.empno%Type,
emp_name In emp1.ename%Type)
Is
Begin
Update emp1 Set ename=emp_name
Where empno=emp_num;
End updateemp_in;
2-2执行:
按位置传递
Call updateemp_in(7400,‘flower’);
按名称传递:
Call updateemp_in(emp_name>=‘flower’,emp_num>=7400);
带out参数的存储过程:
Create or replace procedure 过程名
(输入参数变量名 in 数据类型,输出参数变量名1 out 数据类型,
输出参数变量名2 out 数据类型)
Is
Begin
SQL 语句
End 过程名;
Create Or Replace Procedure select_empout
(No In scott.emp.empno%Type,
name Out scott.emp.ename%Type,
salary Out scott.emp.sal%Type)
Is
Begin
Select ename,sal Into name,salary From emp Where empno=No;
Exception
When no_data_found Then
dbms_output.put_line(‘该员工不存在’);
End select_empout;
执行:var 接受输出值变量名1 数据类型;
var 接受输出值变量名2 数据类型;
Exec 过程名(输入参数值,:接受输出值变量名);
Print 接受输出值变量名1(空格) 接受输出值变量名2
Var emp_name Varchar2(10);
Var emp_salary Number;
Exec select_empout(7369,:emp_name,:emp_salary);
print emp_name emp_salary;
带有in out参数过程:
Create or replace procedure 过程名
(输入输出参数变量名1 in out 数据类型,输入输出参数变量名1 in out 数据类型)
Is
Begin
Sql 语句
End 过程名;
Create Or Replace Procedure swap(x In Out Number,y In Out Number)
Is
z Number;
Begin
z:=x;
x:=y;
y:=z;
End swap;
执行:
Declare
输入参数变量名1 数据类型:=新值1;
输入参数变量名2 数据类型:=新值2;
Begin
过程名(输入参数变量名1,输入参数变量名2)
End;
Declare a Number:=10;b Number:=20;
Begin
dbms_output.put_line(‘交换前a和b的值是:’||a||’ ‘||b);
swap(a,b);
dbms_output.put_line(‘交换后a和b的值是:’||a||’ '||b);
End;
创建函数:
Create or replace function 函数名【(输入参数变量名 in 数据类型)】
Return 返回参数的数据类型 is
【声明变量】
Begin
SQL 语句
Return 返回参数变量名
End 函数名
Create Or Replace Function get_name(emp_num In Number)
Return Varchar2 Is
emp_name emp.ename%Type;
Begin
Select ename Into emp_name From emp Where empno=emp_num;
Return emp_name;
End get_name;
执行:select 函数名(输入参数值)from dual
select get_name(7400) from dual;
1、创建B表,和已有的A表一样的字段,不保存A表的数据
create table BBB as select * from AAA where 1= 0
2、创建B表,和已有的A表一样的字段,同时保存A表已有的数据,一般可以用于备份
create table BBB as select * from AAA where 1= 1
触发器:
分类:
Before:触发语句未执行就执行触发器(预防)
After:触发语句执行后才执行触发器(马后炮)
Instead of :不执行触发语句而直接执行 instead of 定义的操作(只能基于不可修改视图创建)
创建before触发器:
Create or replace trigger 触发器名
Before、after delete、update、insert
On 目标表名
Begin
SQL语句(触发语句)
End ;
(把在emp1删除的数据记录在emp1_his的表中,可用select语句查出来)
Create Or Replace Trigger del_emp1
Before Delete On scott.emp1
For Each Row
Begin
Insert Into emp1_his Values( :old.empno, :old.ename, :old.job,:old.mgr,:old.hiredate,:old.sal,:old.comm,:old.deptno);
-----------Rollback;
End del_emp;
触发:
执行dml操作
Delete from emp1 where empno=7369;
创建instead of 触发器:
Create or replace trigger 触发器名
Instead of dml操作
【declare】
Begin
SQL语句
End 触发器名;
Create Or Replace Trigger update_view
Instead Of Update On emp_dept_view
Declare
Id dept1.deptno%Type;
Begin
Select deptno Into Id From emp1 where empno=:new.empno;
Update dept1 Set dname=:new.dname where deptno=id;
End update_view;
触发:
Dml操作
update emp_dept_view set dname=‘SALES’
where empno=7566;
创建ddl触发器
Create or replace trigger 触发器名
After【before】create、drop、alter table onschema
Begin
SQL语句
End 触发器名;
create or replace trigger ddl_create_schema
after create on schema
begin
dbms_output.put_line(‘新对象被创建了!’);
end ddl_create_schema;
触发:
create table table1(id number);
查询已创建的触发器
select trigger_name from user_triggers;
创建程序包头
Create or replace package 程序包名 is
(声明变量、过程、游标)
End;
create package student_package
as
procedure add_student_procedure
(stu_id number,stu_name varchar2,stu_age number);
function find_student_function(stu_id number) return varchar2;
end student_package;
创建程序体
create or replace package body student_package
as
procedure add_student_procedure
(stu_id number,stu_name varchar2,stu_age number)
as
begin
insert into student values (stu_id,stu_name,stu_age);
end add_student_procedure;
function find_student_function(stu_id number) return varchar2
as
stu_name student.sname%type;
begin
select sname into stu_name from student where sid=stu_id;
return stu_name;
end find_student_function;
end student_package;
执行程序:
exec student_package.add_student_procedure(1005,‘NICK’,24);
select * from student;
上述代码均可执行,喜欢的童鞋可以打赏一下哦~~~~~~
来源:CSDN
作者:qq_43226062
链接:https://blog.csdn.net/qq_43226062/article/details/103569063