一,安装启动登陆部分
1,数据库类型<主要>:
通用
事物处理:适用于电子交易
数据仓库:历史性数据进行优化
2,全局数据库名与SID
全局数据库一般与SID一样
3,启动必须服务:
OracleService(SID名)
Oracle(SID名)TNSListener
4,登陆SQL/PLUS,主机字符串,服务器是本机的话不用输入,否则需要配置
二,示例及常识部分
1,emp表为示例员工表
2,sql/plus中使用set linesize 200
set pagesize 200
3,dual算是名义表 如:select trunc(45.926,2) from dual;
4,ed命令:写入缓存
5,save 'd:/empsql.txt'创建文件
6,clear screen:清屏
7,connect scott/tiger连接命令
8,@ d:/empsql.txt,导入文件
9,run或者r,引用上一行命令
10,get d:/empsql.txt导入文件中命令(不执行)
11,/重复上一次执行命令
12,show user显示用户
13,set sqlprompt tom> 结果命令由sql>变为tom>
三,Oracle基本命令
1,启动:
sqlplusw username/password:本机启动
sqlplusw username/password@connect_string
2,Sqlplus基本命令
desc:显示表结构
list: 列出Sql缓冲区中一行或多行命令语句
Exit: 退出
四,Oracle数据词典,常用的队象(表等)
1,Oracle数据词典一般以user,all,dba为前缀
如:
user_tables用户所有表
user_views试图
user_constraints约束
user_dependencies表之间关系
user_tab_columns表列信息
user_tab_patitions表分区表
user_ind_patitions表分区表
user_triggers触发器
user_types:用户自定义类型
user_sequences:序列
user_sources:用户定义的子程序,类型等的源程序
user_synonyms同义词
user_sys_privs用户权限
2,名词
SGA 系统全局区<内存中>(包括数据缓存等)
3,Oracle数据文件
数据文件*.dbf
控制文件*.ctl
日志文件*.log
路径:oracle9i/oradata/oracle9i
4,数据库逻辑结构
表空间数据库〉tablespaces〉〉表s〉段s〉>数据库区间s〉块s
5,主要系统表空间:
System
Users
Temp
tools
四,SQL语言及示例
1,分类:
1,DDL
2,DML
** insert
1,适用null填充表中值
例:insert into t(id,name,zhiye)values(70,null,'laoshi')
2, 使用绑定变量
例: insert into t(id,name) values(&id,'&name');
输入id值:50
输入name值:'zhangsan'
3,select子查询
insert into a(id,name) select id,name from b where
** update
1,update tablename set column=value[,column=value,...] where
** delete
1,delete [from] tablename where
** 事务控制语句:事务是一组DML语句的逻辑组合
1,单个DDL构成事务
2,单个DCL语句构成事务
3,n个DML语句构成事务
4,事务的开始:当第一条Sql被执行时就开始了
5,事务的结束:四种情况
* commit or rollback
* DDL或DCL语句执行(自动)
* 用户退出
* 系统终止
6,事务控制----
定义事务控制点: Savepoint a
返回事务控制点: rollback to Savepoint a
**Select
1,语法: select [distinct/all] */columns 表达式 as daiti from tablename
2,使用列别名: column/表达式 as 别名
3,连接操作符: ||
4,比较
5,between and
6,in (a,b,c)
7,is [not] null
8,not and or优先级依次下降
9,日期的默认格式为'dd-month-yy'
10,'%' 任意多个 ,'_'任意一个字符
**由select 生成新表
create table aa as select * from bb;
3,DCL
2,
五,函数
1,日期:
系统时间:sysdate
插入:insert into tt (id,date) values(10,to_date('1999-02-04 10:02:01','yyyy-mm-dd hh:mi:ss'))
修改会话日期格式:alter session set nls_date_format='yyyy-mm-dd hh:mi:ss';
2,函数分类:
*单行函数
**Character(oracle中的字符串从1开始)
lower('SqDD')结果:sqdd,
upper('ddds')结果:DDDS,
initcap('mi' 'ssi')结果Mi Ssi,
concat('ff','ss')结果ffss,
substr('string',1,3)结果str注:从第1字符取道第3字符(如果第一个字符是0和1一样),
length('ss')结果2,
instr('srd','d')结果3,
lpad('sss',12,'#')结果#########sss,
**Number
round(45.926,2) 结果:45.93《四舍五入》
round(45.926,0)或者round(45.926)结果:46
round(45.926,-1)结果:50
trunc(45.926,2) 结果:45.92《截取小数》
trunc(45.926,0)或者trunc(45.926)结果:45
trunc(45.926,-1)结果:40
mod(1600,300) 结果:100《取余》
**General
**Conversion
**Date
sysdate返回系统时间
默认时间格式为dd-mon-yy
months_between('01-sep-95','11-jan-94')结果:19.25返回两个日期的月份差值
add_months('11-jan-94',6)结果:11-jul-94在日期上加上月份数
next_day('16-jul-07','friday')结果:2007-7-20(注: 今天是星期一,到星期五,显示星期五的日期 )指定日期的后一天
last_day('16-jul-07')结果:2007-7-31月份中的最后一天
round()结果:四舍五入日期:注试验没成功
trunc()结果:截断日期 注试验没成功
**隐式类型转换
1,varchar2 or char --->number
2,varchar2 or char --->date
3,number----->varchar2
4,date------>varchar2
**显式类型转换
1,varchar2 or char --->number to_number
2,varchar2 or char --->date to_date('1988-10-10','yyyy-mm-dd')
3,number----->varchar2 to_char(id)
4,date------>varchar2 to_char(sysdate,'日期格式')
5,NVL函数,将null值转换为替代的值:varchar2,date,number都可以
如:nvl(id,0)
6,decode(column/expression,)像switch-case结构
select job,sal,decode(job,'ANALYST',sal*2,
'CLERK',sal*3,
'MANAGER',sal*4,
sal)
from emp;
*多行函数
七,锁及数据并行访问
1,锁的类型
**表级锁
1,保护表的数据
2,在多个用户同时访问数据时确保数据的完整性
3,可以设置三种模式:共享,共享更新和排他
******语法
Lock table <table_name> in <lock_mode>
share mode:特点:仅允许其他用户执行select操作
多个用户可以对同一表中放置此锁
share update mode 特点:锁定被更新的行
允许其他用户同时,查询插入更新未被锁定的行
select for update 可以强制使用
允许不同用户锁定表的不同行
exclusive mode(排他锁)特点:
限制性最强
仅允许其他用户查询
同一时间只允许一位用户在表上放置排他锁
nowait作用:请求的资源被锁定则不等待,立即抱错
lock table test in exclusive mode nowait
**行级锁
1,行被锁定,在释放前其它用户不能更改,使用commit or rollback释放锁
2,获取行级锁
方法一,insert,update语句
方法二,select ...for update:可以在一行或多行设置,可以执行除update之外
的其它操作
for update wait 10(时间)子句
六,PL/SQL
语法结构:声明
执行语句
异常处理部分
格式:declare
emp number;
name varchar2;
begin
语句……;
语句……;
exception
语句……
end
变量:数据的临时存储
变量的赋值:1,赋值符号,2用select 语句
类型: 类型还有更细的划分,如number还有很多子类型
标量:容纳单值,没有内部组成,分为4类number,varchar,date,boolean
复合:如可变数组,RECORD varray,nested table
引用:ref操作符,ref cursor
LOB: bolb 二进制大型对象,clob,字符大型队形
nclob,国际字符大型对象,bfile,指向外部文件
注释:命令set serveroutput on 可以使服务器上的信息回显到sql plus
在sqlplus中输出用 DBMS_Output.put_line(varchar v);
变量赋值
赋值符号为":="可以在定义变量时直接初始化如:declare eno varchar(13):='sdfsf';
使用默认default关键字如:isExsit boolean default false;
使用常量constant关键字如:name constant varchar(34):='mike';
注释:常量必须在声明时赋值
用数据库数据赋值:
上面的赋值属于赋静态值
用数据库赋值用select 字段名 into 变量 from 表 来赋值,注意如果变量是单值,只能用where 来限制查询出来的是一条记录
代码注释:
单行注释:用"--"
多行注释:用/* */
属性:
引用数据库中的数据类型和对象
PL/SQL变量和常量可以具有属性
属性的类型:
%type 引用数据库列 举例:declare eno emp.empno%type;注释:表名.字段名%type
%rowtype 代表表中的行 举例:declare emprow emp%rowtype 在执行部分用select * into emprow from emp where empno='7710';然后就可以引用行级属性的属性了,如:emprow.empno
注意,在定义的时候必须是 表名%rowtype 在执行部分,必须是select *
逻辑比较:
注意:一个=号表示等于
控制流语句:
条件控制
if then
if then else :if 没有括号的条件表达式 then 语句 else 语句 endif; endif 后的必须有;
if then elsif then endif;
case
迭代控制
简单循环
loop
icount:=icount+1;
exit when icount>100;--exit when必须有退出条件
isum:=isum+icount;
end loop
while循环
while icount<100 loop
icount:=icount+1;
isum:=isum+icount;
end loop
for循环当标志符是一个连续的整形
for i in 1..100 loop--i为隐式定义一个整数值,当然在游标时,可以为行级变量
isum:=isum+i
end loop
顺序控制
goto 可以定义标签,无条件跳转
null 空语句,可以代替某些地方暂时没有写语句,而以后可能要写,先用null替换
异常处理:
异常类型:
预定义的:违反oracle 规则将隐式引发它
用户定义的:可以由raise语句显式引发
编码错误,被称为语法错误,编译器会停止编译让我们来修改
在程序运行期出现的条件不满足,条件超出了预显,出现的错误,我们称为异常
异常处理涉及到的步骤:
声明异常:
引发异常:
处理异常:
异常类型:
预定义:由oracle 为常见错误预定义,在DBMS_STANDARD程序报中提供了这些定义
非预定义:oracle没有定义的,指定
用户定义:
声明异常:
declare
Dup_Value Exception;--声明异常Dup_Value
icount int:=0;
begin
select count(*) into icount from place where placeid=1;
if icount>0 then
raise Dup_Value;--抛出异常或者说引发异常
end if;
Exception
when Dup_Value then--处理用户自定义异常
DBMS_Output.putline('记录已经存在');--字符串必须用单引号'
others关键字:其他所有异常when others then放在最后
预条件编译:关键指令 pragma Exception_init(自定义异常,-1);其中-1为编号--编译指令
什么叫预条件编译当出现系统预定义异常时,错误信息不好理解,可以让出现此类异常时用自己
定义的异常来完成,如:当违反系统主键唯一性这种异常
如:
declare
Dup_Value Exception;--声明异常Dup_Value
pragma Exception_init(Dup_Value,-1);--覆盖系统指令
begin
insert into table1 values(12,'sfsdf');--不用用raise手工抛出异常或者说引发异常
Exception
when Dup_Value then--处理用户自定义异常
DBMS_Output.putline('fsdfs');--字符串必须用单引号'
一般实例:
Exception
when NO_Data_Found then--没有记录
语句;
when Too_Many_rows then--不止一行
语句;
when Dup_Val_On_Index then--唯一约束被破坏
语句;
when others then
语句;
自定义异常中 Raise_Application_Error方法的用法:可以显示给客户端,其它用户都可以看到,如果上例的用法则只能在pl/sql块中看到 (以交互方式传达预定义的异常)
既可以在执行块使用,也可以在异常块使用
错误编号必须在-20000到-20999之间
错误消息的长度可长达2048个字节
如上例中when Dup_Value then
Raise_Application_Error(-20001,'表中已经有这条记录了');
7 游标 cursor:指向上下文区域的句柄或指针,他是在服务器上存储的,我们用游标实际上是使用服务器的资源(所以要考虑性能)
上下文区域-用于sql 处理的内存区
上下文区域的内容
语句处理的行数
指向语句的语法分析表示的指针
使用游标的好处: 1减少了网络的数据流量
2可以实现遍历(如对一个结果集的逐行检索)
3使用游标可以直接更新表中的行(可以直接引用行)
游标类型: 静态游标的名字不能当作参数传递,引用游标则可以
静态游标: 由用户定义,经过定义,打开,关闭就结术了
特点:对应的结果集是固定的
隐式游标:服务器自动管理,(自动开启,sql 语句执行后就自动关闭)如执行,插,删,改
用于处理:
DML语句,
返回单行查询
显式游标:由用户显示声明
游标将指向活动集中的当前行
控制显式游标
Open: 不打开则无法读取
Fetch
Close:不关闭,则内存中将始终保留
声明:declare cursor cursor_name is select * from emp
游标只是个标示,不能给其赋值,提取的结果集应该在游标区域内
举例:
declare
--在open cursor之前,只是分配了一个内存区域来存储游标内容,而没有 结果集
cursor cursor_name is select * from emp;--游标不是数据类型所以不用后置修饰
emprow emp%rowtype;
begin
--激活后会分配一个游标区域,并执行查询,返回结果集,然后并有一个 指针指向第一条记录
open cursor_name;--打开游标
loop--循环
fetch cursor_name into emprow;--提取游标指示的数据
DBMS_Output.put_line('employee no:'||emprow.empno);
--%rowcount 表示提出了多少行,从一开始
DBMS_Output.put_line('提取了'||cursor_name%rowcount||'行');
exit when cursor_name%notfound;
end loop
close cursor_name;--关闭游标
end
改为while循环,必须先提取一次
declare
cursor cursor_naem is select * from emp;
emprow emp%rowtype;
open cursor_name;--打开游标
fetch cursor_name into emprow;--提取游标指示的数据
while cursor_name%found loop
DBMS_Output.put_line('employee no:'||emprow.empno);
--%rowcount 表示提出了多少行,从一开始
DBMS_Output.put_line('提取了'||cursor_name%rowcount||'行');
fetch cursor_name into emprow;
end loop
close cursor_name;--关闭游标
end
改为for循环,比较经典,自动打开游标,自动提取指示数据,自动关闭游标
declare
cursor cursor_name is select * from emp;
begin
for emprow(隐式声明) in cursor_name loop--被自动打开,并自动的提 取数据给行级变量
end
for循环的缺点,就是必须把数据全部提出,不像其它,可以由条件限制
REF游标(引用游标,也可以叫做动态游标)
在运行时使不同的语句与之关联
ref游标使用游标变量
游标变量:
一种引用类型
可以在运行时指向不同的存储位置
close语句关闭游标并释放用于查询的资源
游标变量的类型:
具有约束的游标变量
具有返回类型的游标变量
也成为‘强游标’
无约束的游标变量
没有返回类型
也成为‘弱游标’
声明:用type来生成引用游标
declare
--就像是一种类型,不过有效区域就在pl/sql块中
type refcursor_name is ref cursor;--弱游标
--type refcursor_name is ref cursor return emp%rowtype;--强游标
empcur refcursor;--定义游标变量
open empcur for select * from emp;--重点记忆
/*因为for 循环会自动打开游标,所以在引用游标中不能使用*/
游标的属性:
%NOTFOUND--返回一个boolean型
%FOUND--返回一个boolean型
%ROWCOUNT
%ISOPEN--返回一个boolean型:隐式游标永远为false
举例:
begin
insert into place values(2,'beijing');
DBMS_Output.putline('游标影响的行数'||SQL%rowcount);--所有游标的统称为SQL (游标的名字)
end
注释:命令save fdfd.txt可以将sqlplus中的记录到txt文件
使用绑定变量来实现交互性:(仅限于sqlplus中使用)
用法:&变量名 --整形
&'变量名' --字符等
如在declare中使用,当然也可以在执行块中使用(赋值符号后用)
declare cursor empcur is select * from emp where sal>&inputSal;
游标管理:游标的限制
1,不能再程序包中声明游标变量
2,远程子程序不能接受游标变量的值
3,不能使用比较操作符对游标变量进行相等或不相等测试--因为指向不同的区域
4,不能将空值赋予游标变量
5,表不能存储游标变量的值
8 子程序:
命名的pl/sql 块
与之前讲的不同declare,执行部分块必须有
优点:
1,将程序分解多个逻辑模块存储在后台数据库中,我们可以将这些块组合在一起,构成复杂的功能
2,可重用型
3,可维护性
类型:
1,过程:存储过程,用于执行某一操作
2,函数:用于执行某项操作并返回值
过程格式:
语法:
create or replace procedure <proc_name>
[(参数 列表 in|out|in out 类型,……)]
is|as--两个都一样,代替了declare 过程中不允许存在declare
<local declarations>--内部变量,存储过程内部使用
begin
语句
[exception]
语句
end
参数模式:
in: 接受值(默认模式)
out:返回给调用子程序
in out:既可以做输入值,也可以做返回值
过程举例1:打印乘法小九九
--创建过程
create or replace procedure xiaojiujiu as
i integer;
j integer;
begin
DBMS_OUTPUT.putline('打印乘法小九九');
for i in 1..9 loop
for j in 1..9 loop
if i>=j then
dbms_output.put(to_char(j)||'*'||to_char(i)
||'='||to_char(i*j)||' ');
end if;
end loop;
dbms_output.putline('');
end loop;
end
--调用过程
方法一:execute关键字
set severoutput on;--想要显示
execute xiaojiujiu--存储过程名;
方法二:匿名的pl/sql块中,如:
begin
xiaojiujiu;
end;
过程举例2:带参数的存储过程
--删除
drop procedure xiaojiujiu;
函数:
语法格式比过程多了一个返回值
create or replace function function_name (参数列表) return 返回的数据类型 is|as
访问:
使用pl/sql;
在sql 语句中使用;
--一般仅接受IN参数
函数举例:
create or replace function getname(sno varchar2) return varchar is
name varchar(12);
begin
select ename into name from emp;
wehre empno=sno;
return name;--返回值
end;
注释:数据字典:user_sourse据对象中存储的对对象名为大写
函数与过程的区别:
过程 函数
作为pl/sql部分使用 作为表达式的一部分使用
不包含return 必须包含
可以返回任何值 必须返回单值
可以包含return,但是不能 必须包含至少一条return
用于返回值
oracle 与sqlserver的存储过程的区别:
1,oracle 不能使用select 来显示结果集
注释:显示编译错误,show errors;
自主事务处理:
问题:存储过程P1 中调用p2 ,p2中的事务可能影响到
p1的事务,
方法:在主事务中的as 与 begin中使用
pragma AUTONOMOUS_TRANSACTION;
函数/过程的纯度级别:
定义由函数读取或修改的数据种类
级别:
WNDS--不写入数据库状态
RNDS--不读取数据库状态
WNPS--不写入程序包状态
RNPS--不读取程序包状态
程序包:
相关对象的封装
程序包的各部分
程序包的规格说明:声明子程序
--使用create package命令进行创建
--包含公用对象和类型
--声明类型,常量,变量,异常,游标和子程序
--可以在没有程序包主体的情况下存在
程序包的主体:定义子程序
--create package body命令进行创建
--包含子程序和游标的定义
--包含私有声明
--不能在没有程序报规格说明的情况下存在
程序包的规格说明语法:
create or replace package package_name is|as
变量声明|类型定义|异常声明|游标声明|函数说明|过程说明
pragma restrict_references(函数名/过程,函数的纯度级别)
end package_name;
程序包的主体语法:
create or replace package body package_name is|as
包体变 量声明|类型定义|异常声明|游标声明|函数定义|过程定义
调用
package_name.类型/函数/过程
删除
drop package package_name;
drop package body package_name;
注释:包的数据字典查询 user_objects,user_source
读取引用游标所指示的
set autoprint on
variable tempcur refcursor;--定义变量,这种方式的变量只能在sqlplus中使用
exec package_name.returnstudent(: tempcur);--returnstudent 是一个方法
重载:
--程序包中的多个子程序可以具有相同的名称
--它们的形参是不同的
--只能位于大包的子程序中
限制
--如果子程序的参数仅名字或模式不同,不能重载
--不能基于返回值来重载(与java不同)
8 触发器:
--是特殊的pl/sql块或存储过程
--是在对关联表执行DML操作时触发器(称为DML触发器三类,插入,更新,删除)
--由数据库服务器自动执行
--还可能有声明部分和异常处理部分
/***********
触发器的组成部份
--触发器语句:制定触发器定时,事件,表名及类型
--触发器的主体:是pl/sql块或对过程的调用
--触发器的限制条件:可以通过when自句实现
触发器的类型
--应用程序触发器
--数据库触发器
DML触发器组件
--触发器定时:比如插入,是插入之前(前置触发器),还是插入以后(后置触发器)
--触发器事件:如插入
--表名
--触发器类型:insert delete update
--when 子句
--触发器的主体
**********/
触发器:
1触发器具有三个部分:
触发事件
可选的触发器约束条件
触发器动作
2,可以创建触发器对应如下语句所触发的触发器
DML语句(Insert Delete Update)
DDL语句(Create Alter Drop)
数据库操作(ServerError Logon LogOff Startup Stutdown)
3,可创建触发器的对象:
数据库表
数据库视图
用户模式
数据库实例
4输发器类型
DML数据库
系统触发器
替代触发器 instead of(在视图上创建触发器)替代 before|after
如果 是instead of insert on view_name
referencing new N
理解:当你向view_name 中插入时,主体部分将替代insert语句。
主体部分向视图的基表进行插入;
5执行DML语句的顺序
执行before语句级触发器(如果有)
对于受语句影响的每一行,执行DML语句
执行after语句级触发器如果有)
6两个特殊值:
New,Old是由触发器维护的行级变量(全局变量,在主体中引用时加:)
但是注意在when 条件表达式中不能用:来引用
必须是行级触发器
7触发器谓词:在混和触发器中使用(所谓混合触发器及如下:before insert or update or delete)
Inserting--可以在主体中使用
Updating
Deleting
举例:日至记录
create or replace trigger trigger_name
before insert or update or delete on table_name
for each row
begin
if inserting then
insert into studentlog values(:new.stuID,:new.stuname,:new.sex,'I')
end if;
if deleting then
insert into studentlog values(:Old.stuID,:Old.stuname,:Old.sex,'D')
end;
创建触发器:
Create or replace Trigger [模式(用户名)]触发器名
before|after--前置(before)或后置(after)
inert|delete|update
on 表名
[for each row]--有的是行级触发器,没有就是表级触发器(表中触发一次)
when 条件表达式
pl/sql块
举例 :
create or replace trigger tg_insert
before insert on student
for each row
begin
DBMS_output.putline('insert student');
end
注释: :变量名--全局变量,全局变量不是由用户的程序定义的,它们是在服务器级定应义的
触发器中尽量不要使用cursor,long ,lob
替代触发器的意义
变异表: 特点:不能进行修改,统计等
当前正由DML语句的修改
声明删除级联(引用完整性约束条件)的影响
举例:
create or replace trigger trigger_name
after delete on emp_t--这里是用的after,在删除后才执行触发器
for each row
declare n integer;
begin
select count(*) into n from emp_t;
DBMS_output.putline(''||n);
end;
约束表:
对于sql 语句,除发器语句直接读取
对于声明的引用完整性约束条件,间接读取
表的变异或约束只是对会话而言的
触发器的维护
删除 drop trigger
修改
修改可用状态 alter trigger trigger_name disable/enable;
触发器的数据字典:
users_triggers;
all_triggers;
dba_triggers;后两个以dba身份登录
内置程序包:
扩展数据库的功能
为pl/sql提供对sql功能的访问
用户sys拥有所有程序包
用户必须具有execute权限才能访问内置程序包
DBMS_OUTPUT--sqlplus中显示数据
enable
disable
put--向缓存区写数据
put_line--向缓存区写数据并显示这一行
new_line缓存区开辟一个新行
get_line从缓存区读取数据
get_lines从缓存区读取数据
DBMS_LOB---对大型对象的操作
read( c clob,读取长度 integer,读取开始位置integer,放入变量 varchar)
--注意英文或汉字的个数是一样的,里面存储的是unicode码
write(c clob,读取长度 integer,读取开始位置 integer, 新值 varchar)
append
compare
copy
erase
fileclose
fileexists
filegetname
getlength(c clob)返回整性长度
举例:
create table downfilelist
(
id varchar(20) not null primary key,
name varchar(43) not null,
filelocation bfile,--文件存放位置
description clob --文件描述,最大2GB
)
---创建目录,需要在数据库中有一个目录指向操作系统的路径
create or replace directory filedir as 'd:/downlist'---filedir代替这个路径
---插入
insert into downfilelist values('10001','oracle 编程',bfilename(upper ('filedir'),'java.zip'),'这是一本好书');
--select
filelocation bfile,存的是路径是二进制的,在sqlplus中不能显示
--修改,用pl/sql
修改大型对象时比较慢,所以,用for update加锁,并且不要忘记用commit提交修改以便
解除行级锁
利用writer函数