- 1、准備說明
- 1.1、為什么要創建的測試環境?
- 1.2、了解 Oracle 實例的默認用戶
- 2、環境說明
1、准備說明
1.1、為什么要創建的測試環境?
我在構思本系列博客的時候,並沒有想到要做什么准備;但當我寫完六七篇稿子的時候,我忽然意識到如下的一系列問題:
-
有些跟時間有關的示例,我有用
SYSDATE
來演示,當讀者把博文中的 SQL 語句拷貝到他的環境中運行時,SYSDATE
的值肯定已經變了,那樣的話,讀者就得花更多的時間來思考和理解其中的不同。 -
部分關於 DML、DQL 的示例,主要演示的是語法而非結果,而且有些示例的結果很長,全都展示出來太占篇幅,不利於讀者閱讀。准確的理解語法和靈活的運用語法才是關鍵,要做到這兩點就必需輔以練習。而讀者的環境中可能沒有方便練習的表結構和數據,自己造自然是好的,但這可能需要花費讀者較多的時間,明顯有悖於本系列博文所追求的 實用 和 省時。
-
Oracle 中的權限很多很復雜,不同的 Oracle 版本還不太一樣,讀者可能會遇到模仿示例改的 SQL 語句在自己的環境中運行結果變少、變多,甚至直接報錯,這都有可能權限的問題,而經驗不多的開發者往往找不到問題的原因,這給他們的理解帶來了非必要的困難,某些初學者甚至會懷疑自己的理解能力和智商!這是我本人非常不願意看到。
基於對以上等問題的思考,最終我決定要創建一個的測試環境,並把前面寫好的稿子重新寫一遍,這樣作者和讀者就能擁有相同的運行環境,方便了二者之間的交流。
1.2、了解 Oracle 實例的默認用戶
在正式創建環境之前,我們需要先來了解下 Oracle 實例的默認用戶。在創建好一個 Oracle 實例之后,這個實例就已經包含了多個默認用戶,不同的 Oracle 版本有所差異,但一定會有 sys 和 system 兩個用戶。其中 sys 是超級用戶,數據字典所有者,擁有最高權限,而 system 是普通管理用戶,擁有 dba 權限。我們一般都是用這兩個用戶其中的一個來完成創建新的用戶或表空間等需要較高權限的操作,有關這兩個用戶的其它疑問建議讀者自行百度,網上有大量的相關介紹和說明。
2、環境說明
首先我得說明的是,由於本系列博文將要介紹的知識點較多,有些操作會有順序要求,不同的章節對演示環境的要求也不太一樣,所以無法一次性創建一個能滿足后續所有演示需要的環境。所以我會首先創建一個基本的環境,然后在后續需要的時候來不斷的完善或修改這個環境,以達到演示的需要。
2.1、創建環境
第1步:以管理員身份登錄數據庫。登錄用戶必須擁有 dba 權限,否則無權進行后續部分操作,如創建數據庫。
第2步:創建一個數據庫用戶並授予 dba 權限。示例:
CREATE USER demo IDENTIFIED BY test; -- 創建用戶 demo 同時設置登錄密碼為 test
GRANT CONNECT,RESOURCE,DBA TO demo; -- 授予 demo 用戶 dba 權限
第3步:創建數據庫對象。這一步操作建議用 demo 用戶來完成,方便后續操作和測試,這也是創建 demo 用戶的原因。退出 sys 用戶,換成 demo 用戶連接為 Normal 登錄,然后執行如下語句(需要特別強調的是如下語句必須逐條執行,否則部分對象會創建失敗!):
CREATE TABLE t_staff(
staff_id NUMBER(10),
staff_name VARCHAR2(50) NOT NULL,
dept_code VARCHAR2(50) NOT NULL,
gender NUMBER(1),
birthday DATE,
edu_bg NUMBER(1),
marital_status NUMBER(1),
post_code VARCHAR2(50) NOT NULL,
manager_id NUMBER(10),
hire_date DATE,
base_salary NUMBER(10,2),
post_salary NUMBER(10,2),
is_disabled NUMBER(1) DEFAULT(0),
CONSTRAINT pk_staff PRIMARY KEY(staff_id)
);
COMMENT ON TABLE t_staff IS '職員表';
COMMENT ON COLUMN t_staff.staff_id IS '職員ID';
COMMENT ON COLUMN t_staff.staff_name IS '職員姓名';
COMMENT ON COLUMN t_staff.dept_code IS '部門編碼{DEPT}';
COMMENT ON COLUMN t_staff.gender IS '性別{1男/0女}';
COMMENT ON COLUMN t_staff.birthday IS '出生日期';
COMMENT ON COLUMN t_staff.edu_bg IS '教育背景{1大專/2本科/3其它}';
COMMENT ON COLUMN t_staff.marital_status IS '婚姻狀況{1未婚/2已婚/3離異/4喪偶}';
COMMENT ON COLUMN t_staff.post_code IS '崗位代碼{POST}';
COMMENT ON COLUMN t_staff.manager_id IS '負責人';
COMMENT ON COLUMN t_staff.hire_date IS '入職日期';
COMMENT ON COLUMN t_staff.base_salary IS '基本工資';
COMMENT ON COLUMN t_staff.post_salary IS '崗位工資';
COMMENT ON COLUMN t_staff.is_disabled IS '是否禁用{1禁用/0啟用}';
CREATE SEQUENCE seq_staff_id INCREMENT BY 1 START WITH 1;
CREATE OR REPLACE TRIGGER trg_staff_id
BEFORE INSERT ON t_staff
FOR EACH ROW
BEGIN
IF :new.staff_id>0 THEN
RETURN;
ELSE
SELECT seq_staff_id.NEXTVAL INTO :new.staff_id FROM DUAL;
END IF;
END;
CREATE TABLE t_field(
field_code VARCHAR2(50),
field_name VARCHAR2(50) NOT NULL,
field_order NUMBER(2) DEFAULT 0,
field_desc VARCHAR2(1000),
CONSTRAINT pk_field PRIMARY KEY(field_code)
);
COMMENT ON TABLE t_field IS '字段表';
COMMENT ON COLUMN t_field.field_code IS '字段編碼';
COMMENT ON COLUMN t_field.field_name IS '字段名稱,即漢語釋義';
COMMENT ON COLUMN t_field.field_order IS '排序,默認0';
COMMENT ON COLUMN t_field.field_desc IS '描述';
CREATE TABLE t_field_enum(
enum_id NUMBER(10),
parent_enum_id NUMBER(10) DEFAULT 0 NOT NULL,
field_code VARCHAR2(50) NOT NULL,
enum_code VARCHAR2(50) NOT NULL,
enum_name VARCHAR2(50) NOT NULL,
enum_level NUMBER(2) DEFAULT 1,
enum_order NUMBER(2) DEFAULT 0,
enum_status NUMBER(1) DEFAULT 1,
CONSTRAINT pk_field_enum PRIMARY KEY(enum_id)
);
COMMENT ON TABLE t_field_enum IS '字段枚舉表';
COMMENT ON COLUMN t_field_enum.enum_id IS '枚舉ID';
COMMENT ON COLUMN t_field_enum.parent_enum_id IS '父枚舉ID';
COMMENT ON COLUMN t_field_enum.field_code IS '字段編碼';
COMMENT ON COLUMN t_field_enum.enum_code IS '枚舉編碼';
COMMENT ON COLUMN t_field_enum.enum_name IS '枚舉名稱,即漢語釋義';
COMMENT ON COLUMN t_field_enum.enum_level IS '等級,默認1';
COMMENT ON COLUMN t_field_enum.enum_order IS '排序,默認0';
COMMENT ON COLUMN t_field_enum.enum_status IS '狀態,默認1{1啟用|0禁用}';
CREATE SEQUENCE seq_field_enum_id INCREMENT BY 1 START WITH 1;
CREATE OR REPLACE TRIGGER trg_field_enum_id
BEFORE INSERT ON t_field_enum
FOR EACH ROW
BEGIN
IF :new.enum_id>0 THEN
RETURN;
ELSE
SELECT seq_field_enum_id.NEXTVAL INTO :new.enum_id FROM DUAL;
END IF;
END;
CREATE OR REPLACE VIEW v_staff AS
SELECT t1.staff_id,t1.staff_name,t1.dept_code,t2.enum_name dept_name,t1.gender,
t1.birthday,EXTRACT(YEAR FROM SYSDATE)-EXTRACT(YEAR FROM t1.birthday) age,
t1.edu_bg,t1.base_salary,t1.post_salary,base_salary+post_salary fixed_salary
FROM demo.t_staff t1
LEFT JOIN demo.t_field_enum t2 ON t1.dept_code=t2.enum_code AND t2.field_code='DEPT'
WHERE t1.is_disabled=0
-- 在職員工檔案視圖
;
CREATE OR REPLACE FUNCTION fn_now
RETURN DATE IS
v_now DATE;
-- 返回當前時間(為了方便演示,假定當前時間始終為 fn_now)
BEGIN
v_now:=TO_DATE('2017-01-10 19:21:30','yyyy-mm-dd hh24:mi:ss');
RETURN v_now;
END;
CREATE OR REPLACE FUNCTION fn_today
RETURN DATE IS
v_today DATE;
-- 返回當前日期(為了方便演示,假定當前日期始終為 fn_today)
BEGIN
v_today:=TO_DATE('2017-01-10','yyyy-mm-dd');
RETURN v_today;
END;
第4步:初始化測試數據。依然用 demo 用戶登錄,然后執行如下語句:
INSERT ALL
INTO demo.t_field(field_code, field_name, field_order, field_desc)
VALUES('DEPT','部門編碼字段',1,'部門編碼前兩位表示一級部門,二到四位表示二級部門,五到六位表示三級部門')
INTO demo.t_field(field_code, field_name, field_order, field_desc)
VALUES('POST','崗位代碼字段',2,'崗位代碼均以字母P開頭,后跟兩位數字代表崗位的級別')
SELECT * FROM dual;
COMMIT;
INSERT ALL
INTO demo.t_field_enum(field_code, enum_code, enum_name, enum_level, enum_order)
VALUES('DEPT','010000','軟件部',1,1)
INTO demo.t_field_enum(field_code, enum_code, enum_name, enum_level, enum_order)
VALUES('DEPT','020000','數據部',1,2)
INTO demo.t_field_enum(field_code, enum_code, enum_name, enum_level, enum_order)
VALUES('DEPT','030000','市場部',1,3)
INTO demo.t_field_enum(field_code, enum_code, enum_name, enum_level, enum_order)
VALUES('DEPT','040000','銷售部',1,4)
INTO demo.t_field_enum(field_code, enum_code, enum_name, enum_level, enum_order)
VALUES('DEPT','050000','人事部',1,5)
INTO demo.t_field_enum(field_code, enum_code, enum_name, enum_level, enum_order)
VALUES('DEPT','060000','財務部',1,6)
SELECT * FROM dual;
COMMIT;
INSERT ALL
INTO demo.t_field_enum(parent_enum_id,field_code, enum_code, enum_name, enum_level, enum_order)
VALUES(1,'DEPT','010100','開發部',2,1)
INTO demo.t_field_enum(parent_enum_id,field_code, enum_code, enum_name, enum_level, enum_order)
VALUES(1,'DEPT','010200','工程部',2,2)
SELECT * FROM dual;
COMMIT;
INSERT ALL
INTO demo.t_field_enum(field_code, enum_code, enum_name, enum_order)
VALUES('POST','P10','CEO、COO、CFO等O',1)
INTO demo.t_field_enum(field_code, enum_code, enum_name, enum_order)
VALUES('POST','P20','總監',2)
INTO demo.t_field_enum(field_code, enum_code, enum_name, enum_order)
VALUES('POST','P30','經理',3)
INTO demo.t_field_enum(field_code, enum_code, enum_name, enum_order)
VALUES('POST','P40','主管',4)
INTO demo.t_field_enum(field_code, enum_code, enum_name, enum_order)
VALUES('POST','P50','員工',5)
SELECT * FROM dual;
COMMIT;
INSERT ALL
INTO demo.t_field_enum(parent_enum_id,field_code, enum_code, enum_name, enum_level, enum_order)
VALUES(7,'DEPT','010101','研發一部',3,1)
INTO demo.t_staff(staff_name, dept_code, gender, birthday, edu_bg, base_salary, post_salary, post_code)
VALUES('小明','010101',1,TO_DATE('1988-05-08','yyyy-mm-dd'),2,2500,8000,'P40')
INTO demo.t_staff(staff_name, dept_code, gender, birthday, edu_bg, base_salary, post_salary, post_code)
VALUES('小強','010101',1,TO_DATE('1990-07-08','yyyy-mm-dd'),2,2500,6000,'P50')
INTO demo.t_staff(staff_name, dept_code, gender, birthday, edu_bg, base_salary, post_salary, post_code)
VALUES('王二','010101',1,TO_DATE('1992-09-02','yyyy-mm-dd'),1,2500,1850,'P50')
SELECT * FROM dual;
COMMIT;
INSERT ALL
INTO demo.t_field_enum(parent_enum_id,field_code, enum_code, enum_name, enum_level, enum_order)
VALUES(7,'DEPT','010102','研發二部',3,2)
INTO demo.t_staff(staff_name, dept_code, gender, birthday, edu_bg, base_salary, post_salary, post_code)
VALUES('小林','010102',1,TO_DATE('1989-10-12','yyyy-mm-dd'),2,2500,7500,'P40')
INTO demo.t_staff(staff_name, dept_code, gender, birthday, edu_bg, base_salary, post_salary, post_code)
VALUES('小薩','010102',1,TO_DATE('1986-03-07','yyyy-mm-dd'),1,2500,6000,'P50')
SELECT * FROM dual;
COMMIT;
INSERT ALL
INTO demo.t_field_enum(parent_enum_id,field_code, enum_code, enum_name, enum_level, enum_order)
VALUES(7,'DEPT','010103','研發三部',3,3)
INTO demo.t_staff(staff_name, dept_code, gender, birthday, edu_bg, base_salary, post_salary, post_code)
VALUES('韓三','010103',1,TO_DATE('1993-08-18','yyyy-mm-dd'),1,2500,5050,'P40')
INTO demo.t_staff(staff_name, dept_code, gender, birthday, edu_bg, base_salary, post_salary, post_code)
VALUES('小玲','010103',0,TO_DATE('1994-06-17','yyyy-mm-dd'),1,2500,2800,'P50')
SELECT * FROM dual;
COMMIT;
INSERT ALL
INTO demo.t_field_enum(parent_enum_id,field_code, enum_code, enum_name, enum_level, enum_order)
VALUES(7,'DEPT','010104','測試部',3,4)
INTO demo.t_staff(staff_name, dept_code, gender, birthday, edu_bg, base_salary, post_salary, post_code)
VALUES('小梅','010104',0,TO_DATE('1991-06-29','yyyy-mm-dd'),2,2500,4500,'P40')
INTO demo.t_staff(staff_name, dept_code, gender, birthday, edu_bg, base_salary, post_salary, post_code)
VALUES('小燕','010104',0,TO_DATE('1992-01-23','yyyy-mm-dd'),2,2500,3000,'P50')
SELECT * FROM dual;
COMMIT;
INSERT ALL
INTO demo.t_field_enum(parent_enum_id,field_code, enum_code, enum_name, enum_level, enum_order)
VALUES(8,'DEPT','010201','實施一部',3,1)
INTO demo.t_staff(staff_name, dept_code, gender, birthday, edu_bg, base_salary, post_salary, post_code)
VALUES('小軍','010201',1,TO_DATE('1989-03-20','yyyy-mm-dd'),1,2500,6000,'P40')
INTO demo.t_staff(staff_name, dept_code, gender, birthday, edu_bg, base_salary, post_salary, post_code)
VALUES('小芳','010201',0,TO_DATE('1990-01-28','yyyy-mm-dd'),2,2500,2500,'P50')
INTO demo.t_staff(staff_name, dept_code, gender, birthday, edu_bg, base_salary, post_salary, post_code)
VALUES('小紅','010201',0,TO_DATE('1992-04-16','yyyy-mm-dd'),2,2500,2000,'P50')
SELECT * FROM dual;
COMMIT;
INSERT ALL
INTO demo.t_field_enum(parent_enum_id,field_code, enum_code, enum_name, enum_level, enum_order)
VALUES(8,'DEPT','010202','實施二部',3,2)
INTO demo.t_staff(staff_name, dept_code, gender, birthday, edu_bg, base_salary, post_salary, post_code)
VALUES('小飛','010202',1,TO_DATE('1991-04-20','yyyy-mm-dd'),1,2500,5500,'P40')
SELECT * FROM dual;
COMMIT;
2.2、更新環境
-- 第 6 篇補充
CREATE TABLE t_staff_copy AS SELECT * FROM t_staff t;
示例添加(t_course、t_course_backup、t_staff2、t_staff3、t_staff4)
示例移除(t_staff_mini、t_staff90)
-- 第 7 篇補充
CREATE TABLE t_staff_young AS
SELECT t.staff_id,t.staff_name,t.dept_code,t.gender FROM t_staff t
WHERE t.birthday>=TO_DATE('1990-01-01','yyyy-mm-dd');
-- 第 8 篇補充
添加數據
INSERT INTO t_course(course_id,course_name,course_desc) VALUES(5,'C/C++','計算機專業課程');
-- 第 11 篇補充
DROP INDEX idx_birthday;
DROP INDEX idx_dept_code;
DROP INDEX idx_gender;
DROP INDEX uk_staff_name;
ALTER TABLE t_staff_copy DROP CONSTRAINT uk_test;
ALTER TABLE t_staff_copy DROP CONSTRAINT fk_test;
CREATE TABLE t_staff_high AS
SELECT t.staff_id,t.staff_name,t.dept_code,t.gender FROM t_staff t
WHERE (t.base_salary+t.post_salary)>=8000;
CREATE TABLE t_staff_low AS
SELECT t.staff_id,t.staff_name,t.dept_code,t.gender FROM t_staff t
WHERE (t.base_salary+t.post_salary)<5000;
CREATE TABLE t_staff_salary AS
SELECT t.staff_id,t.staff_name,t.dept_code,t.base_salary+t.post_salary fixed_salary
FROM t_staff t;
-- 第 13 篇補充
示例添加(t1、t2)
添加數據(t_course(1,'計算機','工科'))
-- 第 19 篇補充
示例添加(t_staff_backup)
-- 第 25 篇補充
CREATE TABLE t_course_backup(
course_id NUMBER(10),
course_name VARCHAR2(50),
course_desc VARCHAR2(2000),
insert_date DATE,
inserted_by VARCHAR2(20),
update_date DATE,
updated_by VARCHAR2(20),
delete_date DATE,
deleted_by VARCHAR2(20)
);
CREATE TABLE t_ddl_log(
trg_event VARCHAR2(30),
obj_owner VARCHAR2(30),
obj_name VARCHAR2(30),
sql_id VARCHAR2(30),
sql_text VARCHAR2(4000),
user_name VARCHAR2(30),
attempt_time TIMESTAMP
);
CREATE TABLE demo.t_login_his(
program_name VARCHAR2(20),
user_name VARCHAR2(20),
login_time TIMESTAMP,
login_ip VARCHAR2(20)
);
-- 第 27 篇補充
添加數據
INSERT ALL
INTO t_course(course_id,course_name,course_desc) VALUES(2,'語文','中國文學')
INTO t_course(course_id,course_name,course_desc) VALUES(3,'數學','中國數學')
INTO t_course(course_id,course_name,course_desc) VALUES(4,'英語','外國文學')
SELECT * FROM DUAL;
CREATE TABLE t3(f1 NUMBER(10));
2.3、卸載環境
方法1:刪除數據,執行如下語句:
DROP SEQUENCE demo.seq_staff_id;
DROP SEQUENCE demo.seq_field_enum_id;
CREATE SEQUENCE demo.seq_staff_id INCREMENT BY 1 START WITH 1;
CREATE SEQUENCE demo.seq_field_enum_id INCREMENT BY 1 START WITH 1;
TRUNCATE TABLE demo.t_staff;
TRUNCATE TABLE demo.t_field;
TRUNCATE TABLE demo.t_field_enum;
方法2:刪除對象,執行如下語句:
DROP FUNCTION demo.fn_now;
DROP FUNCTION demo.fn_today;
DROP TRIGGER demo.trg_staff_id;
DROP TRIGGER demo.trg_field_enum_id;
DROP SEQUENCE demo.seq_staff_id;
DROP SEQUENCE demo.seq_field_enum_id;
DROP VIEW demo.v_staff;
DROP TABLE demo.t_staff;
DROP TABLE demo.t_field;
DROP TABLE demo.t_field_enum;
方法3:刪除用戶和用戶所擁有的對象,執行如下語句:
DROP USER demo CASCADE;
本文鏈接:http://www.cnblogs.com/hanzongze/p/oracle-environment.html
版權聲明:本文為博客園博主 韓宗澤 原創,作者保留署名權!歡迎通過轉載、演繹或其它傳播方式來使用本文,但必須在明顯位置給出作者署名和本文鏈接!本人初寫博客,水平有限,若有不當之處,敬請批評指正,謝謝!