oracle 学习笔记
2012-07-29 22:25
183 查看
Oracle 简单命令
showuser;
connsystem/orcl as sysoper;
connsys/orcl sysdba;
disc[connect];断开连接。
passw[ord]system; 更改密码
startd:\sql.sql;或 @ d:\sql.sql
editd:\sql.sql;
spoold:\spool.txt; 将spool与spool off之间执行的语句输出到指定文本
spooloff;
select* from emp where job = “&job”;
交互式
显示和设置环境变量
showlinesize;
setlinesize 50;
setpagesize 30;
desctableName; 查看表结构,好像来自MySql
SQL>select to_char(sysdate, 'yyyy-mm-dd hh24:mi:ss') as nowtime from dual;
oracle 用户管理
createuser young identified by young;
创建的新用户是没有任何权限的,可以用grant赋权限。Oracle 大概有140种权限。可分为系统权限和对象权限。
alteruser system identified by orcl;
dropuser young cascade; 如果要删除的用户,已经创建了表,那么就需要带一个参数 cascade;
grantconnect to young; connect为一个角色,还有dba角色,resource角色(允许可以在表空间中任意建表)等。
对象权限有select, insert, delete, update,all(包括前四个), create index等,示例如下。
grantselect on emp to young;
select* from scott.emp; (要有scott用户名,这里包括方案的概念)
revoke用来收回权限。只有赋权限的用户可以收回相应的权限。
revokeselect on emp from young;
revokecreate session from young;
如果想让赋予的权限可以传递可以在后面加上with grant option
grantselect on emp to young with grant option;
grantselect on scott.emp to yooung;
如果回收young的权限,那么通过young赋给yooung的权限也会被回收
profile 是口令限制,资源限制的命令集合,当建立数据库时,oracle会自动建立名称为default的profile,当建立用户没有指定profile选项,那么oracle就会将default分配给用户。如下
sql>create profile lock_account limit failed_login_attempts 3 password 3password_lock_time 2;
sql>alert user young profile lock_account;
可以通过以下命令进行用户解锁
Sql>alter user young account unlock;
终止口令:
10天不修改密码就会出现警告,12天后就无法登录,password_reuse_times可以指定口令可重用时间(口令的历史),如下
sql>createprofile myprofile limit password_life_time 10 password_grace_time 2 [password_reuse_time10];
sql>alter user young profile myprofile;
删除profile,当不需要某个profile文件时,可以删除该文件
sql>drop profile password_history [cascade]
Oracle的数据类型:
char, varchar, varchar2, number,date, timestamp
修改表:
添加一个字段
sql>alter table student add(classId number(2));
修改字段的长度
sql>alter table student modify(classId number(4));
删除一个字段:
sql>alter table student drop column sal;
修改表的名字:
sql>rename student to stu;
插入date类型数据:
sql>insertinto student
values(1,
'young',
'男',
'25-1月-1989',
8000.0,
12);
Oracle 中默认的日期格式‘DD-MON-YY’
改日期的默认格式:
sql>alter session set nls_date_format = ‘yyyy-mm-dd’
插入空值:
sql>insert into student(birthday) values(null);
删除数据:
select 删除数据是可以通过日志恢复的,但 truncate table student;就不会写日志,无法找回删除的记录,速度快。
sql> savepoint mypoint;
sql> rollback to mypoint;
可以用set timing on可以在执行sql后显示执行所用时间。
SQL>insert into student select * from student;可以用来快速插入大量数据;
SQL>select distinct deptno, job from emp;可以删除重复的行。
在进行数值运算时如果出现null值,那么运算结果也有null值,可以用nvl函数来解决这个问题。如下
SQL>select ename, sal*12+nvl(comm, 0)*12 "年工资" from emp;
比较日期前后:
SQL>select ename, hiredate from emp where hiredate > '1/1月/1982';或SQL>select
ename, hiredate from emp where hiredate > '1-1月-1982';
like查询:
“%” 表示任意0到多个字符, “_” 表示任意单个字符
嵌套排序:
SQL>select * from emp order by deptno, sal desc;
使用列的别名排序:
SQL>select ename, (sal+nvl(comm, 0))*12 as
年薪 from emp order by '年薪';
group by:
SQL>select avg(sal), max(sal), deptno from emp group by deptno;
SQL>select avg(sal), max(sal), deptno, job from emp group by deptno, job;
having:
SQL>select avg(sal), max(sal), deptno from emp group by deptno having avg(sal) >2000;
分组函数只能出现在选择列表having,order by子句中,
SQL>select avg(sal), max(sal), deptno from emp group by deptno having avg(sal) >2000;
下面的语句会出现笛卡尔集:
QL>select a1.ename, a1.job, a2.dname, a2.deptno from emp a1, dept a2;
规定:多表查询的条件至少不能少于表的个数 – 1;
SQL>select a1.ename, a1.sal, a2.grade from emp a1, salgrade a2 where a1.sal betweena2.losal and a2.hisal;
自连接应用:
SQL>select worker.ename, boss.ename from emp worker, emp boss where worker.mgr =boss.empno;
单行子查询:指的是返回一条数据的子查询。与之相对应的是多行子查询。
在多行子查询中可以使用all来比较,与max()函数的结果是一样的,下面的两个条语句结果是一样的,但是max()效率能高一些。
SQL>select * from emp where sal > all(select sal from emp where deptno = 30);
SQL>select * from emp where sal > (select max(sal) from emp where deptno = 30);
多列子查询如下,注意对应相应列。
SQL>select * from emp where (deptno, job) = (select deptno, job from emp whereename = 'SMITH');
在from子句中使用子查询时,该子查询会被作为一个视图来对待,因此叫作内嵌视图,必须给该子查询指定别名,不能用as,如下。
SQL>select a1.ename, a1.sal, a1.deptno, a2.av from emp a1, (select deptno, avg(sal)av from emp group by deptno) a2 where a1.deptno = a2.deptno and a1.sal >a2.av;
orcle的分页方式:3种
1.这种方式是效率最快的
SQL>select * from (select a1.*, rownum rn from (select * fromemp) a1 where rownum <= 10) a1 where rn >=6;
2.
3.
如果指定查询列,只需改动最里层的语句。就是select* from emp; 排序刚为select* from emp order by sal asc;
用查询结果创建新表,插出数据,更新数据
SQL>create table emp2(id, ename, sal) as select empno, ename, sal from emp;
SQL> insert into tableName(column1,column2) select column1, column2 from tableName2;
SQL> update emp set(job, sal, comm) =(select job, sal, comm from emp where ename = ‘SMITH’) where ename = ‘SCOTT’;
合并查询:union(不包括重复行),union all, intersect(交集),minus(差集),速度比and等快。oracle特有的。
SQL>select ename, sal, job from emp where sal > 2500 union
select ename, sal, job from emp where job ='manager';
Oracle中事务处理
事务用于保证数据的一致性,它由一组相关的dml语句组成,该组dml语句要和全部成功,要么全部失败。
事务和锁:当执行事务操作时,oracle会在被作用的表上加锁,防止其它用户改表的结构。
savapointmy_point;
rollbackto my_point;
只读事务处理:看不到事务后面发生的事情。指只允许执行查询的操作,不允许执行任何其它dml操作的事务,只读事务可以确保用户只能取得某时间以前的数据。
SQL>set transaction read only;
字符函数:
lower(char),upper(char), length(char), substr(char),replace(char, char2, char3)
SQL>select upper(substr(ename, 1, 1)) from emp;
SQL>select lower(substr(ename, 2, length(ename) - 1)), ename from emp;
常用的数学函数:
round(n, [m])(四舍五入),trunk(n, [m])(截取数字),mod(n, [m]), floor(n)(向下取整),ceil(n)(向上取整);
日期函数:
默认情况下日期格式是dd-mon-yy,即12-7月-78
sysdate返回系统时间。
add_months(d, n);
last_day(date),date所在月份的最后一天;
转换函数:
to_char();
SQL>select ename, to_char(hiredate, 'yyyy-mm-dd hh24:mi:ss') from emp;
to_date();可以将字条串转换成日期类型
SQL>select to_date('1989-01-25 9:9:9', 'yyyy-mm-dd hh:mi:ss') from dual;
系统环境:
SQL>selectsys_context('userenv', 'db_name') from dual;
SQL>select sys_context('userenv', 'language') from dual;
SQL>select sys_context('userenv', 'session_user') from dual;
SQL>select sys_context('userenv', 'current_schema') from dual;
每一个用户对应一个方案
数据库管理员
管理数据库的用户主要是sys和system,区别主要是:
1. 最重要的区别,存储的数据的重要性不同
sys所有oracle的数据字典的基表和视图都存放在sys用户中这些基表和视图对于oracle的运行是至关重要的。sys用户拥有dba,
sysdba, sysoper角色或权限。
system用于存放次一级的内部数据,拥有dba, sysdba角色或系统权限
2. 权限不同
管理初始化参数
初始化参数用于设置实例或是数据库的特征
SQL>show parameter;
数据库备份
逻辑备份:
导出具体分为:导出表,导出方案,导出数据库三种方式
表空间和数据文件的管理:
表空间是数据的逻辑组成部分,表空间由一个或多个数据文件组成。
oracle中逻辑结构包括表空间,段,区和块。数据库表空间构成,而段又是由区构成,而区又是由oracle块构成的这样的一种结构,可以提高数据库的效率。
通过表空间可以达到以下的作用:
1. 控制数据库占用的磁盘空间
2. dba可以将不同数据类型部署到不同的位置,这样有利于提高i/o性能,同时利于备份和恢复等管理操作
建立空间:
create tablespace, 须要有create tablespace系统权限
createtablespace sp01 datafile ‘d:\oracle\sp01.dbf’ size 20m uniform size 128k; --区的大小为128k
使用表空间
createtable mypart(deptno number(4)) tablespace sp01;
改变空间的状态:
表空间脱机,联机:
SQL>alter tablespace users offline;、
SQL>alter tablespace users online;
表空间只读
SQL>alter tablespace users read only;
SQL>alter tablespace users read write;
查询表空间中的表
SQL>select * from all_tables where tablespace_name = 'USERS';
查询某个表属于哪个表空间
SQL>select tablespace_name, table_name from user_tables where table_name = 'EMP';
删除表空间
drop tablespace users including contentsand datafiles;
扩展表空间
alter tablespace sp01 add datafile
'd:\oracle\sp02.dbf' size 20m;
alter tablespace sp01
'd:\oracle\sp01.dbf' resize 20m;
alter tablespace sp01
'd:\oracle\sp01.dbf' autoextend on next 10mmaxsize 500m;
移动数据文件
1.确定数据文件所在的表空间
SQL>select tablespace_name from dba_data_files where file_name = 'd:\oracle\sp01.dbf';
2.使表空间脱机
3.使用命令移动数据文件到指定的目标位置
hostmove d:\sp01.dbf c:\sp01.dbf;
4.在物理上移动了数据后,还必须执行alter tablespace命令对数据库文件进行逻辑修改:
alter tablespace sp01 rename datafile
'd:\sp01.dbf' to
'c:\sp01.def';
5.使表空间联机
显示表空间信息
select tablespace_name from dba_tablespaces;
显示表空间所包含的数据文件
SQL> select * from dba_data_fileswhere tablespace_name = 'USERS';
维护数据的完整性
数据的完整性用于确保数据库数据遵从一定的商业和逻辑规则。Oracle中,可以使用约束,触发器,应用程序(过程,函数)三种方法来实现,这三种方法中,因为约束易于维护并且具有最好的性能,所以作为维护数据完整性的首选。
约束:not null, unique(可以为null), primary key(不能为null),
forgien key, check
alter table goods modify goodsName notnull;
alter table customer add constraintcardunique unique(cardId);
alter table customer add constraintaddresscheck check(address in('east', 'west'));
删除约束
alter table customer drop constraintcardunipue;
alter table customer drop primary keycascade;
SQL> select constraint_name, constraint_type,status, validated from User_Constraints;
SQL> select column_name, position fromuser_cons_columns;
管理索引
索引是用于加速数据存取的数据对象,当某一列为unique时,oracle会自动会在上面建立索引。
单列索引
SQL> create index nameIndex onemp2(ename);
复合索引
SQL> create index nameIndex on emp2(ename,job);
索引的缺点
1.建立索引,系统要占用大约为表的1.2倍的硬盘和内存空间来保存索引。
2.更新数据的时候,系统必须要有额外的时间来同时对索引进行更新,以维持一致性。
SQL> select * from user_indexes;
SQL> select table_name, column_namefrom user_ind_columns;
管理权限和角色
预定义角色
1. connect角色,具有一般应用开发人员需要的大部分权限,当建立一个用户后,只要给用户授予connect和resource角色就够了,connect角色具有alter
session, create cluster, create database link, create session,create table, create view, create sequencea权限。
2. resource角色具有应用开发人员所需要的其它权限,比如建立存储过程,触发器等。
自定义角色
一般是dba来建立,其它用户需要具有create role的系统权限。
SQL>create role my_role not identified;
SQL>create role my_role identified by my_role;
授权
如果是系统权限要用admin,而如果是对象权限则用grant.
SQL>grant create session to my_role with admin option;
SQL>grant select on scott.emp to my_role with grant option;
删除角色应该具有drop any role的权限
SQL>drop role my_role;
查询所有角色
SQL>select * from dba_roles;
select * from role_sys_privs;
SQL>select * from dba_role_privs where grantee = 'SCOTT';
PL/SQL编程
块的定义(block):
SQL>set serveroutput on; --打开输出选项
SQL>begin
2 dbms_output.put_line('Hello World');
3 end;
4 /
declare v_ename
varchar2(5);
--定义字符串变量
begin
--执行部分
select ename
into v_ename
from emp
where empno = &no;
--在控制台显示用户名
dbms_output.put_line('用户名是:'
|| v_ename);
end;
异常处理(exception):
--定义字符串变量
declare v_ename
varchar2(5);
begin
--执行部分
selectename
into v_ename
from emp
where empno = &no;
--在控制台显示用户名
dbms_output.put_line('用户名是:'
|| v_ename);
--异常处理
exception
when no_data_found
then
dbms_output.put_line('你的编号输入有误');
end;
创建存储过程(procedure):
SQL>createor replace procedure pro_test is
2 begin
3 insert into test values(123, 'young');
4 end;
5 /
SQL>exec pro_test;
--案例
createprocedure pro_test2(proName
varchar2, proSal
number)
is
begin
--根据用户名去修改工资
update empset
sal = proSal where ename = proName;
end;
函数(function):
用于返回特定的数据,只能返回一个数值
--函数案例
createfunction ly_fun(name1
varchar2)
returnnumberis
yearSalnumber(7,
2);
begin
--执行部分
select sal*12+nvl(comm,
0)*12into
yearSal from emp
where ename = name1;
return yearSal;
end;
调用:
SQL>var v number;
SQL>call ly_fun('SCOTT') into:v;
包(package):
包用于在逻辑上组合过程和函数,它由包规范和包体两部分组成
--创建包
--声明一个过程
--声明一个函数
createpackage ly_package
is
procedure update_sal(namevarchar2,
newsal number);
function annual_income(namevarchar2)
returnnumber;
end;
--给包实现包体
createpackagebody ly_package
is
procedure ...
is
begin
end;
function ...return
numberis
end;
--调用包
exec sp_package.update_sal('SCOTT',
120);
触发器:
变量类型:标量(scalar), 复合变量(composite),参照变量,
复合变量之pl/sql记录,相当于高级语言中的类,如下
declare
--定义一个pl/sql记录类型,
type emp_record_type
isrecord(name
emp.ename%type, salary emp.sal%type, title emp.job%type);
--定义一个变量,类型为emp_record_type
ly_recordemp_record_type;
begin
select ename, sal, job
into ly_record
from emp
where empno =
7788;
dbms_output.put_line(ly_record.name ||
', ' || ly_record.salary);
end;
复合变量之pl/sql表,相当于高级语言中的数组,如下
declare
--定义一个pl/sql表类型,该类型是用于存放emp.ename%type的数组,下标可以为负数
type my_table_type
istableof emp.ename%typeindexbybinary_integer;
--定义一个变量,类型为my_table_type
my_tablemy_table_type;
begin
selectename
into my_table(0)
from emp
where empno=7788;
dbms_output.put_line('ename: ' || my_table(0));
end;
参照变量是指用于存放数值指针的变量,可以使用游标变量(refcursor)和对象类型变量(refobj_type).
declare
--定义游标
type my_emp_cursor
isrefcursor;
--定义一个游标变量
my_cursormy_emp_cursor;
--定义变量
v_enameemp.ename%type;
v_salemp.sal%type;
begin
--my_cursor
和一个select
结合
openmy_cursor
forselect ename, sal
from emp
where deptno = &no;
--循环
loop
fetch my_cursor
into v_ename, v_sal;
--判断my_cursor是否为空
exitwhen my_cursor%notfound;
dbms_output.put_line(v_ename ||
', ' || v_sal);
endloop;
end;
控制结构
if then; if then else; ifthen elsif else;
createorreplaceprocedure
my_pro_if(namevarchar2)
is
v_salemp.sal%type;
begin
select salinto
v_sal from emp
where ename =
name;
--if block
ifv_sal <>
2000then
--update emp set sal = sal*1.1 whereename = name;
dbms_output.put_line(v_sal);
endif;
end;
循环语句 –loop
createorreplaceprocedure
my_pro_loop(numnumber)
is
v_numnumber :=
num;
begin
loop
dbms_output.put_line('loop number: ' || v_num);
exitwhen v_num =
0;
v_num := v_num - 1;
endloop;
end;
-for循环
-- in代表num是一个输入参数,默认是in,
out代表输出参数
createorreplaceprocedure
my_pro_for(num innumber)
is
begin
-- for block, reverse is optional
for i
inreverse1..num
loop
dbms_output.put_line('loop number: ' || i);
endloop;
end;
-goto,不建议使用
goto lable;
<<lable>>
-null null语句是一个空语句,什么都不干
null;
用Java调用有返回值的procedure
cs.registerOutParameter(2, oracle.jdbc.OracleTypes.VARCHAR);
cs.execute();
Stringname = cs.getString(2);
用Java调用返回值为cursor的procedure
--返回结果集的过程
--创建一个包
createorreplacepackage
my_pack_out as
typemy_cursor
isrefcursor;
end my_pack_out;
--创建过程
createorreplaceprocedure
my_pro_pack_out
(innoinnumber, outcursor
out my_pack_out.my_cursor)
is
begin
openoutcursor
forselect *
from emp
where deptno = inno;
end;
/*java */
cs.registerOutParameter(2, oracle.jdbc.OracleTypes.CURSOR);
cs.execute();
ResultSetrs = (ResultSet)cs.getObject(2);
用存储过程实现分页程序
--分页包
createorreplacepackage
divide_pages_pack as
typepack_cursor
isrefcursor;
end divide_pages_pack;
--分页过程
createorreplaceprocedure
divide_pages (
table_nameinvarchar2,
page_sizeinnumber,
--每页记录数
current_pageinnumber,
--当前页号
row_countoutnumber,
--总记录数
page_countoutnumber,
--总页数
out_cursorout divide_pages_pack.pack_cursor
) is
--起始页位置
v_beginnumber := (current_page -
1) * page_size +
1;
--结束页位置
v_endnumber := current_page * page_size;
begin
openout_cursor
for'select * from
(select a1.*, rownum rn from(select * from emp) a1
where rownum <= '|| v_end ||') a1 where rn >= '
|| v_begin;
--计算出总行数
executeimmediate'select count(*) from '
|| table_name into row_count;
ifmod(row_count, page_size) =
0then
page_count := row_count / page_size;
else
page_count := row_count / page_size +
1;
endif;
--关闭游标
--close out_cursor;
end;
视图
是一个虚拟表,其内容由查询定义。
视图与表的区别
1.表需要占用磁盘空间,视图不需要。
2.视图不能添加索引
3.视图有利于提高安全性
--创建视图:
--scott可能没有创建视图的权限,可以登录system用户更改权限。
grant create any view toscott;
createview myview
asselect *
from emp
where sal<
1000;
--可以加上 with
read only 只允许读数据
createorreplaceview
myview asselect *
from emp
where sal <
1000withreadonly;
--删除视图
dropview myview;
showuser;
connsystem/orcl as sysoper;
connsys/orcl sysdba;
disc[connect];断开连接。
passw[ord]system; 更改密码
startd:\sql.sql;或 @ d:\sql.sql
editd:\sql.sql;
spoold:\spool.txt; 将spool与spool off之间执行的语句输出到指定文本
spooloff;
select* from emp where job = “&job”;
交互式
显示和设置环境变量
showlinesize;
setlinesize 50;
setpagesize 30;
desctableName; 查看表结构,好像来自MySql
SQL>select to_char(sysdate, 'yyyy-mm-dd hh24:mi:ss') as nowtime from dual;
oracle 用户管理
createuser young identified by young;
创建的新用户是没有任何权限的,可以用grant赋权限。Oracle 大概有140种权限。可分为系统权限和对象权限。
alteruser system identified by orcl;
dropuser young cascade; 如果要删除的用户,已经创建了表,那么就需要带一个参数 cascade;
grantconnect to young; connect为一个角色,还有dba角色,resource角色(允许可以在表空间中任意建表)等。
对象权限有select, insert, delete, update,all(包括前四个), create index等,示例如下。
grantselect on emp to young;
select* from scott.emp; (要有scott用户名,这里包括方案的概念)
revoke用来收回权限。只有赋权限的用户可以收回相应的权限。
revokeselect on emp from young;
revokecreate session from young;
如果想让赋予的权限可以传递可以在后面加上with grant option
grantselect on emp to young with grant option;
grantselect on scott.emp to yooung;
如果回收young的权限,那么通过young赋给yooung的权限也会被回收
profile 是口令限制,资源限制的命令集合,当建立数据库时,oracle会自动建立名称为default的profile,当建立用户没有指定profile选项,那么oracle就会将default分配给用户。如下
sql>create profile lock_account limit failed_login_attempts 3 password 3password_lock_time 2;
sql>alert user young profile lock_account;
可以通过以下命令进行用户解锁
Sql>alter user young account unlock;
终止口令:
10天不修改密码就会出现警告,12天后就无法登录,password_reuse_times可以指定口令可重用时间(口令的历史),如下
sql>createprofile myprofile limit password_life_time 10 password_grace_time 2 [password_reuse_time10];
sql>alter user young profile myprofile;
删除profile,当不需要某个profile文件时,可以删除该文件
sql>drop profile password_history [cascade]
Oracle的数据类型:
char, varchar, varchar2, number,date, timestamp
修改表:
添加一个字段
sql>alter table student add(classId number(2));
修改字段的长度
sql>alter table student modify(classId number(4));
删除一个字段:
sql>alter table student drop column sal;
修改表的名字:
sql>rename student to stu;
插入date类型数据:
sql>insertinto student
values(1,
'young',
'男',
'25-1月-1989',
8000.0,
12);
Oracle 中默认的日期格式‘DD-MON-YY’
改日期的默认格式:
sql>alter session set nls_date_format = ‘yyyy-mm-dd’
插入空值:
sql>insert into student(birthday) values(null);
删除数据:
select 删除数据是可以通过日志恢复的,但 truncate table student;就不会写日志,无法找回删除的记录,速度快。
sql> savepoint mypoint;
sql> rollback to mypoint;
可以用set timing on可以在执行sql后显示执行所用时间。
SQL>insert into student select * from student;可以用来快速插入大量数据;
SQL>select distinct deptno, job from emp;可以删除重复的行。
在进行数值运算时如果出现null值,那么运算结果也有null值,可以用nvl函数来解决这个问题。如下
SQL>select ename, sal*12+nvl(comm, 0)*12 "年工资" from emp;
比较日期前后:
SQL>select ename, hiredate from emp where hiredate > '1/1月/1982';或SQL>select
ename, hiredate from emp where hiredate > '1-1月-1982';
like查询:
“%” 表示任意0到多个字符, “_” 表示任意单个字符
嵌套排序:
SQL>select * from emp order by deptno, sal desc;
使用列的别名排序:
SQL>select ename, (sal+nvl(comm, 0))*12 as
年薪 from emp order by '年薪';
group by:
SQL>select avg(sal), max(sal), deptno from emp group by deptno;
SQL>select avg(sal), max(sal), deptno, job from emp group by deptno, job;
having:
SQL>select avg(sal), max(sal), deptno from emp group by deptno having avg(sal) >2000;
分组函数只能出现在选择列表having,order by子句中,
SQL>select avg(sal), max(sal), deptno from emp group by deptno having avg(sal) >2000;
下面的语句会出现笛卡尔集:
QL>select a1.ename, a1.job, a2.dname, a2.deptno from emp a1, dept a2;
规定:多表查询的条件至少不能少于表的个数 – 1;
SQL>select a1.ename, a1.sal, a2.grade from emp a1, salgrade a2 where a1.sal betweena2.losal and a2.hisal;
自连接应用:
SQL>select worker.ename, boss.ename from emp worker, emp boss where worker.mgr =boss.empno;
单行子查询:指的是返回一条数据的子查询。与之相对应的是多行子查询。
在多行子查询中可以使用all来比较,与max()函数的结果是一样的,下面的两个条语句结果是一样的,但是max()效率能高一些。
SQL>select * from emp where sal > all(select sal from emp where deptno = 30);
SQL>select * from emp where sal > (select max(sal) from emp where deptno = 30);
多列子查询如下,注意对应相应列。
SQL>select * from emp where (deptno, job) = (select deptno, job from emp whereename = 'SMITH');
在from子句中使用子查询时,该子查询会被作为一个视图来对待,因此叫作内嵌视图,必须给该子查询指定别名,不能用as,如下。
SQL>select a1.ename, a1.sal, a1.deptno, a2.av from emp a1, (select deptno, avg(sal)av from emp group by deptno) a2 where a1.deptno = a2.deptno and a1.sal >a2.av;
orcle的分页方式:3种
1.这种方式是效率最快的
SQL>select * from (select a1.*, rownum rn from (select * fromemp) a1 where rownum <= 10) a1 where rn >=6;
2.
3.
如果指定查询列,只需改动最里层的语句。就是select* from emp; 排序刚为select* from emp order by sal asc;
用查询结果创建新表,插出数据,更新数据
SQL>create table emp2(id, ename, sal) as select empno, ename, sal from emp;
SQL> insert into tableName(column1,column2) select column1, column2 from tableName2;
SQL> update emp set(job, sal, comm) =(select job, sal, comm from emp where ename = ‘SMITH’) where ename = ‘SCOTT’;
合并查询:union(不包括重复行),union all, intersect(交集),minus(差集),速度比and等快。oracle特有的。
SQL>select ename, sal, job from emp where sal > 2500 union
select ename, sal, job from emp where job ='manager';
Oracle中事务处理
事务用于保证数据的一致性,它由一组相关的dml语句组成,该组dml语句要和全部成功,要么全部失败。
事务和锁:当执行事务操作时,oracle会在被作用的表上加锁,防止其它用户改表的结构。
savapointmy_point;
rollbackto my_point;
只读事务处理:看不到事务后面发生的事情。指只允许执行查询的操作,不允许执行任何其它dml操作的事务,只读事务可以确保用户只能取得某时间以前的数据。
SQL>set transaction read only;
字符函数:
lower(char),upper(char), length(char), substr(char),replace(char, char2, char3)
SQL>select upper(substr(ename, 1, 1)) from emp;
SQL>select lower(substr(ename, 2, length(ename) - 1)), ename from emp;
常用的数学函数:
round(n, [m])(四舍五入),trunk(n, [m])(截取数字),mod(n, [m]), floor(n)(向下取整),ceil(n)(向上取整);
日期函数:
默认情况下日期格式是dd-mon-yy,即12-7月-78
sysdate返回系统时间。
add_months(d, n);
last_day(date),date所在月份的最后一天;
转换函数:
to_char();
SQL>select ename, to_char(hiredate, 'yyyy-mm-dd hh24:mi:ss') from emp;
to_date();可以将字条串转换成日期类型
SQL>select to_date('1989-01-25 9:9:9', 'yyyy-mm-dd hh:mi:ss') from dual;
系统环境:
SQL>selectsys_context('userenv', 'db_name') from dual;
SQL>select sys_context('userenv', 'language') from dual;
SQL>select sys_context('userenv', 'session_user') from dual;
SQL>select sys_context('userenv', 'current_schema') from dual;
每一个用户对应一个方案
数据库管理员
管理数据库的用户主要是sys和system,区别主要是:
1. 最重要的区别,存储的数据的重要性不同
sys所有oracle的数据字典的基表和视图都存放在sys用户中这些基表和视图对于oracle的运行是至关重要的。sys用户拥有dba,
sysdba, sysoper角色或权限。
system用于存放次一级的内部数据,拥有dba, sysdba角色或系统权限
2. 权限不同
管理初始化参数
初始化参数用于设置实例或是数据库的特征
SQL>show parameter;
数据库备份
逻辑备份:
导出具体分为:导出表,导出方案,导出数据库三种方式
表空间和数据文件的管理:
表空间是数据的逻辑组成部分,表空间由一个或多个数据文件组成。
oracle中逻辑结构包括表空间,段,区和块。数据库表空间构成,而段又是由区构成,而区又是由oracle块构成的这样的一种结构,可以提高数据库的效率。
通过表空间可以达到以下的作用:
1. 控制数据库占用的磁盘空间
2. dba可以将不同数据类型部署到不同的位置,这样有利于提高i/o性能,同时利于备份和恢复等管理操作
建立空间:
create tablespace, 须要有create tablespace系统权限
createtablespace sp01 datafile ‘d:\oracle\sp01.dbf’ size 20m uniform size 128k; --区的大小为128k
使用表空间
createtable mypart(deptno number(4)) tablespace sp01;
改变空间的状态:
表空间脱机,联机:
SQL>alter tablespace users offline;、
SQL>alter tablespace users online;
表空间只读
SQL>alter tablespace users read only;
SQL>alter tablespace users read write;
查询表空间中的表
SQL>select * from all_tables where tablespace_name = 'USERS';
查询某个表属于哪个表空间
SQL>select tablespace_name, table_name from user_tables where table_name = 'EMP';
删除表空间
drop tablespace users including contentsand datafiles;
扩展表空间
alter tablespace sp01 add datafile
'd:\oracle\sp02.dbf' size 20m;
alter tablespace sp01
'd:\oracle\sp01.dbf' resize 20m;
alter tablespace sp01
'd:\oracle\sp01.dbf' autoextend on next 10mmaxsize 500m;
移动数据文件
1.确定数据文件所在的表空间
SQL>select tablespace_name from dba_data_files where file_name = 'd:\oracle\sp01.dbf';
2.使表空间脱机
3.使用命令移动数据文件到指定的目标位置
hostmove d:\sp01.dbf c:\sp01.dbf;
4.在物理上移动了数据后,还必须执行alter tablespace命令对数据库文件进行逻辑修改:
alter tablespace sp01 rename datafile
'd:\sp01.dbf' to
'c:\sp01.def';
5.使表空间联机
显示表空间信息
select tablespace_name from dba_tablespaces;
显示表空间所包含的数据文件
SQL> select * from dba_data_fileswhere tablespace_name = 'USERS';
维护数据的完整性
数据的完整性用于确保数据库数据遵从一定的商业和逻辑规则。Oracle中,可以使用约束,触发器,应用程序(过程,函数)三种方法来实现,这三种方法中,因为约束易于维护并且具有最好的性能,所以作为维护数据完整性的首选。
约束:not null, unique(可以为null), primary key(不能为null),
forgien key, check
alter table goods modify goodsName notnull;
alter table customer add constraintcardunique unique(cardId);
alter table customer add constraintaddresscheck check(address in('east', 'west'));
删除约束
alter table customer drop constraintcardunipue;
alter table customer drop primary keycascade;
SQL> select constraint_name, constraint_type,status, validated from User_Constraints;
SQL> select column_name, position fromuser_cons_columns;
管理索引
索引是用于加速数据存取的数据对象,当某一列为unique时,oracle会自动会在上面建立索引。
单列索引
SQL> create index nameIndex onemp2(ename);
复合索引
SQL> create index nameIndex on emp2(ename,job);
索引的缺点
1.建立索引,系统要占用大约为表的1.2倍的硬盘和内存空间来保存索引。
2.更新数据的时候,系统必须要有额外的时间来同时对索引进行更新,以维持一致性。
SQL> select * from user_indexes;
SQL> select table_name, column_namefrom user_ind_columns;
管理权限和角色
预定义角色
1. connect角色,具有一般应用开发人员需要的大部分权限,当建立一个用户后,只要给用户授予connect和resource角色就够了,connect角色具有alter
session, create cluster, create database link, create session,create table, create view, create sequencea权限。
2. resource角色具有应用开发人员所需要的其它权限,比如建立存储过程,触发器等。
自定义角色
一般是dba来建立,其它用户需要具有create role的系统权限。
SQL>create role my_role not identified;
SQL>create role my_role identified by my_role;
授权
如果是系统权限要用admin,而如果是对象权限则用grant.
SQL>grant create session to my_role with admin option;
SQL>grant select on scott.emp to my_role with grant option;
删除角色应该具有drop any role的权限
SQL>drop role my_role;
查询所有角色
SQL>select * from dba_roles;
select * from role_sys_privs;
SQL>select * from dba_role_privs where grantee = 'SCOTT';
PL/SQL编程
块的定义(block):
SQL>set serveroutput on; --打开输出选项
SQL>begin
2 dbms_output.put_line('Hello World');
3 end;
4 /
declare v_ename
varchar2(5);
--定义字符串变量
begin
--执行部分
select ename
into v_ename
from emp
where empno = &no;
--在控制台显示用户名
dbms_output.put_line('用户名是:'
|| v_ename);
end;
异常处理(exception):
--定义字符串变量
declare v_ename
varchar2(5);
begin
--执行部分
selectename
into v_ename
from emp
where empno = &no;
--在控制台显示用户名
dbms_output.put_line('用户名是:'
|| v_ename);
--异常处理
exception
when no_data_found
then
dbms_output.put_line('你的编号输入有误');
end;
创建存储过程(procedure):
SQL>createor replace procedure pro_test is
2 begin
3 insert into test values(123, 'young');
4 end;
5 /
SQL>exec pro_test;
--案例
createprocedure pro_test2(proName
varchar2, proSal
number)
is
begin
--根据用户名去修改工资
update empset
sal = proSal where ename = proName;
end;
函数(function):
用于返回特定的数据,只能返回一个数值
--函数案例
createfunction ly_fun(name1
varchar2)
returnnumberis
yearSalnumber(7,
2);
begin
--执行部分
select sal*12+nvl(comm,
0)*12into
yearSal from emp
where ename = name1;
return yearSal;
end;
调用:
SQL>var v number;
SQL>call ly_fun('SCOTT') into:v;
包(package):
包用于在逻辑上组合过程和函数,它由包规范和包体两部分组成
--创建包
--声明一个过程
--声明一个函数
createpackage ly_package
is
procedure update_sal(namevarchar2,
newsal number);
function annual_income(namevarchar2)
returnnumber;
end;
--给包实现包体
createpackagebody ly_package
is
procedure ...
is
begin
end;
function ...return
numberis
end;
--调用包
exec sp_package.update_sal('SCOTT',
120);
触发器:
变量类型:标量(scalar), 复合变量(composite),参照变量,
复合变量之pl/sql记录,相当于高级语言中的类,如下
declare
--定义一个pl/sql记录类型,
type emp_record_type
isrecord(name
emp.ename%type, salary emp.sal%type, title emp.job%type);
--定义一个变量,类型为emp_record_type
ly_recordemp_record_type;
begin
select ename, sal, job
into ly_record
from emp
where empno =
7788;
dbms_output.put_line(ly_record.name ||
', ' || ly_record.salary);
end;
复合变量之pl/sql表,相当于高级语言中的数组,如下
declare
--定义一个pl/sql表类型,该类型是用于存放emp.ename%type的数组,下标可以为负数
type my_table_type
istableof emp.ename%typeindexbybinary_integer;
--定义一个变量,类型为my_table_type
my_tablemy_table_type;
begin
selectename
into my_table(0)
from emp
where empno=7788;
dbms_output.put_line('ename: ' || my_table(0));
end;
参照变量是指用于存放数值指针的变量,可以使用游标变量(refcursor)和对象类型变量(refobj_type).
declare
--定义游标
type my_emp_cursor
isrefcursor;
--定义一个游标变量
my_cursormy_emp_cursor;
--定义变量
v_enameemp.ename%type;
v_salemp.sal%type;
begin
--my_cursor
和一个select
结合
openmy_cursor
forselect ename, sal
from emp
where deptno = &no;
--循环
loop
fetch my_cursor
into v_ename, v_sal;
--判断my_cursor是否为空
exitwhen my_cursor%notfound;
dbms_output.put_line(v_ename ||
', ' || v_sal);
endloop;
end;
控制结构
if then; if then else; ifthen elsif else;
createorreplaceprocedure
my_pro_if(namevarchar2)
is
v_salemp.sal%type;
begin
select salinto
v_sal from emp
where ename =
name;
--if block
ifv_sal <>
2000then
--update emp set sal = sal*1.1 whereename = name;
dbms_output.put_line(v_sal);
endif;
end;
循环语句 –loop
createorreplaceprocedure
my_pro_loop(numnumber)
is
v_numnumber :=
num;
begin
loop
dbms_output.put_line('loop number: ' || v_num);
exitwhen v_num =
0;
v_num := v_num - 1;
endloop;
end;
-for循环
-- in代表num是一个输入参数,默认是in,
out代表输出参数
createorreplaceprocedure
my_pro_for(num innumber)
is
begin
-- for block, reverse is optional
for i
inreverse1..num
loop
dbms_output.put_line('loop number: ' || i);
endloop;
end;
-goto,不建议使用
goto lable;
<<lable>>
-null null语句是一个空语句,什么都不干
null;
用Java调用有返回值的procedure
cs.registerOutParameter(2, oracle.jdbc.OracleTypes.VARCHAR);
cs.execute();
Stringname = cs.getString(2);
用Java调用返回值为cursor的procedure
--返回结果集的过程
--创建一个包
createorreplacepackage
my_pack_out as
typemy_cursor
isrefcursor;
end my_pack_out;
--创建过程
createorreplaceprocedure
my_pro_pack_out
(innoinnumber, outcursor
out my_pack_out.my_cursor)
is
begin
openoutcursor
forselect *
from emp
where deptno = inno;
end;
/*java */
cs.registerOutParameter(2, oracle.jdbc.OracleTypes.CURSOR);
cs.execute();
ResultSetrs = (ResultSet)cs.getObject(2);
用存储过程实现分页程序
--分页包
createorreplacepackage
divide_pages_pack as
typepack_cursor
isrefcursor;
end divide_pages_pack;
--分页过程
createorreplaceprocedure
divide_pages (
table_nameinvarchar2,
page_sizeinnumber,
--每页记录数
current_pageinnumber,
--当前页号
row_countoutnumber,
--总记录数
page_countoutnumber,
--总页数
out_cursorout divide_pages_pack.pack_cursor
) is
--起始页位置
v_beginnumber := (current_page -
1) * page_size +
1;
--结束页位置
v_endnumber := current_page * page_size;
begin
openout_cursor
for'select * from
(select a1.*, rownum rn from(select * from emp) a1
where rownum <= '|| v_end ||') a1 where rn >= '
|| v_begin;
--计算出总行数
executeimmediate'select count(*) from '
|| table_name into row_count;
ifmod(row_count, page_size) =
0then
page_count := row_count / page_size;
else
page_count := row_count / page_size +
1;
endif;
--关闭游标
--close out_cursor;
end;
视图
是一个虚拟表,其内容由查询定义。
视图与表的区别
1.表需要占用磁盘空间,视图不需要。
2.视图不能添加索引
3.视图有利于提高安全性
--创建视图:
--scott可能没有创建视图的权限,可以登录system用户更改权限。
grant create any view toscott;
createview myview
asselect *
from emp
where sal<
1000;
--可以加上 with
read only 只允许读数据
createorreplaceview
myview asselect *
from emp
where sal <
1000withreadonly;
--删除视图
dropview myview;
相关文章推荐
- oracle 11g 学习笔记10_29(2)
- oracle 触发器 学习笔记
- Oracle 学习笔记--入门篇
- Oracle 学习笔记(二)
- Oracle第一课(学习中笔记)
- oracle之alter学习笔记
- ORACLE DBA学习笔记--启动和关闭数据库
- Oracle 学习笔记(15)
- Oracle 9i/10g/11g编程艺术(2e)学习笔记【第6章】
- oracle PLSQL学习笔记--类型
- 数据库学习笔记2-oracle 数据库锁
- ORACLE DBA学习笔记--表空间的管理(tablespace)
- 倪蒙oralce学习笔记之Oracle创建删除用户、角色、表空间、导入导出数据库总结
- oracle 学习笔记
- oracle入门学习笔记
- Oracle--学习笔记
- Oracle 11g学习笔记--伪列
- 学习《Oracle 9i10g编程艺术》的笔记 (三)
- oracle 学习笔记 删除example表空间
- 学习《Oracle 9i10g编程艺术》的笔记 (六) 体系结构