.Net程序员学用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
版权声明:本文为博客园博主 韩宗泽 原创,作者保留署名权!欢迎通过转载、演绎或其它传播方式来使用本文,但必须在明显位置给出作者署名和本文链接!本人初写博客,水平有限,若有不当之处,敬请批评指正,谢谢!

posted @ 2017-01-11 18:44  韩宗泽  阅读(2171)  评论(0编辑  收藏  举报
回到顶部