Chinaunix首页 | 论坛 | 博客
  • 博客访问: 717301
  • 博文数量: 147
  • 博客积分: 6010
  • 博客等级: 准将
  • 技术积分: 1725
  • 用 户 组: 普通用户
  • 注册时间: 2008-08-22 10:36
文章分类

全部博文(147)

文章存档

2011年(1)

2010年(1)

2009年(35)

2008年(110)

我的朋友

分类: Oracle

2009-05-27 08:28:17

三个默认的用户和密码:
    sys    change_on_install  [as sysdba]
    system manager
    scott  tiger
启动:
   监听程序:lsnrctl start
   数据库实例:oradim -startup -sid orcl
   登陆:sqlplus / as sysdba
创建用户:
    create user lisi indentified by lisi;
系统权限:
    grant create session to lisi;
    grant create table to lisi;
    grant unlimited tablespace to lisi;
    revoke create session from lisi;
    grant create any table to public;//把session权限授权给所有用户
    select * from user_sys_privs;//查看当前用户有哪些系统权限  【数据字典】
    select * from user_tab_privs;//查看当前用户有哪些对象权限set linesize 400;设置行的宽度
    select * from user_col_privs;//查看当前用户有哪些对象权限(权限控制到列)
     注意:查询和删除不能控制到列
     
    
对象权限:
    grant select on mytab to lisi;  
    grant all on mytab to lisi;
    grant update(name) on mytab to lisi;//把更新name列的权限授权给lisi(将权限限定到列)
    (update wuangwu.mytab set name='lihuoming' where id=1;)
    grant insert(id)  on mytab to lisi;
   
    revoke select on mytab from lisi;
    alter table mytab add name varchar(10);//修改表结构
    oracle默认的是手动提交数据(commit)

   ddl:数据定义语言(创建,修改表)
 dml:数据操纵语言(插入,删除,更新等)需要提交
 dcl:数据控制语言(授权和撤销权限)
权限的传递:把权限给A,A在传递给B
show user;查看当前用户
sys把alter权限给lisi:grant alter any table to lisi;
默认lisi不能把alter权限给wangwu
可以这样:grant alter any table to lisi with admin option;

对象权限传递:
sys创建表A,sys把查询的权限给lisi,但是lisi不能把该权限授给其他人
可以这样:grant select on A to lisi with grant option;
 

角色:
create role myrole;
grant create session to myrole;
grant create table to myrole;
create user zhangsan identified by zhangsan;
grant myrole to zhangsan;
drop role myrole;
有些系统权限不能够放在角色里面:
比如:grant unlimited tablespace to myrole;会出现无法将该权限放在myrole里面
只能直接将该权限给用户!
create any table的权限:不仅可以给自己创建表还可以给其他人创建表
不过要先给他赋予使用空间的权限
表是属于某一个用户的,角色不属于某个用户

丢失管理员密码:
比如普通用户的密码丢失了:sys登陆,然后alter user scott identified by 新密码
如果sys密码丢失:
  oracle三种验证机制:
      操作系统验证:
      密码文件验证:
      数据库验证:普通用户
      sys用户可以启动和关闭数据库,那么数据库没有启动sys就可以进入数据库里面去(但是监听和实例必须启动,否则会出现协议适配器错误),所以sys用户采用操作系统和密码文件验证
linux下oracle的启动过程
    lsnrctl start(监听程序)
    sqlplus sys/密码 as sysdba
    startup启动数据库实例
windows下oracle的启动过程
    lsnrctl start
    oradim -startup -sid orcl
conn / as sysdba为什么不写密码也能够进入数据呢???
         因为sysdba是操作系统验证,右击我的电脑,选择管理,组,双击ora_dba,在这个组里的 用户都是sysdba,所以不用密码,那么你可以将改组的用户给删除了,那么conn / as sysdba就不能进去了!
然后conn 用户名/密码 as sysdba就采用密码文件验证
为了安全应该删除操作系统验证,那么只能采用密码文件验证,如果密码忘记了.......
   密码文件在d:\database\PWDorcl.ora,可以先把他删除,然后在建立:
   orapwd file=d:\database\PWDorcl.ora password=123456 entries(允许在该文件中建立特殊用户的个数)=10
 
创建用户:
 create user abc
 indentified by abc
 default tablespace Users(默认表空间,存放用户的数据)
 Temporary Tablespace Temp(临时表空间,比如排序,将临时数据放在这个空间里面)
 Quota 50M on users(abc用户只能用50M表空间)
临时表空间上不能使用限额
限制用户:
  用户加锁:alter user 用户名 account lock
  用户解锁:alter user 用户名 account unlock
  注意:commit
用户口令失效:
   alter user 用户名 password expire
删除用户:
  drop user 用户名 [cascade强制删除用户下的所有文件]
 

中科院oracle视频:
1.oracle体系结构:
  a.实例和数据库
     .数据库实例也称为服务器,是指用于访问数据库文件集的存储结构(统称为SGA)和后台进程的集合,一个数据库可以被多个实例访问,数据库的物理结构和存储结构之间的关系是由后台进程来维持的,数据库拥有多个进程.........
     .数据库指的是一个数据容器,包含了表,索引,视图,过程,函数,包等对象,并对其进行统一管理,用户只有和一个确定的数据库连接,才能使用和管理该数据库中的数据,数据库的内部结构:表空间,表,列,分区,用户,索引,视图权限,角色,段,盘区,块等;外部结构有:控制文件(.ctl),日志文件(联机日志文件(redo01.log,第一个写满之后,写在第二个,然后写在第三个,然后再写在第一个,默认此时第一个文件被覆盖掉),归档日志文件是在进行热备份时候选择的日志文件格式),数据文件(.dbf).....
         控制文件管理和控制数据文件和日志文件,启动实例后-->启动控制文件-->打开数据文件
     .查看控制文件:
           DESC v$controlfile 
           select status,name from v$controlfile
     .查看数据文件:
           DESC v$datafile 
           select file#,name from v$datafile
     .查看日志文件:
           DESC v$logfile 
           select member from v$logfile
     .参数文件(并不是数据里面的有效组成部分,数据库启动时候参数文件不直接参与工作,不过控制文件是由参数文件来寻找的):
                         物理结构
                         参数文件
          控制文件                      控制文件

    数据文件     数据文件          日志文件     日志文件
                                   
  b.内存结构
      .当oracle的一个实例运行的时候,他分配了一个称为SGA(系统全局区)的大的内存块,实例的SGA被该实例的所有后台进程所共享,整个SGA的区里面有:数据库高速缓存池,大共享区,共享池,日志缓存池,固定SGA。
      .数据库高速缓存池:如果每执行一个sql查询的时候,oracle都从磁盘读取数据块,并且在改变之后,又必须把每一个数据块写入磁盘,那么oracle执行效率会非常慢,而oracle的缓存区经常能够使用内存里的数据块,在那里访问数据,内存中用来频繁访问数据的区域叫数据库的高速缓存池!数据库高速缓存池包括:默认缓存池(),保持缓存池(对于想在内存中长期保存的,频繁访问的使用该缓存池,这个缓存池在数据库关闭之前一直保留,并不释放内存空间),再生缓存池(想尽快从内存中排除的对象我们可以使用再生缓存池,例如频繁访问的大表,除此之外还可以考虑默认缓存池)!
      .共享池:主要由库缓存区和字典缓存区构成!用来缓存pl/sql的程序单元,sql语句的执行版本以及相关的执行计划。共享池的规模对于数据库的性能有着非常重要的影响!库缓存区中包括:PL/SQL区(保留了pl/sql的过程,函数等程序单元的编译版本,以便于所有的用户能够共享)和共享SQL区(保留了sql语句的解释版本,以便再次使用的时候,不用重新解释)
  
  c.逻辑结构
        .主要由块(block),盘区(extent),段(segment),表空间(tablespace)组成!
        .其中一个表空间对应一个或者多个数据文件,在物理结构时候,知道我们存储的对象信息,记录,数据都是存储在oracle的数据文件中的,但是在逻辑上,我们是将这些的表和表中的数据存储在表空间中
        .一个表空间可以包含多个段
        .段和物理的数据文件并不存在一一对应关系,一个段可能跨的不同的数据文件来存储
        .一个段可以包含多个盘区
        .一个盘区可以包含多个块
        .oracle存储数据的基本单位是块,windows下默认块的大小是8k,oracle的块大小一定是操作系统的块大小的整数倍
2.sql*plus基础
     .sys登陆必须以sysdba身份
     .startup启动数据库实例-打开控制文件-打开数据文件,参数mount(启动数据库实例的时候,打开控制文件,不启动数据文件),nomount(启动实例,连控制文件都不打开,一般在控制文件丢失的时候使用此参数,然后ALTER DATABASE MOUNT,alter databases open)
     .我们进行热备份的时候,是不允许进行非归档方式的!我们要修改在归档模式下进行热备份,但是在数据库已经启动的情况下是不允许修改的,那么我们只能先关闭数据库,关闭之后在启动实例startup mount打开控制文件,但是不能打开数据文件,然后:alter databases archivelog 然后alter databases open
     .关闭:shutdown immediate(迫使每个用户执行完当前的sql语句后立即断开连接)/abort(强迫关闭数据库,很可能造成文件破坏)/transactional(迫使用户在当前执行完程序后,断开连接,终止实例,恢复破坏的文件和数据文件,不能同其他的数据库文件保持一致)
     .想使用oracle数据库,那么首先就得启动两个服务:一个是启动监听程序lsnrctl start,一个是启动实例oradim -startup -sid orcl
     .sql*plus也可以在浏览器中控制,建议使用这中方式
         
常用的一些sql*plus命令:
         保存缓存区的命令:save c:\oracle\test.txt
         编辑缓存区的命令:edit
         执行外部文件:@c:\oracle\test.txt
         查看外部文件:get c:\oracle\test.txt
         列出缓存区的命令:list
         再一次执行缓存区的命令:/
    查看命令的用法:? 命令
       对部门的名称给一个标签:col deprno Heading "编号"
       或者是格式化输出:col department format A10(显示10个字符)/999,999,999(整型的格式化)  heading "编号"
    设置报表:
       设置行宽:set linesize 50
       标题居中并且指定名称:ttitle center "我的主题" skip 1-(指的是报表空一行)
                             left "测试报表" right "页" -(指sql语句换一行写)
                             format 999 sql.pno skip 2(页和数字之间空2行)
      关闭标题:ttitle off
      报表的重要的命令:break和comp
                     重复的记录值显示一条:break on pub
                                          select * from book
                     统计:comp count lable "计数" of books_name(字段) on pub
   将数据保存起来:spool c:\orcle\test.txt
                   select * .....
                   spool off
     
3.sql语言基础:
   .语言分类:  DDL(数据定义语言):create,drop,alter DCL(数据控制语言):grant,revoke DML(数据操纵语言):select insert delete update
    .常用的系统函数:
       字符:
                查看字符个数select length('abcdef') from dual;
                截掉左边空格: select ltrim('abcdef') from dual;
                截掉右边空格: select rtrim('abcdef') from dual;
                截掉空格: select trim('abcdef ') from dual;
                查看字节个数:select lengthb('abcdef') from dual;
                取子字符串(从第二个位置取三个bcd):select substr('abcdef',2,3) from dual;
                右取三个:select substr('abcdef',length('abcdefg')-3+1,3)
        时间:
               查看当前时间:select sysdate from dual;                               select current_date from dual;
               设定当前时间的格式: alter session set nls_date_format='dd-mon-yyyy hh:mi:ss';
                当前日期为准,星期三是多少号:select next_day(sysdate,'星期三') from dual;
        转换类型:
                日期转换为字符串24小时制: select to_char(sysdate,'yyyy24-mm-dd hh:mi:ss') from dual;
                日期转换为字符串16小时制: select to_char(sysdate,'yyyy-mm-dd hh:mi:ss') from dual;
                字符串转化为日期:select to_date('12-3月-04') from dual;
                字符型转换为整型:select to_number('99') from dual;
         聚集函数:
                 sum:select sum(price) from books;
                 max:......
                 min:........
                 avg:平均值
                 count:count(*)表的行数count(price):字段的行数      
         其他:        
               查看当前登陆用户:select user from dual;                查看性别为男和女分别有多少人:select sum(decode('sex','男',1,0)),sum(decode('sex','女',1,0)) from e;    decode和if差不多
               select a1,nvl(a2,'没有输入') a2 from aa;            nvl查看是否为空值

分组语句:
   select pub,sum(price*qty) from books group by pub;       group by后面可以多于前面select中的字段,但是不能少!       
    聚集函数不能出现在where下面,只能用having
   select pub,sum(price*qty) from books group by pub having sum(price)>50;
模糊查询:   
    select * from aa where a1 like 'a_' 'a__' 'a%' '__a' '%a' '%a%';
连接查询:
    select eid 编号,ename 姓名,sex 性别,d.name 所在部门 from e,d where e.id=d.id
    内连接(完全匹配):
          select eid 编号,ename 姓名,sex 性别,d.name 所在部门 from e join d on e.id=d.id
    外连接(不完全匹配):
       左外连接:
          select eid 编号,ename 姓名,sex 性别,d.name 所在部门 from e,d where e.id=d.id(+)
       右外连接:
          select eid 编号,ename 姓名,sex 性别,d.name 所在部门 from e,d where e.id(+)=d.id
子查询:
   无关子查询:select * from e where id in (select id from d);
              select * from e where exists (select id from d);
   相关子查询:select * from e where id in (select id from d where id=e.id and id='03');
              select * from e where exists (select id from d where id=e.id);把符合的查询出来
              select * from e where not exists (select id from d where id=e.id);把不符合的查询出来
             
合并行数据:select eid,ename from e union select id,name from d;
选出都有的数据:select id from e intersec selct id from d;
每次插入多条记录:
 insert into e(eid,ename) select id,name from d;把另外一个表中的数据写入e表中,类型要匹配。
复制表:
create table tt as(select * from e);
 

4.PL/SQL基础
pl/sql块结构如下:
declare
   ...(变量声明)
begin
   ....(代码处理)
exception
   ....(异常处理)
end;
/
变量声明:
  赋予变量适当名称
  赋予变量正确的数据类型
  定义变量(标准,记录)
  控制变量范围
  变量长度范围:1~30
例子:
 Declare
 x varchar2(10);
 begin
 x:='this is..';
 DBMS_OUTPUT.PUT_LINE('x is'||x);
 END;
 /
让服务器的输出打开:set SERVEROUTPUT ON SIZE 10000
上面的DBMS_OUTPUT是个包
行注释:--
块注释:/*       */
赋初值:x varchar2(10):='abcde';
        x STRING(10):='abcde';
        y INTEGER:=123;
        y NUMBER:=123;
分支语句:
  if分支
    .....
  case分支
    case
    when....then...
    else
    end case
例子:
  declare
  a number;
  b varchar2(10);
  begin
  a:=2;
  if a=1 then
  b:='A';
  elsif a=2 then
  b:='B';
  else
  b:='C';
  end if;
  DBMS_OUTPUT.PUT_LINE('b is '||b);
  end;
  /

 declare
  a number;
  b varchar2(10);
  begin
  a:=2;
  case
  when a=1 then b:='A';
  when a=2 then b:='B';
  when a=3 then b:='C';
  else
  b:='others';
  end case;
  DBMS_OUTPUT.PUT_LINE('b is '||b);
  end;
  /
循环语句
   基本循环(Loop)
   LOOP
     ....
   END LOOP
   while循环
   while expression LOOP
     ....
   end LOOP;
   for循环
   for counter in [REVERSE] start_value..end_value LOOP
   .....
   end LOOP;
例子:
 DECLARE
 x number;
 begin
 x:=0;
 LOOP
 x:=x+1;
 if x>=3 then
 exit;
 end if;
 DBMS_OUTPUT.PUT_LINE('in:x='||x);
 end loop;
 end;
 /
 DECLARE
 x number;
 begin
 x:=0;
 while x<=3 LOOP
 x:=x+1;
 DBMS_OUTPUT.PUT_LINE('in:'||x);
 end loop;
 end;
 /
 
 begin
 for i in 1..5 LOOP
 DBMS_OUTPUT.PUT_LINE('i='||i);
 END LOOP;
 end;
 /
begin
 for i in reverse 1..5 LOOP
 DBMS_OUTPUT.PUT_LINE('i='||i);
 END LOOP;
 end;
 /
DECLARE
 x number;
 begin
 x:=0;
 <>
 x:=x+1;
 DBMS_OUTPUT.PUT_LINE(x);
 if x<3 then
  GOTO repeat_loop;
 end if;
 end;
 /
异常处理:
 异常结构:
  EXCEPTION
  when...then
  .....
例子:
DECLARE
 test varchar2(10);
 begin
 select name into test from  deptment where id='tt';
 DBMS_OUTPUT.PUTLINE(test);
 exception
 when no_data_found then
 DBMS_OUTPUT.PUTLINE("没有数据");
 end;
 /
常见系统预定义异常
  ZERO_DIVIDE 发生被零除
  DUP_VAL_ON_INDEX:向有唯一约束的表中插入了重复行
  NO_DATA_FOUND:在一个select into语句中没有返回值
  TOO_AMNY_ROWS:select into语句返回了多行
  VALUE_ERROR:一个算法,转换,截断或大小约束发生错误
自定义异常:
 declare
 tname varchar2(10);
 e exception;
 begin
 select name into tname from deptment where id='01';
 if tname<>'b部门' then
 raise e;
 end if;
 DBMS_OUTPUT.PUTLINE(tname);
 exception
 when e then
 DBMS_OUTPUT.PUTLINE("错误");
 end;
 /
复合变量:记录
 记录是有几个相关值构成的复合变量,常用于支持select语句的返回值,使用记录可以将一行数据看成一个单元进行处理,而不必将每一列单独处理
记录的声明:
TYPE type_name IS RECORD(
Variable_name datatype[,
Variable_name datatype[,
......
);
real_name type_name;
例子:
declare
 type myrecoder id record(
 id varchar2(10),
 name varchar2(10)
 );
 real_record myrecord;
begin
 select emp_id,emp_name into real_record from emp where emp_id='001';
 DBMS_OUTPUT.PUTLINE(real_record.id||real_record.name);
end;
/
定义记录类型中的每一个变量和表中的类型和长度一样:
declare
 type myrecoder id record(
 id emp.eid%TYPE,
 name varchar2(10)
 );
 real_record myrecord;
begin
 select emp_id,emp_name into real_record from emp where emp_id='001';
 DBMS_OUTPUT.PUTLINE(real_record.id||real_record.name);
end;
/
定义记录类型和表中字段的类型和长度,个数一样:
declare
 myrec emp%ROWTYPE
begin
 select * into myrec from emp where emp_id='001';
 DBMS_OUTPUT.PUTLINE(myrec.eid||myrec.ename);
end;
/

PL/SQL高级应用
游标:是pl/sql控制结构,可以对sql语句的处理进行显示控制,便于对表的行数据进行处理
分类:隐士游标和显示游标
游标的属性:%FOUND %ROWCOUNT %ISOPEN %NOTFOUND
例子:
显示游标:
declare
 CURSOR mycur IS select * from books;
 myrecord book%ROWTYPE;
begin
 open mycur;
 fetch mycur into myrecord;//第一行数据
 while mycur%FOUND LOOP
 DBMS_OUTPUT.PUTLINE(myrecord.book_id||myrecord.book_name);
 fetch mycur into myrecord;
 end loop
 close mycur;
 end;
 /
显示游标带参数:
declare
 CURSOR mycur(id varchar2) IS select books_name from books where books_id=id;
 t_name books.books_name&TYPE;
begin
 open mycur('001');
 LOOP
 fetch mycur into t_name;//第一行数据
 exit when mycur%NOTFOUND;
 DBMS_OUTPUT.PUTLINE(myrecord.book_id||myrecord.book_name);
 end loop
 close mycur;
 end;
 /
第二种写法
declare
 CURSOR mycur(id varchar2) IS select books_name from books where books_id=id;
begin
 DBMS_OUTPUT.PUTLINE("*******结果集为:**********");
 for cur in mycur('001') LOOP
 DBMS_OUTPUT.PUTLINE(cur.book_name);
 end loop;
 end;
 /
ISOPEN用法:
declare
 CURSOR mycur(id varchar2) IS select books_name from books where books_id=id;
 t_name books.books_name&TYPE;
begin
 if mycur%ISOPEN then
  DBMS_OUTPUT.PUTLINE("游标已经被打开");
 else
  open mycur('001');
 end if;
 fetch mycur into t_name;//第一行数据
 close mycur;
 DBMS_OUTPUT.PUTLINE(t_name);
 end;
 /
ROWCOUNT的用法:
declare
 CURSOR mycur IS select from deptment;
 t_name varchar2(10);
begin
 open mycur;
 LOOP
 fetch mycur into t_name;
 exit when mycur%NOTFOUND or mycur%NOTFOUND IS NULL;
 DBMS_OUTPUT.PUTLINE('游标mycur的ROWCOUNT是:'||mycur%ROWCOUNT);
 END LOOP;
 close mycur;
 end;
 /
//如果没有做fetch的话,游标为null
利用游标修改数据
declare
cursor cur is select name from deptment for update;
text varchar2(10);
begin
open cur;
fetch cur into text;
while cur%FOUND LOOP
update deptement set name=name||'_t' where current of cur;
fetch cur into text;
end loop;
close cur;
end;
/
隐式游标:就是我们不需要open和close
begin
for cur in(select name from deptment) LOOP
DBMS_OUTPUT.PUTLINE(cur.name);
end loop;
end;
/
存储过程:
创建语法:
create [or replace] procedure procedurename
[(param1[{in|out{in out}] param1_type
[(param2[{in|out{in out}] param2_type
.......
is|as
..
begin
Proc_body;
end;
/
例子:
create or replace procedure myproc(id in varchar2)
is
name varchar2(10);
begin
select books_name into name from books where books_id=id;
DBMS_OUTPUT.PUTLINE(name);
end myproc;
/
查询存储过程错误:
show errors procedure myproc;
执行存储过程:
declare
tid varchar2(10);
begin
tid:='0001';
mypro(tid);
end;
/
或者
begin
myproc('0001');
end;
/
或者
execute myproc('0001');
输出参数的使用:
create or replace procedure myproc(id in varchar2,name out varchar2)
is
begin
select books_name into name from books where books_id=id;
end;
/
declare
tid varchar2(10);
tname varchar2(10);
begin
tid:='0001';
mypro(tid,tname);
DBMS_OUTPUT.PUTLINE(tname);
end;
/
6.视图,同义词,序列
视图实际是一条查询语句,是数据的显示方式
创建视图:
create or replace view myview
as
select * from books;
查询视图:
select * from myview;
插入:
insert into myview(books_id) values('0008');
那么book表中也插入了,视图中也插入

create or replace view myview
as
select * from books where price>30;
插入:
insert into myview(books_id,price) values('0008',23);
那么book表中插入了,视图中没有插入

create or replace view myview
as
select * from books where price>30 with check option;
插入:
insert into myview(books_id,price) values('0008',32);
如果插入的记录小于30的话,就不让插入了

两个以上的表:
create or replace view myview
as
select eid,ename,sex,d.id,d.name from emp e,deptment d where e.id=d.id;
插入:
insert into myview values('0008','abc','M','007','tt');出现错误
组成视图的两个以上的表,不能同时对两个表进行更新
让组成的视图只读,不能更新:
create or replace view myview
as
select eid,ename from emp with read only;
如果视图中含有聚合函数等也不允许更新!
查看用户视图:
select text from user_views where view_name='myview';
查看系统视图:
select text from dba_views where view_name='myview';
select text from all_views where view_name='myview';
 
同义词:可以方便的操纵不同用户模式下的对象
查看当前用户:select user from dual;
select * from dept;出错,因为dept是scott下的表
select * from scott.dept;正确,要加上模式
那么创建同义词可以解决上面的问题:
create synonym dept for scott.dept;这个是专有的
select * from dept;正确,如果换到其他的用户,在执行就会出现错误
创建公共的同义词,sys用户:create pulbic synonym dept for scott.dept;
删除:drop synonym dept;
查找当前用户的同义词
select synonym_name,table_name,table_owner from user_synonyms;
序列:(例如递增序列)
创建序列:
create sequence myseq
start with 1
increment by 1
order
nocycle;
查询
select myseq.nextval from dual;
select myseq.currval from dual;
写完nextval之后才能写currval
应用在表上:
create table auto(a number,b varchar2(10));
insert into auto vlaues(myseq.nextval,'dddd');
查询当前用户序列:
select sequence_name,sequence_owner from user_sequences;
更改递增量:alter sequence myseq increment by 3;
  
 

6.触发器:
创建触发器:
create or replace trigger del_deptid
after delete on deptment
for each row
begin
 delete from emp where id=:old.id;
end del_deptid;
/
create or replace trigger del_deptid
after insert on deptment
for each row
begin
 insert...values('kkk',:new.id);
end del_deptid;
/
上面的old和new表是在内存中的
我们对哪个表进行了delete那么old表就和他的结构一样
我们对哪个表进行了insert那么new表就和他的结构一样
插入数据时候先插入到new表中,然后在插入实际的表中
删除数据时候先把数据放在old表中,提交后在从old表中删除
insert涉及new表
delete涉及old表
update涉及old和new表
create or replace trigger del_deptid
after update on deptment
for each row
begin
 update emp set id=:new.id where id=:old.id;
end del_deptid;
/
create or replace trigger del_deptid
after delete on deptment
for each row
begin
 if :old.book_id='0001' then
   raise_application_error(-20000,'不允许删除');
 end if
end del_deptid;
/
触发器中不能写rollback也不能写DBMS_OUTPUT.PUTLINE
-20999~-20000可以写,以外的错误号就不可以写了!

上面的是行级触发器
下面的是语句级触发器:
先构造一个表:
create table mylog(curr_usre varchar2(100),curr_date date,act char(1));
创建触发器:
create or replace trigger dml_aa
after insert or delete or update on aa
begin
 if inserting then
   insert into mylog values(user,sysdate,'I');
 elsif deleting then
   insert into mylog values(user,sysdate,'D');
 else
   insert into mylog values(user,sysdate,'U');
 end if;
end;
/
语句级的不涉及到数据完整性的问题,只要做相应的语句动作就会触发,与行无关,无论多少行只要做了这个动作就触发!

替换触发器只能建在视图上面:
create or replace trigger tr_v_e_d
instead of insert on v_em_dept
for each row
begin
 insert into deptment values(:new.id,new:name);
 insert into emp(eid,ename,sex,id) vlaues(:new.eid,new.ename,:new.sex,:new.id);
end;
/
上面就是利用替换触发器解决视图的多表更新问题

7.表空间的管理
分配和管理表空间
 创建表空间可以在浏览器中创建:
 create tablespace tabs
 datafile 'D:\oracle\oradata\orcl\tabs.dbf' size 10M;
修改用户的默认表空间:
 alter user test default tablespace tabs;
 create unlimited tablespace,dba to test;
那么用户在创建表的时候,默认是在默认表空间中的!
可以指定表空间:
create table ..... tablespace tt;
就是将这个表放在tt表空间中!
8.表的管理:
 实体完整性通过主键来保证完整性
 域完整性是输入的数据要符合定义的类型
 参照完整性是外键
外键约束:
 alter tbale mm add constraint fk_mm foreign key(n1) references nn(n1);
check约束:
alter table emp add constraint ck_emp_sex check(sex='男' or sex='女');
查看当前用户模式下的约束:
select constraint_name,constraint_type from user_constraints where table_name='EMP';
索引:建立在表的字段上的
可以提高查询的速度
创建索引:
create index my_mm_idx on mm(m1);
索引建立在经常查询的字段上
创建位图索引:
create bitmap index bit_map on emp(sex)
这种索引是针对数据量很大,但是唯一值很少的类型数据,例如性别字段
9.SQL*Loader的使用:装载数据
准备好数据文件loader.txt:
abc,efg
def,rff
准备控制文件cont.ctl:
load data
infile 'c:\loader.txt'
append
into table scott.mm(
m1 position(1:3) char,
m2 position(5:7) char)
导入:sqlldr sys/password control=e:\cont.ctl data=e:\loader.txt
如果数据文件中:
abc,cde
dfsfdas,fd
那么控制文件:
oad data
infile 'c:\loader.txt'
append
into table scott.mm(
m1 char terminated by ",",
m2 char terminated by ",")
10.OEM的配置
11.监听程序和服务的配置
12.数据库备份与恢复
逻辑备份
    使用exp进行逻辑备份(将数据库中的数据写在文件中)
逻辑恢复
    使用imp进行逻辑恢复
物理备份
    冷/热备份
冷备份是脱机备份
热备份是联机备份
冷备份:
   停止备份:shutdown immediate
   拷贝:将d:\oracle\...\orcl文件夹拷贝到备份目录
热备份
   将日志改为归档方式(会把第一个日志文件备份到一个路径下,这个路径默认是(查看:archive log list):use_db_recovery_file_dest)
    设置:alter system set log_archive_start=true scope=spfile
    停止数据库:shutdown immediate;
    启动:startup mount;
    alter database archivelog;
    alter database open;
    进行备份:
    假定备份tt模式下的tt表空间:
    alter tablespace tt begin backup;
    然后拷贝tt表空间文件:d:\...\tt.dbf
    alter tablespace tt end backup;
    归档当前的联机日志:alter system archive log current;
    切换:alter system switch logfile;
    在切换:alter system switch logfile;
    停止数据库:shutdown immediate;
    如果我们删除tt.dbf
    然后启动:startup,就会出现错误提示
    解决:
       alter database datafile 6 offline drop;
       alter database open;
       将备份的文件拷贝到原来的路径下
       recover datafile 6(会出现提示选择auto);(6从错误提示中可以看出来)
       alter database datafile 6 online;
物理恢复
    冷热恢复

如果数据库中控制文件丢失:
  备份控制文件:alter database backup controlfile to trace(备份路径:d:\admin\orcl\udump\..时间最近的那个文件);
  找到控制文件的备份,拷贝到一个路径下面:create_rctl.txt
  停止数据库:shutdown immediate
  执行脚本:@c:..\create_rctl.txt
 
如果日志文件丢失:
 recover database until cancel;
 alter database open resetlogs;重新生产日志文件
 
 
 
 

总结:我们在安装oracle的时候,已经让我们新建立了一个数据库,每一个数据库都会有一个或者多个数据库实例来访问,这个数据库实例有个SID,来唯一标示这个数据库实例,默认名称和数据库名字一样!安装成功后,系统自带的用户可以登陆访问这个新建的数据库,默认的也是进入这个数据库!如果我想新建一个数据库,可以通过dbca来创建!系统用户访问不用的数据库,他的密码可以不一样!我们也可以通过sqlplus 这样的方式来让用户登陆到指定的数据库!
 
 

 用户解锁:alter user scott account unlock;
dual表是个特殊的表!
select 2*3 from dual;
这个表就是这个作用!

表达式中有一个为null,那么这个结果就会为null
例如:sal*12+comm
如果comm为null值,那么sal*12+comm结果为null
字符串连接:select ename||sal from emp;
数据库中表示字符串都是用单引号,如果字符串里有一个单引号了,那么:select ename||'sdfasf''fsafds' from emp;
就是用两个单引号代替一个单引号
去掉重复的deptno:
select distinct deptno from emp;
去掉重复的组合:
select distinct deptno,ename from emp;
就是这个组合重复了才去掉!
根据日期来查找:
select ename,sal,hiredate from emp where hiredate > '20-2月-1981';
日期的格式查看sysdate
姓名中有%的,要用注意字符
select ename from emp where ename like '%\%%';
我也可以换转移字符:
select ename from emp where ename like '%$%%' escape '$';

把aci码转换为字符:
select chr(65) from dual;
把字符转换为aci码:
select asci(A) from dual;
四舍五入:
select round(23.65) from dual;结果为24
select round(23.654,2) from daul;结果为23.65是保留到小数点后两位
转换为特定格式的字符串:
select to_char(sal,'$99,999.9999') from emp;
9表示1位数字,如果没有就不显示
$表示美元
L表示本地货币
0表示1位数字,如果没有就用0填充
日期转换:
select to_char(hiredate,'YYY-MM-DD HH:MI:SS') from emp;
select ename,hiredate from emp where hiredate>to_date('1981-2-20 12:34:56','YYYY-MM-DD HH24:MI:SS');
select ename,hiredate from emp where sal>to_number('$1,250.00','$9,999.99');
处理null值:
表达式中有一个为null,那么这个结果就会为null
例如:sal*12+comm
如果comm为null值,那么sal*12+comm结果为null
那么解决如下:
 select ename,sal*12+nvl(comm,0) from emp;
count某一个字段,如果这个字段不是null,就算1个
count(distinct deptno)
出现在选择列表里的字段,没有出现在组函数里面就必须出现在group by里面!
select deptno,max(sal) from emp group by deptno;
sql执行顺序:
select * from emp
where...
group by...
having...
order by...
按照关键字的先后顺序!先过滤---分组---限制组----排序--取出数据

取出前五行:
select * from emp where rownum<=5;
取出大于5行:
select * from (select rownum r,ename from emp) where r>10;
查看当前用户下面有多少张表:select table_name from user_tables;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
阅读(2460) | 评论(0) | 转发(0) |
0

上一篇:struts2视频总结

下一篇:linux视频总结

给主人留下些什么吧!~~