谨把这篇文章作为复习Oracle(只有相关的SQL语句部分,不涉及Oracle工具
的其他诸如回复容灾等等)之用。让各位大虾在偶然用到但却忘记的时候过来看看,正要学习的小虾们也过来看看……
下面的SQL语句是创建序列、表,以及简单修改表结构、向表中插入数据、常用简单的SQL查询(一般的分页语句都是封装过了的,直接写句子的并不常见)。
其中,在创建sequence的时候,有一个nocache(默认)表示不创建序列缓存。大家熟知,一般情况下创建缓存是可以提高效率的,那还有什么区别呢?我们来做个实验:假设seq是start with 1 increment by 1 cache 20,你新建了15条数据,你的缓存中还有16,17,18,19,20这5个索引在缓存中未使用,突然 在这个时候宕机了,或者直接说由于某种原因数据库重启了(你的缓存就没了哈,)。但是你的索引再次使用的时候,你会发现是从21-40的,这就是是否使用缓存的区别了。nocache中能保证所有的索引都是连续的,
……
--序列
create sequence teaSeq
minvalue 1
increment by 1
start with 1
nocache;
create sequence stuSeq
minvalue 1
increment by 1
start with 1
nocache;
--表
create table Teacher (
teaid int,
tname varchar2(15),
sex char(2) check(sex='男' or sex='女'),
age int,
phonenumber varchar2(15),
taddress varchar2(30),
primary key(teaid)
);
create table Student(
stuid int,
sname varchar2(15),
sex char(2),
age int,
teacherid int,
phonenumber varchar2(12),
address varchar2(30),
primary key(stuid),
foreign key(teacherid) references Teacher(teaid)
);
-- modify column
alter table Student modify phonenumber varchar2(15);
-- add constraint
alter table Student add constraint sex check(sex in ('男','女'));
-- rename column
alter table Student rename column address to saddress;
-- insert data/添加数据
insert into Teacher values(teaSeq.nextval, '张孝祥', '男', 33, '13826754208', '中国河南省南阳市');
insert into Teacher values(teaSeq.nextval, '李清照', '女', 43, '13426754204', '中国上海');
insert into Teacher values(teaSeq.nextval, '赵子龙', '男', 28, '13626754206', '中国浙江省杭州市');
insert into Teacher values(teaSeq.nextval, '李小龙', '男', 36, '13526754205', '中国湖北省武汉市');
insert into Teacher values(teaSeq.nextval, '武则天', '女', 45, '13226754202', '中国广东省深圳市');
insert into Teacher values(teaSeq.nextval, '西施', '女', 21, '13126754201', '中国香港九龙');
insert into Teacher values(teaSeq.nextval, '诸葛亮', '男', 27, '13726754207', '中国广西省南宁市');
insert into Teacher values(teaSeq.nextval, '王昭君', '女', 18, '13026754200', '中国云南省昆明市');
insert into Teacher values(teaSeq.nextval, '王永民', '男', 56, '13326754203', '中国青海省西宁市');
insert into Teacher values(teaSeq.nextval, '于丹', '女', 31, '13926754209', '中国陕西省西安市');
insert into Student values(stuSeq.nextval, '影影', '女', 21, 1, '1234567891', '中国广西省南宁市');
insert into Student values(stuSeq.nextval, '寒梅', '女', 22, 1, '1234567892', '中国广西省南宁市');
insert into Student values(stuSeq.nextval, 'Lily', '女', 23, 1, '1234567893', '中国广东省深圳市');
insert into Student values(stuSeq.nextval, 'Lucy', '女', 24, 2, '1234567894', '中国广东省深圳市');
insert into Student values(stuSeq.nextval, 'Tom', '男', 25, 3, '1234567895', '中国西藏拉萨市');
insert into Student values(stuSeq.nextval, 'Alice', '女', 26, 3, '1234567896', '中国广西省南宁市');
insert into Student values(stuSeq.nextval, 'Jack', '男', 27, 2, '1234567897', '中国广西省南宁市');
insert into Student values(stuSeq.nextval, 'Jack', '男', 27, 4, '1234567897', '中国广西省南宁市');
commit;
select user from dual;
select sysdate from dual;
-- 最简单的关连查询
select * from Student stu, Teacher tea where teacherid = teaid; -- 等效于全连接
select * from Student stu left join Teacher tea on teacherid=teaid; -- 左连接
select * from Student stu right join Teacher tea on teacherid=teaid; -- 右连接
select * from Student stu join Teacher tea on teacherid=teaid; -- 全连接
-- 很奇怪,当查询id的时候distinct就无效了(各路神仙,求解)……
select distinct sname, sex, age, saddress from student stu;
select * from Teacher order by age desc; -- asc(default)/desc
PROCEDURE and EXCEPTION/存储过程和异常
存储过程的结构:
CREATE OR REPLACE PROCEDURE 存储过程名字(参数1 IN NUMBER, 参数2 OUT NUMBER, ...)
IS|AS
变量1 INTEGER :=0;
变量2 DATE;
BEGIN
...
exception
when VALUE_ERROR/NO_DATA_FOUND/TOO_MANY_ROWS then
dbms_output.put_line('...');
when OTHERS then
dbms_output.put_line('...');
END 存储过程名字;
-- no parameter
create or replace procedure proc1
is
begin
Dbms_Output.put_line('Hello world!'||chr(10)||'I am a happy DBA secooler');
end;
GOTO;
-- parameter: in(default)
create or replace procedure proc2(stname student.sname%type)
is
address student.saddress%type;
begin
select saddress into address from student where sname=stname;
dbms_output.put_line('Name:'||stname||' Address:'||address);
exception
when VALUE_ERROR then
dbms_output.put_line('赋值错误/parameter error!');
when NO_DATA_FOUND then
dbms_output.put_line('No data!');
when TOO_MANY_ROWS then
dbms_output.put_line('Too many rows!');
when OTHERS then
dbms_output.put_line('Other error!');
end;
GOTO;
-- parameter: in out out out
create or replace procedure proc3(stid in student.stuid%type, stname out student.sname%type, stadd out student.saddress%type, status OUT VARCHAR2)
as countnumber number;
begin
status := 'SELECT SUCESS';
SELECT sname,saddress INTO stname,stadd FROM student WHERE stuid=stid;
exception
WHEN NO_DATA_FOUND THEN
status := 'NO_DATA_FOUND';
end;
GOTO;
-- use these procedures/调用存储过程.
declare
stuid student.stuid%type;
stuname student.sname%type;
stuadd student.saddress%type;
stustatus varchar2(15);
begin
proc1; -- 调用存储过程proc1
stuname :='Lucy'; -- 调用输入参数前必须先赋值,输出参数不必要
proc2(stuname); -- use proc2
stuname :='Jack';
proc2(stuname); -- Too many rows error.
stuid := 1;
proc3(stuid,stuname,stuadd,stustatus); -- use proc3
dbms_output.put_line('Status:'||stustatus||'! Name:'||stuname||' Address:'||stuadd);
proc3(stid=>2,status=>stustatus,stname=>stuname,stadd=>stuadd); -- 此种写法参数顺序可变
dbms_output.put_line('Status:'||stustatus||'! Name:'||stuname||' Address:'||stuadd);
end;
GOTO;
-- VALUE_ERROR
declare
stuid student.stuid%type;
begin
stuid :='ss'; -- value_error
exception
when VALUE_ERROR then
dbms_output.put_line('赋值错误');
when OTHERS then
dbms_output.put_line('其它错误');
end;
GOTO;
-- user-defined exception/自定义异常
DECLARE
stuname student.sname%type;
VALUE_NOT_EXIST exception;
BEGIN
stuname := 'd';
IF stuname NOT IN('a','b','c') THEN
BEGIN
RAISE VALUE_NOT_EXIST;
END;
END IF;
EXCEPTION
WHEN VALUE_NOT_EXIST THEN
dbms_output.put_line('该值不存在');
WHEN OTHERS THEN
dbms_output.put_line('其它错误');
END;
GOTO;
-- cycle/循环 LOOP(EXIT WHEN)/WHILE/FOR
DECLARE
stid student.stuid%type;
maxid student.stuid%type;
stname student.sname%type;
stadd student.saddress%type;
BEGIN
DBMS_OUTPUT.PUT_LINE('-----------------LOOP-----------------');
stid:=1;
select max(stuid) into maxid from student;
LOOP
IF(stid<=maxid) THEN
select sname into stname from student where stuid=stid;
DBMS_OUTPUT.PUT_LINE('Name:'||stname);
stid := stid+1;
ELSE
BEGIN
DBMS_OUTPUT.PUT_LINE('Over');
EXIT;
END;
--exit when stid>maxid --此句也可用于结束循环
END IF;
END LOOP;
DBMS_OUTPUT.PUT_LINE('-----------------WHILE-----------------');
stid:=1;
WHILE stid<= maxid LOOP
select sname into stname from student where stuid=stid;
DBMS_OUTPUT.PUT_LINE('Name:'||stname);
stid := stid+1;
END LOOP;
DBMS_OUTPUT.PUT_LINE('-----------------FOR-----------------');
stid:=1;
FOR indexid IN stid..maxid LOOP
select sname into stname from student where stuid=indexid;
DBMS_OUTPUT.PUT_LINE('Name:'||stname);
END LOOP;
END;