介绍
oracle也是一个关系型的数据库,相比mysql功能更加强大,有自己独有的plSql。
安装及卸载步骤
安装:
卸载:
sql讲解:
数据类型及基本增删查改:
/*
数据类型:String:
char(10) 默认是byte字节为单位
char(10 char) 设置为字符类型,范围<2000 byte
varchar2(可变字符),范围<=4000 byte
/*
char(5)和varchar(5)的区别:
在char中后面定义了多大,在内存就会占用多大的空间,而不管存的数据的大小,但是varchar不同。
*/
数值型:
number 可存储所有的数值,包括小数和负数。
number(p,s) p代表有效位数,s代表小数位。
float 在数据库中比double常用。
alter:
add
drop
modify
columnName to newColumnName
改表名
约束:
主键约束
唯一性约束(忽略空值,聚合函数中也忽略空值)
check
复制表:
create table 表名 as select * from 被复制的表名
主表(主键表),从表(外键表)
*/
create table testType(test1 number(6,1),test2 number(6,2),test3 number(6,0),test4 number(6,-2),test5 number(6,-1))
insert into testType(test1,Test2,Test3,Test4,Test5) values(123.456,123.456,123.456,123.456,123.456);
答案-->123.5 123.46 123 100 120
alter table student2 add constraint student2_newAge check(newAge in('t','e','u'));--check 约束
alter table student2 drop constraint student2_newAge;--删除约束
insert into student2(id,newage) values(1,'e');
create table student2 as select * from tableName; --复制表
alter table student2 add constraint student2_id primary key(id);--增加主键约束
alter table student2 add age int;--添加字段
alter table student2 drop column name; --删除字段
alter table student2 modify age char(12);--修改属性类型
alter table student2 rename column age to newAge;--修改属性名
alter table student2 drop constraint student2_id;--删除约束
alter table student2 add constraint student2_newAge unique(newAge);--设置唯一性约束
alter table emp2 add constraint foreign_deptno foreign key(deptno) references emp(deptno);
横竖表转换:
create table test1(sname varchar(123),object_name varchar(123),grade number);--创建竖表
create table test2(sname varchar(123),yuwen number,shuxue number,yingyu number);--创建横表
insert into test1(sname,object_name,grade)values('老大','yuwen',90);
insert into test1(sname,object_name,grade)values('老大','shuxue',91);
insert into test1(sname,object_name,grade)values('老大','yingyu',92);
insert into test1(sname,object_name,grade)values('老二','yuwen',80);
insert into test1(sname,object_name,grade)values('老二','shuxue',81);
insert into test1(sname,object_name,grade)values('老二','yingyu',82);
insert into test1(sname,object_name,grade)values('老三','yuwen',70);
insert into test1(sname,object_name,grade)values('老三','shuxue',71);
insert into test1(sname,object_name,grade)values('老三','yingyu',72);
insert into test2(sname,yuwen,shuxue,yingyu)values('老大',90,91,92);
insert into test2(sname,yuwen,shuxue,yingyu)values('老二',80,81,82);
insert into test2(sname,yuwen,shuxue,yingyu)values('老三',70,71,72);
select * from test1;
select * from test2;
--横表转竖表,用 union 连接生成行
select sname,'yuwen' as object_name,yuwen as grade from test2
union
select sname,'shuxue' as object_name,shuxue as grade from test2
union
select sname,'yingyu' as object_name,yingyu as grade from test2;
--竖表转换成横表,用left join生成列
select t1.sname,t1.yuwen,t2.shuxue,t3.yingyu from
(select sname,grade as yuwen from test1 where object_name='yuwen')t1
left join
(select sname,grade as shuxue from test1 where object_name='shuxue')t2
on(t1.sname=t2.sname)
left join
(select sname,grade as yingyu from test1 where object_name='yingyu')t3
on(t2.sname=t3.sname);
函数的使用:
select * from tableName for update 查询是为了修改(在这个状态下可以直接修改数据)
方法原型=方法声明(就是还没有方法体)
||在oracle里面表示字符串拼接
''是转义字符,''='(''单独使用就会转义成一个')
函数的使用:
mod
power
round
sort
trunc
LPAD(pagel,15,*)
Ltrim
replace--还有其他的版本,只是编码不同
translate
length
sysdate--获取数据库当前的系统时间
extract(year from hiredate)--从hiredate的值中取出年
Months_between
Add_Months(字段,2)--代表给字段的值的月份加两个月
to char(datatime)
to Date
decode
nvl(字段,默认值)--替换空值
nvl2(字段1,字段2,默认值)--当字段1不为空时就范围字段2,否则就返回默认值
表连接:select * from a,b where a.a=b.a(+);解析:这是左连接因为+号在等号右边,同理如果用右连接,+号就写在等号左边。
select distinct job,mgr from emp--distinct后面跟了几个字段说明是去除了这些字段重复的组合
select MONTHS_BETWEEN (TO_DATE('02-02-1995','MM-DD-YYYY'),TO_DATE('01-01-1995','MM-DD-YYYY')) "Months" from dual;
select mod(11,-3)from dual;--取余
select sysdate from dual;--sysdate获取当前系统的时间
select lpad('我爱我家',10,'*-')from dual;--lpad 第一个位置是一个字符串,第二个位置是需要该字符串的长度,如果不够就用第三个位置的内容在前面填充
select ename,Add_Months(hiredate,2)from emp where comm=300;--改变月数的大小
select sname ,decode(sex,0,'男',1,'女')from stu1;--转换编码
select sname,nvl(yuwen,100)from stu1;--nvl替换空值
select sname,nvl2(shuxue,20,0)from stu1;
select translate('sql*plus/user''s/guide','*/''','=+.')from dual;--第一个参数表示一个要处理的字符串,第二个参数表示特定的字符要换第三个参数的字符,第二个参数和第三个参数是一一对应的
select replace('that so beautiful','a','rr')from dual;--replace
select ename||sal from emp--||相当于字符串连接符
SELECT MONTHS_BETWEEN (TO_DATE('02-02-1995','MM-DD-YYYY'),TO_DATE('01-01-1995','MM-DD-YYYY') ) "Months" FROM DUAL;
select sysdate from dual--查询当前时间,dual是返回一个计算结果
select MONTHS_BETWEEN (TO_DATE('02-02-1995','MM-DD-YYYY'),TO_DATE('01-01-1995','MM-DD-YYYY')) "Months" from dual; select mod(11,-3)from dual;--取余
select sysdate from dual;--sysdate获取当前系统的时间
select lpad('我爱我家',10,'*-')from dual;--lpad 第一个位置是一个字符串,第二个位置是需要该字符串的长度,如果不够就用第三个位置的内容在前面填充
select ename,Add_Months(hiredate,2)from emp where comm=300;--改变月数的大小
select sname ,decode(sex,0,'男',1,'女')from stu1;--转换编码
select sname,nvl(yuwen,100)from stu1;--nvl替换空值
select sname,nvl2(shuxue,20,0)from stu1;
select translate('sql*plus/user''s/guide','*/''','=+.')from dual;--第一个参数表示一个要处理的字符串,第二个参数表示特定的字符要换第三个参数的字符,第二个参数和第三个参数是一一对应的
select replace('that so beautiful','a','rr')from dual;--replace
select * from stu1 for update;(select for update 和select for update nowait的区别:两者都会对所查询的结果集进行加锁,不同的是,如果另一个线程正在修改结果集中的数据,后者不会进行资源等待,只要发现结果集中的数据被加锁,)
alter table stu1 add sex int; alter table stu1 add grade number;
plSql基本结构:
declare--存储函数
v_num number:=0;
begin
v_num:=2/v_num;
dbms_output.put_line(v_num);
exception
when others then
dbms_output.put_line('error....');--打印语句
end;
for loop
while loop
Goto(跳出多层循环,不常用)
声明时:j i%type 表示j这个变量取i的数据类型
rowid
rownum;
sequence;
select * from (select e.*,rownum r from (select * from emp2 order by sal desc)e)where r>6 and r<10;//取职工薪水第七位到第十位的人
select * from(select rownum n,e.* from stu1 e where rownum<=100 order by e.sname)where n>10;//rownum 分页
select * from (select rownum n,sname from stu1)where n>2; //和上面的分页效果相同,但是上面的分页是根据sname来分页的。
create sequence my_sequence; //序列化,可用于赋值
select * from stu1;
insert into stu1(sname,yuwen,shuxue,yingyu,sex)values('赵六',92,91,99,my_sequence.nextval);
insert into stu1 select * from stu1 where sname='赵六';
delete from stu1 where sname in(select sname from stu1 group by sname having count(sname)>1)//删除表中重复的记录(根据某个字段来判断)
and rowid not in(select min(rowid)from stu1 group by sname having count(sname)>1);
procedure
参数传递模式:in out in out
参数:位置表示法,名称表示法,混合表示法。
create or replace procedure myprcedure(ss stu1.sname%type)
is
begin
dbms_output.put_line('ss:'||ss);
end;
declare
--student stu1.sname%type:='媛媛';
student stu1.sname%type default '源源';//默认值
begin
myprcedure(student);//调用存储过程
end;
--参数v_a是入参,不能改变;参数v_b是默认也是入参;参数v_ret是出参,返回给调用者的参数;参数v_temp是入参也是出参,可以使用也可以改变值
create or replace procedure p(v_a in number,v_b number,v_ret out number,v_temp in out number)
is
begin
dbms_output.put_line('=='||v_ret);--出参是拿不到值的 ,只能操作值,调用者才能拿到值
if(v_a>v_b) then
v_ret :=v_a;
else
v_ret:=v_b;
end if;
v_temp:=v_temp+1;
end;//创建存储过程
declare//调用存储过程
v_a number := 6;
v_b number := 9;
v_ret number:=3;
v_temp number:=10;
begin
p(v_a,v_b,v_ret,v_temp);
dbms_output.put_line(v_ret);
dbms_output.put_line(v_temp);
end;
oracle有number数据类型,默认支持小数和整数包括负数。
调用存储过程的方式不一样:mysql是直接call 存储过程的名称,oracle是直接把存储过程的名称写在begin end中调用。
oracle有自己的plsql
游标:
声明时:j i%type 表示j这个变量取i的数据类型
隐式游标(Implicit Cursors,自带,名称为SQL)
显式游标(Explicit Cursors,名称自定义)
begin//隐式游标,属性:SQL%FOUNF,SQL%ROWCOUNT,SQL%NOTFOUND,
insert into stu1 select * from stu1 where sname='王五';
if SQL%fOUND then
dbms_output.put_line('增加成功');
dbms_output.put_line(SQL%ROWCOUNT);
end if;
end;
DECLARE--显式游标
cursor stu1_cursor is select * from stu1;--声明一个游标
student stu1_cursor%rowtype;
BEGIN
open stu1_cursor;--打开游标
fetch stu1_cursor into student;--让指针游标往下移动
while stu1_cursor%found
loop
dbms_output.put_line(student.sname);
fetch stu1_cursor into student;
exit when stu1_cursor%notfound;
end loop;
close stu1_cursor;
END;
declare
cursor mysor is select * from stu1;//游标定义为接收一个查询出来结果集
rt mysor%rowtype;//该结果集的类型就是rowtype的类型
begin
open mysor;--打开游标
loop
fetch mysor into rt;
dbms_output.put_line(rt.sname);
exit when mysor%notfound;
end loop;
close mysor;
end;
触发器:
create or replace trigger trigs//触发器
after insert or delete or update on emp2 for each row
begin
dbms_output.put_line('emp2表中更新了一条记录');
end;
练习:
declare--打印一个九九乘法表
i int :=1;
j int :=1;
k int :=1;
begin0
loop
k:=i*j;
dbms_output.put(rpad(j||'*'||i||'='||k,10));
j:=j+1;
exit when j>i;
end loop;
dbms_output.put_line('');
i:=i+1;
exit when i>9;
end loop;
end;
/*【程序20】
题目:有一分数序列:2/1,3/2,5/3,8/5,13/8,21/13...求出这个数列的前20项之和。
1.程序分析:请抓住分子与分母的变化规律。
*/
declare
v_count int :=1;
v_sum int :=0;
v_total int :=0;
i int:=2;--分子
j int:=1;--分母
k int:=0;--中间值
begin
loop
v_sum:=i/j;--计算单个值
v_total:=v_total+v_sum;--计算总和
k:=i+j;
j:=i;
i:=k;
v_count:=v_count+1;
dbms_output.put('i:'||i);dbms_output.put(' j:'||j);dbms_output.put(' k:'||k);
dbms_output.put_line(' v_sum:'||v_total);
exit when v_count>20;
end loop;
end;