您的位置:首页 > 数据库 > Oracle

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;
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息