Oracle bacic

 1.连接Oracle  2.操作数据库  3.单表查询  4.SUID  5.常用函数  6.集合运算  7.Oracle 对象  8.PL/SQL  9.存储函数  10.存储过程  11.触发器  


1.连接到数据库

Oracle 特点:
    多用户、大事务量
    数据安全性、完整性控制
    分布式处理
    可移植性

比较MySQL;更加强大

Oracle 数据库的体系结构
    逻辑结构:数据库、表空间、段、区、数据块
    物理结构:文件、数据块
    用户:

远程连接Oracle:

>sqlplus username/password@orcl
>sqlplus username/password@address:port/orcl

使用 PL-SQL Developer:指定连接时客户端工具信息   .

配置:
环境变量:指定 tnsnames.ora 位置
C:\Users\Administrator>echo %TNS_ADMIN%
C:\chuanzhi\PLS8\client\
连接工具:Oracle 主目录名(自动检测为空):
OCI 库(自动检测为空):
中文乱码:
select userenv('language') from dual;
C:\Users\Administrator>echo %NLS_LANG%
AMERICAN_AMERICA.AL32UTF8

JDBC 连接数据库:

Class.forName("oracle.jdbc.driver.OracleDriver");
Connection conn = DriverManager.getConnection("jdbc:oracle:thin:@address:port/instance", "username", "password");

2.操作数据库

  • 创建库、用户、授权角色

创建表空间、创建用户

创建表空间
create tablespace name
datafile 'C:\oracleDB\filename.dbf'
size 100m
autoextend on
next 10m; 创建用户
create user username
identified by password
default tablespace ts_name;
授权角色
grant dba to username;

创建表的方法

创建表
create table t_name (
column_name type_name key;
...
) 数据类型:
CHAR 固定长度
VARCHAR2 变长
LONG 大文本类型
NUMBER 数值型
DATE 日期时间

示例:创建表

例子:
create table t_owners(
id number primary key,
name varchar2(30),
addressid number,
housenumber varchar2(30),
watermeter varchar2(30),
adddate date,
ownertypeid number
);

SQL 语句分类:

SQL 语言:
DDL:cteate drop truncate
DML:update insert delete
DQL:select
DCL:grant revoke
  • DML 语句
增加数据:
insert into table_name (id,name) values (?,?);
commit; 删除数据:
delete from t_owners where id > 7 and id < 11;
commit; 修改数据:
update t_owners set column_name = value where id = ?;
commit;
  • 库的导入导出
整库的导入、导出
exp system/password full=y
imp system/password full=y 按用户导入、导出
exp system/password owner=username file=${PATH}/${filename}
imp system/password fromuser=username file=${PATH}/${filename} 按照表导入、导出
exp username/password tables=t1,t2,t3 file=C:\username.dmp
imp username/password tables=t1,t2,t3 file=C:\username.dmp

exp: 命令后边须紧跟 USERID(username/password)

示例:导出表、导入表;不指定名称,默认“EXPDAT.DMP”,是个二进制文件

Desktop>exp scott@orcl tables=dept
Desktop>imp test@orcl tables=dept

示例:导出时,指定文件名;指定为 “dept.sql”,是个文本文件。(还是个 DMP 二进制文件)

Desktop>exp test tables=dept file=dept.sql

示例:导时,指定文件名不带扩展名,会自动添加,扩展名 DMP。

Desktop>exp scott@orcl tables=emp file=emp
Desktop>imp test@orcl tables=emp file=emp

3.单表查询

  • 通配符: %、_(用在 like 子句中)
  • 匹配空值:is、is not
  • 排序:desc、asc

示例:查询某些特征的字符串

select * from t_owners where name like '__';--名字是俩字符
select * from t_owners where name like '刘%';--刘姓

示例:查询空值

select * from t_pricetable where maxnum is null;

示例:按列值排序

select * from t_account order by usenum asc;--升序
select * from t_account order by usenum desc;--降序
select * from t_account order by usenum;--默认升序

  既然默人按升序排列,又为啥显式指定呢?因为某些情况下获取了结果,某个列不是排序的,需要特别指明。

select o.id,o.name,ot.name from t_owners o, t_ownertype ot where o.ownertypeid = ot.id;--查询的结果未排序
select o.id,o.name,ot.name from t_owners o, t_ownertype ot where o.ownertypeid = ot.id order by o.id asc;

4.SUID

示例:增删改

String sql = "insert into t_edu values (?, ?)";
String sql = "update t_edu set name = ? where id = ?";
String sql = "delete from t_edu where id = ?";

示例:查询 伪列

select rowid,rownum,e.* from t_edu e;

ROWID 固定值;ROWNUM 虚值,结果排序

示例:内连接

select t1.name, t2.name
from t_owners t1, t_ownertype t2
where t1.ownertypeid = t2.id;

示例:外连接

select t1.name, t2.name
from t_owners t1 right join t_ownertype t2
on t1.ownertypeid = t2.id;

示例:分页,前 5 行

select rownum,a.* from t_account a where rownum < 5;

伪列 rownum 为最后的结果表 排序,只有 [小于]、[小于等于] 能查出结果。

  当需要查询 5~10 行,需要使用到子查询。在子查询的结果中使用伪列,最终结果表临时保存于内存中,外层查询是可以获取到虚拟表的 rownum 列信息。从而实现分页。

分页查询实现:子查询别名

示例:分页,查询 5~10 行

select *
from (select rownum r, a.* from t_account a)
where r > 5
and r < 10;

5.函数

  • 字符函数:length、substr、concat
  • 数值函数:round、trunc
  • 日期:add_months、last_day、
  • 转换:字符串、日期、数值互转,to_char、to_date、to_number
  • 条件:空值处理 nvl、条件取值 decode ...
  • 分析函数: 漏

示例:字符串长度

SELECT length('hello') from dual;
select id, length(name) from t_owners;

示例:截取子串

select substr('itheima', 2, 2) from dual;--th
select id, substr(name, 0, 1) from t_owners;--姓

示例:字符串拼爹

select 'hello ' || 'die.' from dual;
select concat('hello', 'die') from dual;

示例:四舍五入

select round(3.1415926) from dual; --
select round(3.1415926, -1) from dual; --
select round(3.1415926, 2) from dual; --3.14
select round(3.1415926, 3) from dual; --3.142

示例:截取(绝对值只会变小

select trunc(3.1415926) from dual; --
select trunc(3.1415926, 3) from dual; -- 3.141
select trunc(-3.1415926) from dual; -- -3 负数
select trunc(-3.1415926, 3) from dual; -- -3.141 负数

示例:12个月之前,一年后

select add_months(sysdate, -12) from dual;
select add_months(sysdate, 12) from dual;

示例:本月底最后一天的当前时间

select last_day(sysdate), last_day(sysdate + 1), last_day(sysdate + 4)
from dual;
-- 加号没有效果

时间:时间截取

select trunc(sysdate) from dual;--截取日期,截掉时间,效果-1
select trunc(sysdate,'y') from dual;--年份的第一天,没有时间
select trunc(sysdate,'mm') from dual;--年份和月份的第一天,没有时间
select trunc(sysdate,'dd') from dual;--等于 效果-1
select trunc(sysdate,'hh') from dual;--日期时间,分钟为零,秒为零
select trunc(sysdate,'mi') from dual;--日期时间,秒为零

示例:转字符串

select to_char(100) from dual; --
select to_char(sysdate, 'yy') from dual; --
select to_char(sysdate, 'yyyy') from dual; --
select to_char(sysdate, 'dd') from dual; --

示例:转成时间

select to_date('1988-3-16','yyyy-mm-dd') from dual;

示例:空值处理,为空是显示 null

select nvl(null, '空') 空值处理 from dual;--第一个参数为空时,返回第二个参数
select id,nvl(name,'null') from t_edu;--名称列出现空值时,显示字符串 null

  把数据库适合的表达方式翻译成程序容易接受理解的内容。

示例:空值处理,NVL2

???

  • 条件取值 decode(oxpr, case1, value1, case2, value2 ... [default]);
    • 表达是 expr,与 case 比较,比中就返回对应的 value 结束比对,未比中有默认就返回默认。

示例:条件取值(等值比较)

select decode(33, 13,'xi',33,'ha','def') from dual;--ha
select decode(34, 13,'xi',33,'ha','def') from dual;--def

  可以使用 case when then 达到一样甚至更加强大的效果,比较就不限于等值比较。

示例: case when then ...

select id,name,area,(case name
when 1 then v1
when 2 then v2
when 3 then v3
else 'other'
end ), (case area
when 1 then a1
when 2 then a2
when 3 then a3
else 'ao'
end ) from t_owners, t_area, t_address
...

6.集合运算

  • 并集(union):
  • 交集(intersect):
  • 差集(minus):

示例:union...

select * from t_account where id >40
intersect
select * from t_account where id <= 45;
select * from t_account where id in (47,48)
union
select * from t_account where id = 45;
select * from t_account where id in (47,48)
minus
select * from t_account where id = 45;

7.Oracle 对象

  • 视图 view
  • 序列 sequence
  • 同义词 synonym
  • 索引 index

示例:创建 视图

create view v_test
as
select * from t_test;--创建相同架构的视图 insert into v_test values(33, 'hhhe');
select * from v_test;--插入数据成功
select * from t_test;--插入视图,影响到了表
-----------------------
create view v_test2
as
select rownum id,t.id uuid,t.name from t_test t; select * from v_test2;
insert into v_test2 (uuid,name) values(44, 'work');--插入数据报错:视图操作不合法
-----------------------
create view v_owners
as
select * from t_owners;--创建名称为 v_owners 的视图
create or replace view v_owners
as
select rownum id,o.name,o.addressid,o.housenumber,o.watermeter from t_owners o;--创建视图时,有意隐藏某些列的信息

示例:删除创建视图的表,……

drop table t_test;
select * from v_test;--报错:视图不存在
--重新创建表
create table t_test(
id number,
name varchar2(30)
); insert into t_test values (29, 'xian');
insert into t_test values (10, 'beijing'); select * from t_test;
select * from v_test;--又能查询到数据
select * from v_test2;--又能查询到数据 --创建个其他架构的表,视图依然重新可查询
create table t_test(
id number,
name varchar2(30),
dirty varchar2(1)
);

  视图的检查约束,创建的视图内容属于表的某个形式的子集时,必然存在一些过滤条件(不包括分组)。这时再去操作视图,受到约束检查限制。

示例:创建带检查约束的视图

create view v_ownertype
as
select * from t_ownertype where id > 13;--不带检查约束的视图
create view v_ownertype
as
select * from t_ownertype where id > 13
with check option;--创建带检查约束的视图,条件 id > 13.

  只读视图,

示例:创建只读视图

create view v_ownertype
as
select * from t_ownertype where id > 13
with read only;--创建只读视图

  先创建视图,再创建相应的表。

示例:创建带错误的视图

create force view v_ownertype
as
select * from t_ownertype
with chek option;--带上 force 创建 错误视图

  物化视图,实体化视图,查询时,等于查询单表。

示例:创建物化视图

create meterialized view mv_test
as
select ...

  物化视图的刷新方式:增量、全量

  增量刷新的前提:为基表创建增量物化日志;创建视图时,增加日志依赖列

示例:创建序列

create sequence seq_test;--局部序列

  同义词,用来处理兼容性问题

示例:创建同义词

create synonym syn_owners for t_owners;--私有
create public synonym syn_owners for t_owners;--公共

  索引:提高查询效率

索引类型的选择,依据的是数据的类型情况:

  • -普通索引:非均态分布的线性数据
  • -反向键索引:均态分布的线性数据
  • -位图索引:非线性数据

示例:创建索引

create index in_name_owners on t_owners(name);--创建索引
create unique index ... --唯一索引
create index in_max_account on t_account(ownerid,ownertypeid);--复合索引
create index in_re_account on t_account(name) reverse;--反向键索引
create bitmap index in_dept on ... --位图索引

位图索引,创建列内容非线性……

8.PL/SQL

  • PL/SQL 语法
  • 变量
  • 异常
  • 条件、循环
  • 游标

PL/SQL 语法:

--变量: 变量名 类型(长度);
--赋值: 变量名:=值; [declare
--
]
begin
--
[exception
--
]
end;

示例:声明变量、并赋值

declare
var_price number(10,2);--单价
var_usenum number;
var_money number(10,2);--小计金额
begin
var_price:=3.14;
var_usenum:=23233;
var_money:=var_price*var_usenum;
end; --使用 SQL 语句赋值
begin
select usenum into var_usenum from t_account
where id = '';

示例:引用型声明变量

--属性类型(引用型 表名.列名%type)
declare
var_price t_account.price%type;--单价
var_usenum t_account.usenum%type;
var_money t_account.money%type;--小计金额
begin
select price,usenum into var_price,var_usenum from t_account where id = '';
var_money:=var_price*var_usenum;
end;

示例:记录型声明变量

--属性类型(记录型 表名%rowtype)
declare
var_row_account t_account%rowtype;--记录类型变量
begin
select * into var_row_account from t_account where id = '';
var_price:=var_row_account.price;
var_usenum:=var_row_account.usenum;
var_money:=var_row_account.money;
end;

  异常:运行程序时出现的错误。发生异常后,语句将停止执行。预定义异常有 21 种,用户还可以自定义异常。

示例:异常处理

--异常处理格式
exception
when ...异常类型 then
...异常处理逻辑 --异常处理实例
exception
when no_data_found then
...
when too_many_rows then
...
end;

  条件判断

语法格式:

--单条件判断
if ... then
业务逻辑
end if;
--多条件判断
if ... then
业务逻辑
elsif ... then
业务逻辑
elsif ... then
业务逻辑
else
业务逻辑
end if;

  循环:无条件循环、有条件循环、for循环

示例:无条件循环

--无条件循环,语法格式:
loop
循环体
end loop;
--实例
declare
var_num number;
begin
var_num:=1;
loop--无条件循环
dbms_output.put_line(var_num);
var_num:=var_num+13;
if var_num >= 1000 then
exit;--退出循环
end if;
end loop;--循环结束
end;

示例:有条件循环

--有条件循环,语法格式:
while ...--循环条件
loop
循环体
end loop;
--实例
declare
var_num number;
begin
var_num:=1;
while var_num <= 1000--循环条件
loop
dbms_output.put_line(var_num);
var_num:=var_num+13;
end loop;--循环结束
end;

示例:for循环

begin
for var_tmp in 1 .. 1000--for循环
loop
dbms_output.put_line(v_num);
end loop;
end;

  游标:系统为用户准备的数据缓冲区,PL/SQL 中存放 SQL 语句的执行结果。 使用前,须先声明游标:cursor cur_name is SQL 语句;

示例:使用游标

--游标语法
declare
cursor cur_name is SQL 语句;
begin
open cur_name;--激活游标
loop
fetch cur_name into var_tmp;
exit when ...
end loop;
end;
--实例
declare
var_tmp t_pricetable%rowtype;
cursor cur_price is select * from t_pricetable where id > 30 and id <=73;--声明游标
begin
open cur_price;--打开游标
loop
fetch cur_price into var_tmp;--提取游标
exit when cur_price%notfound;--退出循环游标
end loop;
close cur_price;--关闭游标
end;

  游标还可以使用参数,……

示例:带参游标,从使用参数的位置看,open 理解为执行游标好像更加合理。执行结束,关闭引用即可

--使用带参游标,参数表示基本工资
--获取薪资 1800 以上,名称是 4 个字符的员工名称
declare
cursor cur_sal(var_sal emp.sal%type)--游标带有参数
is
select distinct ename
from emp
where sal > var_sal and ename like '____';
var_tmp emp.ename%type;--定义临时变量
begin
open cur_sal(1800);--打开游标 loop
fetch cur_sal into var_tmp;--提取游标
exit when cur_sal%notfound;
dbms_output.put_line(var_tmp);
end loop; close cur_sal;
end;

  for 循环处理游标,会更加简洁,打开、关闭、退出都会自动完成

示例:for 循环处理 游标(* 注意打印时调用方式)

declare
cursor cur_sal(var_sal emp.sal%type)
is
select ename--获取的是单值,与写成 * 一个效果
from emp
where sal > var_sal and ename like '____';
begin
for v_tmp in cur_sal(800)--读取的可不是单值
loop
dbms_output.put_line(v_tmp.ename);--单值输出方式也...
end loop;
end;

9.存储函数

  • 是啥:自定义函数,封装查询
  • 用途:查询
  • 使用:SQL 语句中调用
  • 格式:有返回值,必须返回
--存储函数格式
create or replace function fn_getIt(var_name var_type...)--参数有类型,无长度
return re_type--定义返回值类型,无长度
is
--声明变量
begin
--body
return ...
end;

示例:把练习的 sql 查询语句 改写成 存储函数(查询同一个入职年份全体员工的收入总和)

--scott 的 emp 表中,与某个入职时间同年份进公司的职业收入总和
--参数类型是日期型,与 入职日期 格式一致
create or replace function fn_sum(var_year emp.hiredate%type)
return emp.sal%type
is
var_result emp.sal%type;
begin
select sum(sal + nvl(comm, 0)) into var_result
from emp
where to_char(hiredate, 'yyyy') = to_char(var_year, 'yyyy');
return var_result;
end; --调用存储函数
select fn_sum(to_date('', 'yyyy-mm-dd')) from dual; --执行结果
SQL> select fn_sum(to_date('', 'yyyy-mm-dd')) from dual; FN_SUM(TO_DATE('','YYYY-MM-DD'))
----------------------------------------
25025 SQL>

示例: 把练习的 sql 查询语句 改写成 存储函数(查询某个时间之后入职的在职员工总数)

--统计某个日期时间之后入职的员工总数
--参数是字符串形式的日期类型
create or replace function fn_count(var_date varchar2)
return number
is
var_count number;
begin
select count(*) into var_count
from emp
where hiredate > to_date(var_date,'yyyy-mm-dd'); return var_count;
end; --调用存储函数
select fn_count('1981-07-01') from dual; --在 sqlplus 中截取执行结果
SQL> select fn_count('1981-07-01') from dual; FN_COUNT('1981-07-01')
----------------------
8 SQL>

  * 遗憾的是,这里的示例只能返回单值,不能返回集合。

10.存储过程

  • 是啥:对外封装函数
  • 用途:修改(uid),java 程序使用
  • 调用:call、PL/SQL 中直接调用名称、程序中调用("{call pro_name}")
  • 参数模式:in、out、in out,默认 in
  • 格式:没有返回值
--存储过程格式
create or replace procedure pro_name (var_name [参数模式] var_type...)
is|as
--声明变量
begin
--body
end;

示例:删除 scott 库部门表的部门信息,没有提交语句,在调用后查询不能立即生效。

--创建存储过程
--按照提供的部门编号,删除部门信息
create or replace procedure pro_delete(var_id in number)
is begin
delete from dept where deptno = var_id;
end; --调用存储过程
call pro_delete(40);--使用 call 调用 begin
pro_delete(20);--使用 PL-SQL 调用存储过程
end;

示例:修改 scott 库部门表的部门信息,增加提交语句

--创建存储过程     --参数 var_id:表中的现有的部门编号;    --var_name:表中新的部门名称
create or replace procedure pro_update(var_id dept.deptno%type, var_name dept.dname%type)
is
begin
update dept set dname = var_name where deptno = var_id;
commit;--须提交才能生效
end; --调用
call pro_update(40, 'zhaoccai');--调用存储过程,修改表

示例:增加 scott 库部门表的部门信息,带提交语句

--创建存储过程
create or replace procedure pro_insert(var_id dept.deptno%type,var_name dept.dname%type, var_loc dept.loc%type)
is
begin
insert into dept (deptno, dname, loc) values(var_id, var_name, var_loc);
commit;--提交生效
end; --调用存储过程
call pro_insert(30, 'tjhh', 'haqiu');--调用存储过程增加部门信息 --调用存储过程
begin
pro_insert(50,'runhe','nanjing');
end;

示例:存储过程的调用方法

--SQL 语句调用存储过程
call pro_insert(30, 'tjhh', 'haqiu');--调用存储过程增加部门信息 --PL-SQL 调用存储过程
begin
pro_insert(50,'runhe','nanjing');
end; -- Java 语言中调用
stmt_insert = conn.prepareCall("{call pro_insert(?, ?, ?)}");
stmt_delete = conn.prepareCall("{call pro_delete(?)}");
stmt_update = conn.prepareCall("{call pro_update(?, ?)}");

11.触发器

  • 用途:数据确认、安全检查、审计、数据备份……
  • 伪记录变量::new、:old
  • *注意:自动提交,无须 显示 调用 commit()
  • 格式:
    --创建触发器
    create or replace trigger tri_name
    before | after--触发时机
    [delete] [[or] insert] [[or] update [of column_name]]--监控点
    on table_name--一定是依附于某个表
    [for each row]
    [when(条件)]--触发点
    declare begin
    --body
    end;

A

上一篇:学习调用WCF服务的各种方法


下一篇:Lucene学习笔记: 五,Lucene搜索过程解析