??xml version="1.0" encoding="utf-8" standalone="yes"?>
DDL 数据定义语言 - 建立数据库对?
create /alter/ drop/ truncate ……table table_name.
DML 数据操纵语言 - 数据的查看和l护
select / insert /delete /update
TCL 事务控制语言 - 数据是否保存到数据库?
commit / rollback / savepoint
DCL 数据控制语言 -- 查看对象的权?
grant / revoke
数据库设?
关系数据模型的组?
一张或多张?
表的索引
视图
触发?
表与表的关系
数据库Schema
概念上的 Q?一lDDL
物理上的 Q?一个命名空_包含了表Q过E,视图的集?
常用命o
connect 用户?密码 q接到指定用?
desc tab_name 察看表tab_name的结?
quit/exit 退?
clear screen 清除屏幕
set linesize 200 讄一行显C?00个字W?
set pagesize 20 讄每页昄20?
dbms_output.put_line() 打印,cM于System.out.println();
set serveroutput on 打开服务器输出,否则上面打印语句报错
edit ~辑~存中的语句
/ 执行上一ơ语句块/可重复执?
@ sqlpath 执行某sql文g
@@ sqlfile 执行sqlpath环境变量中的文g
spool file 打印日志到文本文?
spool off 停止打印
# 在输入sql语句的过E中临时先运行一个sql*plus命o
--查看大字短的大小
SELECT DBMS_LOB.GETLENGTH(MYCLOB) FROM ATTACHMENT; //MYCLOB是列?ATTACHMENT 是表?
SELECT DBMS_LOB.GETLENGTH(MYBLOB) FROM ATTACHMENT;
常用?
user_constraints 用户U束
user_tables 用户?
all_all_tables 所有用戯
all_constraints 所有约?
user_cons_columns U束?
all_cons_columns 所有约束列
nls_session_parameters 当前会话信息
v$nls_parameters pȝ参数
数据cd
字符?
char 最?000个字?定长
varchar2最?000个字?变长
数字cd
number 10?38ơ方 ?0?8ơ方 可以表示数 也可以表C整?
日期
date 包含q月日和时分U?7个字?
大对?
clob 字符型大对象 >4000字节 最?G
blob 二进制大对象 囑փ/声音 4G
伪类?
%type 可以引用某列的类?
%rowtype 可以引用某表Q作为类?
rownum l果集每行的行号
表操作基
创徏?
create table tab_name
(
column_name data_type ,
column_name data_type ,
column_name data_type ,
……..
)
修改?
插入?
alter table tab_name add(column_name data_type)
修改?
alter table tab_name modify(column_name data_type)
删除?
alter table tab_name drop column column_name;
表重命名
rename tab_name to change_name
删除?
drop table tab_name删除记录和结?不可恢复
d数据
insert into tab_name[(column_name , column_name…)] values(value,value…)
序列 sequence <仅oracle中有>
创徏序列
create sequence 自定义序列名?
获得下一个?
seq_name.nextval
获得当前?
seq_name.currval
复杂序列 序列的nextval是不可逆的
create sequence 自定义序列名?
increment by 5 <--递增5-->
start with 0 <--?开?->
maxvalue 100 <--最大?也可以用nomaxvalue-->
minvalue -100 <--最?也可以用nominvalue-->
cycle <--循环增长 也可以用nocycle-->
cache 30 <--~存 也可以用nocache-->
修改数据
update tab_name set expression
删除数据
delete tab_name 删除记录Q不删除l构Q可以恢??
delete tab_name where expression 条g删除 ?
truncate table tab_name 仅清除数据,保留l构Q不可恢?
U束
主键U束 用来唯一表示一条数据的字段Q其g能重复,不能为null
create table test
(
nationality varchar2(20),
city varchar(20),
constraint nick_pk primary key(nationality,city)
);
外键U束 引用其他表的主键到本?在本表中叫外键,用来做表关系
create table test
(
nationality varchar2(20),
city varchar(20),
constraint nick_fk foreign key(nationality) references
tab_name(nationality)
);
<** create table test1
(
id varchar2(20),
name varchar(20),
tid varchar(20),
primary key(id),
constraint test1 foreign key(tid) references
test2(tid)
);
"constraint test1:外键兌?
create table test2
(
tid varchar2(20),
descp varchar(20),
primary key(tid)
); **>
非空U束
create table test
(
nationality varchar2(20) not null,
);
唯一U束
create table test
(
nationality varchar2(20) ,
constraint nick_uk unique(nationality)
);
查约?
create table test1
(
nationality varchar2(20) ,
constraint nick_ck check(nationality <> '国')
);
默认?
default
讑֮U束条g无效
disable|enable constraint_name
U联删除<U联更新要用触发器>
references … ON DELETE CASCADE
q算W?
< 于
<= 于{于
> 大于
>= 大于{于
= {于
!= 不等?
<> 不等?
:= 赋?
is null 如果操作Cؓnullq回true
like 比较字符?_代表一个字W?%代表多个字符
create table test
(
a number
)
insert into test value(10);
insert into test value(20);
insert into test value(30);
between 验证值是否在范围之内
select * from test where a between 10 and 20;
in 验证操作书在讑֮的一pdg
select * from test where a in(1,10,20,30);
all 表示子查询返回g的所有?相当于比较最大?
select sal from emp where sal > all( select sal from emp where sal<2000);
any 表示子查询返回g的Q意|相当于最?
and 两个条g都满?
or 只满一?
not 取反
+ ?
- ?
* ?
/ ?
基础查询
<--基本的select语句-->
select 列名,列名,.. from 表名,表名,.. where 条g group by 列名 having 条g
select 是必ȝ Q后面添你要查询的列?Q? 代表所?
from 是必ȝ Q?后面填写你要查询的表名,可以有多?
where 可选的Q后面填写你的查询条?
group by 可选的Q对聚合q行分组Q当查询内容多于一列且包含聚合函数时?
having 仅用于group by 的关键字Q和where作用一?
查询最大?
select * from product where price not in (select p.price from product p, product d
where p.price<d.price)
<--消除相同的行-->
select distinct 列名,列名,..from 表名
<--排序 order by-->
select 列名,列名,.. from 表名 order by 要排序的列名
<--注意Qorder by指o需聚合函数配合使用Q否则只能是单列-->
<--聚合函数-->
avg q_?
select avg(emp.sal) from emp;
sum 求和
select sum(emp.sal) from emp;
max 最大?
select max(emp.sal) from emp;
min 最?
select min(emp.sal) from emp;
count L
select count(emp.sal) from emp;
<--排序-->
升序
select * from emp order by emp.sal ;
降序
select * from emp order by emp.sal desc;
<--数据复制-->
select * into myemp from emp;
<--表复?->
create table myemp as select * from emp;
create view bb as select ………
<--技?->
哑元?在没有查询表的情况下使用
select 1+1 from dual
查询分割 ||
select a.a1 ||'----'|| a.a2 from a;
查询行数限制
select * from a where rownum<=2;
查询表结?
desc tab_name
数据复制
select tab_name into tab_name|var from tab_name
--索订单总额最大的用户
select * from users where id =
(
select userid from
(
select userid, sum(price*quantity) as total
from orders group by userid order by total desc
)
where rownum=1
);
mysql:技?可将文g的内Ҏ入到表中.
load data local infile 'd:/sql.txt' into table product;
高查询
W卡乘U?
select dname,ename from emp,dept; q种通过多张表简单对加是没有太大意义?
集合q算
交集 用来得到两个或者多个不同集合的共同元素,两个集合的交集就是其中所有属性相{的元素.交集有一个严格的限制Q每个结果集中所有列都必d配相{?
减集 用来查找在一个集合中出现q,而在另一个集合中没有出现的元?与交集相反的? 每个l果集中所有列都必d配不相等
q 用来合ƈ两个或者多个类似的集合
交集 intersect
select语句 intersect select语句
减集 minus
select语句 minus select语句
q union or union all
select语句 union select语句
内连?
在连接条件中使用{于?=)q算W比较被q接列的列|其查询结果中列出被连接表中的所有列Q包括其中的重复列?
select dname,ename from dept,emp where dept.deptno = emp.deptno
外连?
条g列?+)Q则此列为外q列Q主列信息全部显C,外连列没有则昄I?
多行子查?
q回多个行,必须包含一个多行运符?
视图
视图语法
创徏视图: create [or replace] view <名字> as <select 语句>
视图用于化查询,视图中实际存攄是一个查询语句而已Q返回的是结果集
在视图中可以修改数据Q但? 建立视图的查询语句必L一个简单的select(只查询一个表,q且不含有分l函?
查看视图: select * from 视图?
E序?
在这之前Q我们所有的sql语句都是一句一句执行的Q如果我们把很多事情看作一个整体提交执行的话,必须使用E序块?
声明部分Q声名变量及初始?
关键字:declare
执行部分Q存放所有可执行的代码,q些代码包含在begin/end?
关键字:begin end
每个指ol束?表示Q?-表示注释
--q是一个示?
declare
i number:=5; y number:=6;
begin
i:=i+y;
dbms_output.put_line(i);
end;
/
程控制
--条gif......then...elseif.. .end if;
declare
i number:=50;
begin
if i=50
then dbms_output.put_line(i);
elsif i<50
then dbms_output.put_line(0);
end if;
end;
/
-----使用loop循环(exit when 退出条?
declare
i number;
begin
i:=0;
loop
exit when i=10;
dbms_output.put_line(i);
i:=i+1;
end loop;
end;
-----使用while-loop循环
declare
i number;
begin
i:=0;
while i<10
loop
dbms_output.put_line(i);
i:=i+1;
end loop;
end;
/
-----使用for-loop循环
begin
for i in 1..10
loop
dbms_output.put_line(i);
end loop;
end;
/
-----使用for-loop反序循环
begin
for i in REVERSE 1..10
loop
dbms_output.put_line(i);
end loop;
end;
事务处理
隔离U别 脏读 不可重复?虚读
L提交
Read uncommitted 可以 可以 可以
d提交
Read committed 不可?可以 可以
可重复读
Repeatable read 不可?不可?可以
可串行化
Serializable 不可?不可?不可?
脏读是指当一个事务正在访问数据,q且Ҏ据进行了修改Q而这U修改还没有提交到数据库中,q时Q另外一个事务也讉Kq个数据Q然后用了q个数据?
例如Q你银行?000块,你取?00Q但没最l提交,你老婆q时通过ATM查帐Q你攑ּ了取ƾ,q时帐户应该q有1000Q但是你老婆看到的是500Q于是你老婆提交了,l果你损׃500
Ps: 用线E方式理?-----L据不加锁
不可重复L指当事务两次d同一行数据,但每ơ得到的数据都不一hQ就会发生这U事件?
例如Q你用网l察看你银行帐户Q你老婆q时用ATM察看Q这时你取出?00Q你老婆准备?000块发C够了…..
Ps: 用线E方式理?-----M前加锁,dN
脏读和不可重复读的区别是Q一个未提交dQ一个以提交d
虚读是指一个事物查询两ơ,另一个事物在q两ơ之间插入了数据Q导致两ơ查询的l果不同
Ps: 用线E方式理?-----M前加锁,d不放锁,直到commit或rollback才放?
串行?----完全安全的数据访问模?
Ps: 用线E方式理?-----M前加条g锁,d不放锁,直到commit或rollback才放?
commit 提交上一个事物,开始下一个事?
savepoint var 保存?
rollback 回滚C务开始处Q或某保存处
存储q程
语法格式
create or replace procedure q程?参数 参数讄 参数cd) is
声明语句D?
begin
执行语句D?
exception
异常处理语句D?
end;
参数讄
in参数Q读入参敎ͼȝ序向q程传递参数倹{?
out参数Q读出参敎ͼq程向主E序传递参数倹{?
in out 参数Q双向参敎ͼq程与主E序双向交流数据?
调用存储q程Ҏ
无返回参?execute q程?参数);
有返回参数的要在另一个过E中调用q赋?
例子:
--赋D?lt; := >
create or replace procedure pro4(w in integer,h in integer)
as
width integer :=w;
hight integer :=h;
area real;
begin
area :=(width+hight)*2;
dbms_output.put_line('area=' || area);
end;
/
--条g语句<if .. then ... end if>
create or replace procedure myro5(num in integer) as
n integer :=num;
begin
if n=5 then
dbms_output.put_line('ok');
else
dbms_output.put_line('not equals');
end if;
end;
/
--循环<while ** loop *** end loop; for * in ***loop end loop;>
create or replace procedure mypro6(n in integer) as
con integer :=0;
begin
dbms_output.put_line('while loop.=========');
while con<n loop
dbms_output.put_line(con);
con :=con+1;
end loop;
dbms_output.put_line('for loop ==========');
con :=0;
for con in 1..n loop
for con in n..1 loop
dbms_output.put_line('*');
end loop;
end loop;
end;
/
--使SQLPLUS控制台可以输?
set serveroutput on
set serveroutput off
--控制台输?
declare
begin
dbms_output.put_line('this is ');
end;
/
declare
aaa varchar2(100);
begin
dbms_output.put_line((2+3)*6);
end;
/
异常处理
自定义异常处?
1. 定义异常处理
定义异常处理的语法如下:
declare
异常?exception;
begin
2. 触发异常处理
触发异常处理的语法如下:
raise 异常?
3. 处理异常
触发异常处理后,可以定义异常处理部分Q语法如下:
Exception
When 异常? then
异常处理语句D?;
When 异常? then
异常处理语句D?;
end;
技?
raise_application_error(错误代码,错误原因) 函数可以直接抛异?
其中错误代码?20000?20999之间Q错误原因ؓ2000个以内的字符
触发?
触发器相当于java中的事g监听Q当某事件发生时Ȁzȝ定的事gq执行相应的逻辑
DML触发器中包含了三U事?insert update delete
语法格式
create [or replace] trigger 触发器名
{before| after | instead of} {insert|delete|update}
on 表名
[for each row]
when 条g
begin
end;
before 在事件开始前执行begin/end
一般应用场?
1 判断触发事g(一般是一个DML 语句)是否应该被执?
2 在触发事件之前计一个列的?
after 在事件开始后执行begin/end
一般应用场?
1 完成触发事g
for each row 表示每操作一ơ都触发Q称作行U,不写表示无论操作多少行,只触发一ơ,UC表
when(条g) 必须是行U?
技巧:
触发器中可以使用三个条g?Inserting,deleting,updating
触发器中可以使用两个变量 :old | :new 分别表示旧有的值和新|必须是行U?在过E中?)
instead of 替代触发? 只能作用在视图上Q用于替代DML语句 Q行U,不可与when同用
两个d:
W一?
创徏一张表 create table test(aa number primary key);
执行10?insert into test values(L整数) ; 语句
查询此表Q结果ؓ 1 2 3 4 5 6 7 8 9 10
W二?
创徏一触发器保证每周的周六周日Q以及每天早八点前和晚六点后不允许对emp表进行Q何的DMLQinsert,delete,updateQ操作?
W三?
实现emp表中的外键deptid的联更新功?
游标
游标是从数据表中提取出来的数据,以时表的Ş式存攑֜内存中,在游标中有一个数据指针,在初始状态下指向的是首记录,利用fetch语句可以Ud该指针,从而对游标中的数据q行各种操作Q然后将操作l果写回数据表中?
首先我们先看看emp?select * from scott.emp ;
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
------ ---------- --------- ---------- ---------- ---------- ---------- ----------
7369 SMITH CLERK 7902 1980-12-17 800 20
7499 ALLEN SALESMAN 7698 1981-02-20 1600 300 30
我想查找sal<1000得数?
select * from scott.emp where sal <1000
q回若干行,q回的若q行事实上是一个时表。游标的作用是对q个临时表进行逐行处理
游标通常用于在存储过E及客户端开发中
游标程
声明游标QCURSOR cursor_name IS select_statement
为查询打开游标QOPEN cursor_name
取得l果攑օPL/SQL变量中;
FETCH cursor_name INTO list_of_variables;
FETCH cursor_name INTO PL/SQL_record;
关闭游标QCLOSE cursor_name
游标的属?
mycursor%isopen --是否打开
mycursor%found --fetch有数?
mycursor%notfound –fetch没有数据
mycursor%rowcount --q回游标的行?若返回gؓ0Q没有提取出数据?
--最基本的游?
declare
cursor mycursor is select * from scott.emp where sal > 1000 ;
temp mycursor%rowtype ;
begin
open mycursor ;
fetch mycursor into temp ;
dbms_output.put_line(temp.sal);
close mycursor;
end;
/
--游标的滚?
declare
num number;
i emp%rowtype;
--定义游标
cursor mycursor is
select * from emp;
begin
select count(*) into num from emp;
if num>0 then
open mycursor; --打开游标
loop
fetch mycursor into i; --d游标中的值到变量?
exit when mycursor%notfound; --没有取到记录Ӟ退出@?
dbms_output.put_line(i.sal);
end loop;
close mycursor; --关闭游标
else
dbms_output.put_line('emp=0');
end if;
end;
日期函数
函数? to_date(string)
含义: 字符串{日期
CZ: select to_date('2002-1-1'Q?yyyy-MM-dd') from dual;
l果: 2002-1-1
函数? add_months(date,month)
含义: 增加或减月?
CZ: select add_months(sysdate,1) from dual ;
l果: xxxx-xx-xx
函数?sysdate
含义:当前日期Q可直接加减天数
CZ:select sysdate+1 from dual
l果:当前日期+1?
函数? extract(year|month|day from dateType)
含义:截取日期
CZ: select extract(year from sysdate)"This year" from dual;
l果: 2007
问题Q获取几个月以后的年?
函数? last_day(dateType)
含义: 最后一?
CZ: select last_day(sysdate) from dual ;
l果: xxxx-xx-xx
函数? months_between(dateType,dateType)
含义: q回两个日期间的月䆾
CZ: select months_between('2002-1-1','2003-1-1') from dual
l果: -12
函数? to_char(dateType,yyyy|dd|mm|hh{12|24}|mi|ss|day|ww|dy)
含义: 把日期{换ؓ字符?
CZ: select to_char(sysdate,'yyyy-mm-dd-hh24:mi:ss') from dual;
l果: xxxxxxxx
问题: 两个日期间共有几星期
字符串函?
函数? ASCII(char)
含义: q回与指定的字符对应的十q制?
CZ: select ascii('?) from dual;
l果: 50127
函数? CHR(int)
含义: l出整数,q回对应的字W?
CZ: select chr(50127) from dual;
l果: ?
函数? CONCAT(string,string)
含义: q接两个字符?
CZ: select concat('我是','孟庆?) from dual;
l果: 我是孟庆?
函数? INITCAP(string)
含义: q回字符串ƈ字W串的第一个字母变为大?
CZ: select INITCAP('aaa') from dual;
l果: Aaa
函数? INSTR(被搜索字W串,搜烦的字W串,搜烦的开始位|默认ؓ1,W几ơ出现默认ؓ1)
含义: 在一个字W串中搜索指定的字符,q回发现指定的字W的位置
CZ: select INSTR('我是孟庆?,'?,1,1) from dual;
l果: 3
函数? LENGTH(string)
含义: q回字符串的长度
CZ: select length('孟庆?) from dual ;
l果: 3
函数? LOWER(string)
含义: 写形式
CZ: select lower('AAA') from dual
l果: aaa
函数? UPPER
含义: 大写形式
CZ: select upper('aaa') from dual ;
l果: AAA
函数? RPAD & LPAD
含义: 黏脓字符串到目标字符串左?
CZ: select lpad('a',10,'*') from dual ;
l果: *********a
函数? ltrim & rtrim
含义: 删除左边Q右边)的字W串
CZ: select ltrim('abc','a') from dual ;
l果: bc
函数? substr
含义: 取字W串(原字W串,W几个开?取几?
CZ: select substr ('abcdefg',3,4) from dual
l果: cdef
函数? REPLACE(string,string,string)
含义: 替换字符?
CZ: select replace('abcde' , 'abc' , 'aaa' ) from dual ;
l果: aaade
数学函数
函数? abs
含义: q回指定值的l对?
CZ: select abs(-10) from dual
l果: 10
自定义函?
--函数function
create or replace function prices
(
proprice in number
)
return integer
is
pricecount integer;
begin
select count(price) into pricecount from product where price>proprice;
if(pricecount >0) then
return pricecount;
else
return 0;
end if;
end prices;
declare
counter number := 0;
begin
counter := prices(30);
if counter >0 then
dbms_output.put_line('counts:'||counter );
else
dbms_output.put_line('counts:'||counter );
end if;
end;
/
常见问题
1 不能启动监听
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\OracleOraHome92TNSListener
d字符串项ImagePath,gؓc:\oracle\ora90\bin\TNSLSNR
2 启动?监听器不启动或打开出错
错误现象Q?
Oracle启动Ӟ监听器不启动或打开出错Q服务器端:用username/passwordd正常Q但用username/password@aliasd不成功;客户端:用username/password@aliasd不成?
解决Ҏ
Q?Q如果是因ؓ修改了NT的机器名Q则把listener.ora文g中的host参数全部改ؓ新的NT机器名,重新启动OracleTNSListener80服务卛_?
例如:
LISTENER =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(Host = NT_Name)(Port = 1521))
(ADDRESS=(PROTOCOL=TCP)(Host=NT_Name)(Port= 1526))
)
3 q行oracle后tomcatq行出错
原因Q端口冲H?
解决Ҏ
修改tomcat的conf.xml文gQ查?080Q修改ؓ其他
4 本地日期问题
扑ֈ注册表MACHINE/SOFTWARE/ORACLE/HOME0/
d字符?NLS_DATE_FORMAT gؓyyyy-mm-dd