Oracle基本語法及例子

--創建表空間
CREATE TABLESPACE mydb
DATAFILE 'D:\Oracle\mydb.dbf'
SIZE 5M
--創建用戶
CREATE USER admin_1 IDENTIFIED BY 123456  
DEFAULT Tablespace mydb

--賦值權限
GRANT CONNECT,RESOURCE TO ADMIN_1

--移出權限
REMOVE CONNECT,RESOURCE TO ADMIN_1
--刪除用戶
DROP USER ADMIN_1 cascade; 
--創建表
CREATE TABLE UserInfo(
       NAME Varchar2(40) NOT NULL,
       sex VARCHAR2(1) DEFAULT 'Y'NOT NULL,
       birthday DATE NOT NULL,
       height Number(3,2),
       weight NUMBER(3,2),
       memo VARCHAR2(100)
);
--給列添加描述
COMMENT ON column userinfo.name IS '姓名';
COMMENT ON column userinfo.sex IS '性別';
COMMENT ON column userinfo.birthday IS '生日';
COMMENT ON column userinfo.height IS '身高';
COMMENT ON column userinfo.weight IS '體重';
COMMENT ON column userinfo.memo IS '備註';
--創建主鍵
alter TABLE userinfo ADD CONSTRAINT tb_test_p_name PRIMARY KEY (NAME);
--提交以上操作
COMMIT;

                  --創建表
                  CREATE TABLE student(
                        sid Varchar2(20) PRIMARY KEY  NOT NULL,
                        sname varchar2(20) NOT NULL,
                        sbirth DATE,
                        sclass varchar2(20) NOT NULL,
                        saddress varchar2(100)
                  )TABLESPACE mydb;


                  CREATE TABLE department(
                        did Varchar2(20) PRIMARY KEY  NOT NULL,
                        dname varchar2(40),
                        doffice VARCHAR2(100),
                        dtelphone varchar2(20),
                        dprincipal varchar2(20)
                  )TABLESPACE mydb;


   CREATE TABLE CLASS(
          cid Varchar2(20) PRIMARY KEY  NOT NULL,
                        department varchar2(20), 
                        cname VARCHAR2(20)
                  )TABLESPACE mydb;
                  --提交以上操作
                  COMMIT;
--插入測試數據:
INSERT INTO student(SID,sname,sbirth,sclass,saddress)
VALUES('201005101','楊過',Date'1990-07-11','C001','湖南長沙');
INSERT INTO student(SID,sname,sbirth,sclass,saddress)
VALUES('201005102','小龍女',Date'1992-05-11','C002','雲南大理');
INSERT INTO student(SID,sname,sbirth,sclass,saddress)
VALUES('201005103','趙敏',Date'1995-04-01','C001','湖北武漢');
INSERT INTO student(SID,sname,sbirth,sclass,saddress)
VALUES('201005104','李莫愁',Date'1950-11-21','C001','北京');
INSERT INTO student(SID,sname,sbirth,sclass,saddress)
VALUES('201005105','段然',Date'1980-12-25','C002','四川成都');
INSERT INTO student(SID,sname,sbirth,sclass,saddress)
VALUES('201005106','阿珠',Date'1970-07-10','C002','重慶');
INSERT INTO student(SID,sname,sbirth,sclass,saddress)
VALUES('201005107','株珠',Date'1997-07-10','C003','廣東東莞');

INSERT INTO CLASS(cID,department,cname)VALUES('C001','d001','軟件一班');
INSERT INTO CLASS(cID,department,cname)VALUES('C002','d001','軟件二班');
INSERT INTO CLASS(cID,department,cname)VALUES('C003','d002','建築一班');

INSERT INTO department(did,dname,doffice,dtelphone,dprincipal)
VALUES('d001','計算機系','計算機樓','086-88764278','歐陽鋒');
INSERT INTO department(did,dname,doffice,dtelphone,dprincipal)
VALUES('d002','建築工程系','工程樓','086-88764285','黃華華');
--------------------------------Oracle第三章Oracle模式對象-----------------------------------
 --查看錶(編輯表)
SELECT rowid ,student.* FROM student;
SELECT * FROM CLASS FOR UPDATE;
SELECT * FROM department; 
 --約束
ALTER TABLE class
ADD CONSTRAINT FK_department
FOREIGN KEY (department) REFERENCES department(did);

ALTER TABLE student
ADD CONSTRAINT FK_sclass
FOREIGN KEY (sclass) REFERENCES class(cid);
--查詢語句
SELECT student.SID,student.sname,student.sbirth,class.cname,department.dname FROM CLASS 
INNER JOIN student ON class.cid=student.sclass
INNER JOIN department ON department.did=class.department;
 --權限
GRANT CREATE VIEW,CREATE SEQUENCE,CREATE SYNONYM TO admin_1;

--創建視圖
CREATE VIEW view_student AS
SELECT * FROM student;
--查看視圖
SELECT * FROM VIEW_student
--刪除視圖
       DROP VIEW VIEW_student

--創建索引
CREATE INDEX index_sname ON student(sname);
--查看索引
SELECT * FROM all_indexes;
--刪除索引
DROP INDEX index_sname;

--創建序列號
CREATE SEQUENCE seq_student
START WITH 1
INCREMENT BY 1
--添加序列號
INSERT INTO student(SID,sname,sbirth,sclass,saddress)
VALUES(seq_student.nextval,'Tony',Date'1995-07-10','C001','廣東東莞');
--查看序列號
SELECT seq_student.nextval FROM dual;
 --刪除序列號
DROP sequence seq_student 


 --同義詞
CREATE SYNONYM stu FOR mydb.studnet
 --查看
SELECT * FROM stu;
 --刪除
DROP SYNONYM stu;

--------------------------------Oracle第四章PL/SQL程序設計-----------------------------------  
--聲明輸出
DECLARE 
    number1 INTEGER:=90;
BEGIN
    dbms_output.put_line(number1);
END;

/*
--------PL/SQL塊-----------
聲明(DECLARE)
    變量,遊標等
開始(BEGIN)
    SQL語句或者PL/SQL語句
異常(EXCEPTION)
    異常處理
結束(END)

*/
SELECT * FROM STUDENT;

DECLARE
      NAME VARCHAR2(20);  
BEGIN
      SELECT sname INTO NAME FROM student WHERE SID='201005101';
      dbms_output.put_line(NAME);
END;
--if-else條件控制
DECLARE 
     u1 NUMBER:=50;
     u2 NUMBER:=50;
BEGIN
     IF u1<u2 THEN
       dbms_output.put_line('u1小於u2');
     ELSIF u1>u2 then
       dbms_output.put_line('u1大於u2');
     ELSE
       dbms_output.put_line('u1等於u2');
     END IF;
END;
---case條件控制
BEGIN
    CASE '&level'
      WHEN 'A' THEN  dbms_output.put_line('優秀');
      WHEN 'B' THEN  dbms_output.put_line('良好');
      WHEN 'C' THEN  dbms_output.put_line('一般');
      WHEN 'D' THEN  dbms_output.put_line('還需努力');
   END CASE;
END;
--loop...exit...end loop循環控制
/*
loop
  循環語句塊
    if 條件 then
    exit
    end if;
end loop;
*/
DECLARE
   number1 Integer:=50;
   number2 INTEGER:=60;
   i INTEGER:=0;
BEGIN
  LOOP
     number1:=number1+1;
     IF number1=number2 THEN
       EXIT;
     END IF;
     i:=i+1;
  END loop;
  dbms_output.put_line('共循環次數:'||to_char(i));
END;

--loop...exit...when...end loop循環
DECLARE
     i NUMBER:=0;
BEGIN
     LOOP
       i:=i+1;
       dbms_output.put_line('共循環次數:'||to_char(i));
       EXIT WHEN i>10;
     END LOOP;
END;

--for...in..loop..end循環控制
DECLARE
      i NUMBER:=0;
BEGIN
  FOR i IN 1..10 LOOP
    dbms_output.put_line(to_char(i));
  END LOOP; 
END;
--while...loop..end loop
DECLARE
   number1 Integer:=50;
   number2 INTEGER:=60;
   i INTEGER:=0;
BEGIN
  WHILE number1<number2 LOOP
    NUMBER1:=NUMBER1+1;
    i:=i+1;
  END loop;
  dbms_output.put_line('共循環次數:'||to_char(i));
END;

/*
九九乘法表
*/

--if循環
DECLARE
  i NUMBER:=1;
  j NUMBER:=1;
BEGIN
  FOR i IN 1..9 LOOP
    FOR j IN 1..i LOOP
      dbms_output.put(j||'*'||i||'='||i*j||'  ');

    END LOOP;
     dbms_output.put_line('');
  END LOOP;
END;
--goto語句
  BEGIN
      GOTO put;
  dbms_output.put_line('這句話不會執行');
    <<put>>
       dbms_output.put_line('跳到這裏了');
  END;
--exp01:
DECLARE
   classname VARCHAR2(20);
BEGIN
   SELECT cname INTO classname FROM student,CLASS WHERE student.sclass=class.cid AND SID='&stuid';
   IF classname='軟件一班'THEN
       dbms_output.put_line('發放獎金500');
   ELSIF classname='軟件二班'THEN
        dbms_output.put_line('發放獎金300');
   ELSE
     dbms_output.put_line('無獎金');
    END IF;
END; 
--exp02:
CREATE TABLE temp_table(
      ID NUMBER,
      NAME VARCHAR2(20)
);


DECLARE
 i NUMBER:=1;
 NAME VARCHAR2(20):='HelloWord';
BEGIN
   FOR i IN 1..6 LOOP
      INSERT INTO temp_table(ID,NAME) VALUES(i,NAME);
     END LOOP;  
END;

SELECT ROWID,temp_table.* FROM temp_table;

--預定義異常
DECLARE
  sname VARCHAR2(20);
BEGIN
 SELECT sname INTO sname FROM student;
  EXCEPTION
    WHEN TOO_MANY_ROWS THEN
       dbms_output.put_line('出現返回了多行的異常'); 
END;

--自定義異常
DECLARE
--定義異常
  not_in EXCEPTION;
  city VARCHAR2(20);
BEGIN
  city := '&name';
IF city NOT IN('長沙','常德','北京') THEN
    RAISE not_in;
END IF;
EXCEPTION
WHEN not_in THEN 
    dbms_output.put_line('輸入的地名不正確!');
end;

--------------------------------Oracle第五章遊標------------------------------------
select * from student;
-------------------------------隱式遊標-------------------------------------
--%found遊標:DML語句影響一行或者多行是,%found屬性返回true
begin
  update student set sid='201005108'where sid='1';
  if sql%found then
    dbms_output.put_line('存在記錄');
  else
    dbms_output.put_line('不存在記錄');
  end if; 
end;
--%notfound遊標:與%found遊標作用相反
begin
  delete from student where sid='1';
  if sql%notfound then
    dbms_output.put_line('刪除失敗');
  end if;
end;
--%rowcount遊標:返回DML語句執行的行數
begin
 update student set sid='201005109'where sid='2';
  if sql%rowcount=0 then
    dbms_output.put_line('沒有查詢到數據');
  else
    dbms_output.put_line('查詢到'||sql%rowcount||'條數據');
  end if;
end;
--Cursor for loop遊標遍歷查詢結果集
begin
  for s in(select sid,sname,saddress from student)
  loop
    dbms_output.put('學生編號'||s.sid||'  ');
    dbms_output.put('學生姓名'||s. sname||'  ');
    dbms_output.put_line('學生住址'||s.saddress);
  end loop;
end;
--------------------------自定義顯示遊標------------------------------------
declare
  cursor cur_class is
  select * from class ;
  cid varchar2(20);
  department varchar2(20);
  cname varchar2(20);
begin
  open cur_class;
  loop
    fetch cur_class into cid,department,cname; --從遊標中提取數據
    exit when cur_class%notfound;
    dbms_output.put('科目編號'||cid||'  ');
    dbms_output.put('教師編號'||department||'  ');
    dbms_output.put_line('住址'||cname);
  end loop;
  close cur_class;
end;

-----------顯示遊標帶參(參數不能帶長度)--------------
declare
  cursor cur_class(id class.cid%type) is
       select * from class where cid=id  ;
  crow class%rowtype; --行類型
  id class.cid%type;
begin
  id := '&id';
  open cur_class(id);
  loop
    fetch cur_class into crow  ; --從遊標中提取數據
    exit when cur_class%notfound;
     dbms_output.put('科目編號'||crow.cid||'  ');
     dbms_output.put('教師編號'||crow.department||'  ');
     dbms_output.put_line('住址'||crow.cname);
  end loop;
  close cur_class;
end;


--遊標for循環
declare
  cursor cur_student is
  select * from student;
begin
  for s in cur_student
    loop
    dbms_output.put('學生編號'||s.sid||'  ');
    dbms_output.put('學生姓名'||s.sname||'  ');
    dbms_output.put_line('學生住址'||s.saddress);
    end loop;
end;
--遊標for循環的上機練習2
begin
  for showclass_cur in (select * from class) loop
    dbms_output.put_line('班級名:'||showclass_cur.cid);
    for showstu_cur in (select * from student where sclass=showclass_cur.cid) loop
      dbms_output.put_line('學生名:'||showstu_cur.sname);
    end loop;
  end loop;
end;
----------------遊標變量--------------------
declare
--聲明遊標類型
   type stu_cur is ref cursor return student%rowtype;
--聲明遊標變量
   stu_cur_type stu_cur ;
--聲明接收結果集變量
  sturow student%rowtype;
begin
  --打開遊標
  open stu_cur_type for select * from student;
  loop
    fetch stu_cur_type into sturow;--接收stu_cur_type遊標變量中的結果集
    exit when stu_cur_type%notfound;
    dbms_output.put('學生編號'||sturow.sid||'  ');
    dbms_output.put('學生姓名'||sturow.sname||'  ');
    dbms_output.put_line('學生住址'||sturow.saddress);
  end loop;
  --關閉遊標
  close stu_cur_type;
end;




------------第六章存儲過程---------------
select * from student;
--聲明無參proc
create  procedure showstudent as
begin
 for student_cur in (select * from student)
 loop
     dbms_output.put('學號:'||student_cur.sid||' ');
     dbms_output.put('姓名:'||student_cur.sname||' ');
     dbms_output.put_line('住址:'||student_cur.saddress);
 end loop;
end showstudent;
--調用proc
begin
  showstudent;
  --exec showstudent;
end;

--查看存儲過程
select text from user_source where name = 'SHOWSTUDENT';
--刪除proc
drop procedure showstudent;



--聲明有參proc(in,out參數類型)
create or replace procedure GetStuInfo(id in varchar2,sname out varchar2,cname out varchar2) is
begin
  select s.sname,c.cname into sname,cname from 
  student s join class c on s.sclass=c.cid where s.sid=id;
exception
    --no_data_found異常是在找不到一條記錄時報錯
    --dup_val_on_index唯一索引重複報錯
   when no_data_found then
     dbms_output.put_line('該學生信息不存在!');
   commit;
end GetStuInfo;
--調用proc
declare
  stuname varchar2(20);
  calssname varchar2(20); 
begin
  GetStuInfo('201005106',stuname,calssname);
  dbms_output.put('學生姓名:'||stuname||'  ');
  dbms_output.put_line('班級名稱:'||calssname||'  ');
end;


--聲明有參proc(in out參數類型)
--給電話號碼增加區碼
create or replace procedure add_region(tel_num in out varchar2)
as
begin
  tel_num := '0735-'||tel_num;
end add_region;
--調用add_region存儲過程
declare
  phone varchar2(15):='84541542';
begin
  add_region(phone);
  dbms_output.put_line('新電話號碼爲:'||phone);
end;

--存儲函數
create or replace function getsnamebyid(id varchar2)
  return varchar2 --聲明返回值類型
as
  name varchar2(20);--接收值的變量
begin
  select sname into name from student where sid=id;
  return(name); --返回值 
exception
  when no_data_found then
    dbms_output.put_line('沒有數據');
    return(null);
  when others then
    dbms_output.put_line('發生其他錯誤');
    return(null);
end;
--調用函數
begin
   dbms_output.put_line(getsnamebyid('201005101'));
end;



select * from student;
select * from class;
--計算當前的年份差select語句
select floor(to_number(sysdate-to_date(student.sbirth))/365) from student;
--自定義計算當前的年份差timepoor函數
create or replace function time_poor (years in varchar2) return varchar2
as
timepoor varchar2(20);
begin
  select floor(to_number(sysdate-to_date(years,'yyyy-mm-dd'))/365) into timepoor from dual;
  return(timepoor);
end;
--調用function
begin
  if time_poor('1998-01-05')>=18 then
    dbms_output.put_line('成年!');
  else
    dbms_output.put_line('未成年!');
  end if;
  --dbms_output.put_line('時間差爲:'||time_poor('2001-01-05'));
end;


------------------程序包--------------------
create or replace package stuInfo is --聲明包頭
  function getclassname(id varchar2) return varchar2; ---根據班級號獲得班級名稱函數
  procedure showstu;  ---獲得學生信息列表proc

end; 

create or replace package body stuInfo --包體部分
as
---根據班級號獲得班級名稱函數--
  function getclassname(id varchar2)
     return varchar2
 is
    classname varchar2(20);
  begin
    select cname into classname from class where cid=id;
    return(classname);
  exception
    when no_data_found then
      dbms_output.put_line('沒有數據');
      return(null);
    when others then
      dbms_output.put_line('發生其他錯誤');
      return(null);
  end;
  ---獲得學生信息列表proc--
  procedure showstu
  is
  begin
    for stu in (select * from student) loop
      dbms_output.put('學生編號爲:'||stu.sid||'       ');
      dbms_output.put('學生姓名爲:'||stu.sname||'     ');
      dbms_output.put_line('學生住址爲:'||stu.saddress||' ');
    end loop;
  end showstu;
end stuInfo;

--刪除程序包
drop package stuinfo;

--調用程序包
begin 
  dbms_output.put_line('班級名稱爲:'||stuinfo.getclassname('C005'));
   dbms_output.put_line('----------------------------------');
  dbms_output.put_line('----學生列表----');
  stuInfo.showstu;
end;


------------------------第七章觸發器-------------------------
-----------------------表操作----------------------
create table temp(
  Del_name varchar2(20),
  Del_time date
)TABLESPACE mydb;

--新增字段 [alter table 表名 add 字段名 字段類型;]
alter  table temp add v_type varchar2(15);
--修改字段名 [alter table 表名 rename column 原字段名 to 新字段名;]
alter table temp rename column  V_TYPE to t_type;
--刪除字段 [alter table 表名 drop column 字段名;]
alter table temp drop column  t_type;
--修改表名
alter table temp rename                                                                                                             .........
                                                                                                                                                                                                                                                                                                                                                                  to recordtable;

--語句級觸發器(未使用for each now):不管DML語句影響多少行 也只調用一次觸發器
--創建多條件觸發器(當刪除學員以後觸發插入語句 插入數據到recordtable表中)
create or replace trigger t_student_trigger
after --觸發時機
delete or update or insert  --觸發事件
on student --觸發目標
begin
  if deleting then
    insert into recordtable values(user,sysdate,'delete');  --觸發操作
  elsif updating then
    insert into recordtable values(user,sysdate,'update');  --觸發操作
  elsif inserting then
    insert into recordtable values(user,sysdate,'insert');  --觸發操作
  end if;
end;

--刪除student表中數據
delete from student where sid='201005108';
--插入student數據
INSERT INTO student(SID,sname,sbirth,sclass,saddress)
VALUES('201005108','Tong',Date'1991-07-10','C002','美國紐約');
--更改student表中數據
update student set sname='李逍遙' where sid='201005107';
--查詢recordtable表
select * from recordtable for update;


--行級觸發器(使用for each now):DML語句影響多少行數據的時候 對其中的每行數據都會調用觸發器
--[標識符:new和:old]
create or replace trigger t_student_trig
  after delete on student 
  for each row --行內觸發器標誌
    when(old.sid = '201005108') --條件標識符不能加冒號
begin
  insert into recordtable values(:old.sid,sysdate,'delete_row');  --觸發操作
end;
--測試行級觸發器
delete  from student where sid > '201005106';

--instead of觸發器(基於多表視圖是無法進行insert,update,delete操作)
--創建學生學分視圖
create or replace view stu_cla_view as
select sname,cname,cps,sclass
from class,student
where class.cid=student.sclass;
 --查看視圖
 select * from user_updatable_columns
 where table_name=upper('stu_cla_view');

select * from stu_cla_view;

 --測試是否能更新視圖 
 update stu_cla_view set cname='軟件二班' where sclass='C002';
-- delete from stu_cla_view  where cname='經管一班';
 select * from student;
 select * from class;
 --更新視圖trig
 create or replace trigger update_view
 instead of update
 on stu_cla_view 
 for each row
 begin
      update class
      set cname=:new.cname
      where cid=:new.sclass;
 end;


--系統事件觸發
--數據庫關閉時記錄的關閉時間
create or replace trigger db_close_trig
before shutdown
on database
begin
  dbms_output.put_line('系統於'||sysdate||'關閉');
end;

--用戶事件觸發器:DDL語句或者用戶註冊登錄等事件的時候觸發
create table user_log(
username varchar2(20),
log_date timestamp,
l_type varchar2(20)
)
--創建觸發器
--登錄觸發器
create or replace trigger logon_trig
after logon on schema
begin
  insert into user_log values(user,sysdate,'Logon');
end;
--註銷
create or replace trigger logff_trig
before logoff on schema
begin
  insert into user_log values(user,sysdate,'logoff');
end;
--測試用戶事件觸發器
select * from user_log;

--查看觸發器
select trigger_name,trigger_type,triggering_event from user_triggers
where trigger_name=upper('T_STUDENT_TRIG');


---------------------使用觸發器和序列自動增長-----------------------
create table test(
id number primary key,
name varchar2(20)
)
  --創建序列號
  create sequence seq_test_id
  start with 1
  increment by 1
  --創建觸發器
  create or replace trigger test_trig
    before insert
    on test 
    for each row
  declare
    next_id number; --接收序列號變量
  begin
    select seq_test_id.nextval into next_id from dual;
    :new.id := next_id;
  end test_trig;

select * from test;

--測試
insert into test
  (name)
values
  ('Pater');

-----------------第八章數據庫備份與恢復--------------------
select name,created,log_mode from V$database;



select * from test;
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章