oracle基础部分学习笔记

     这部分是我在看视频和看《oracle四大宝典》时写下的一点笔记,写的比较乱和烂。主要学的是数据库开发方面的知识和整体的架构,非常基础的内容。

dSql*plus常用命令:

1、conn 用户名/密码@网络服务器名 [as sysdba/sysoper]当用特权用户登录是要使用as[]

2、Disc退出 3passw修改密码 4desc table 查表结构

3、Creat user xxx identified by ****创建用户

4、授权grant [系统角色权限] to [user]grant [对象权限] on [对象名] (字段名) to [user]  (with grant /admin option )权限传递下去

5、回收权限 revoke ......from ......级联回收的

6、创建profile锁定配置文件creat profile (filename) limit failed_login_attempts (count) password_lock_time (days) , alter user username profile (filename);

解锁:alter user username) account unlock 

Drop profile filename[cascade(删除相关的)]

Oracle数据类型:

Timestamp 精确到毫秒日期类型。

Char 比 varchar2 查询快很多

Blob 二进制数据类型 存放图片、视频、音频文件。

内嵌视图:

SQL> select * from t_student stu, (select avg(salary) as agv_sal,class_id from t_student group by class_id ) new where stu.salary  > new.agv_sal and stu.class_id = new.class_id; 

(select avg(salary) as agv_sal,class_id from t_student group by class_id ) new作为一个内嵌的视图,其实也是内嵌的一张表

子查询:

多行子查询:

All用法:SQL> select * from t_student stu where stu.salary > all(select a.salary from t_student a where a.class_id = 2 );

ANY用法:SQL> select * from t_student stu where stu.salary >= any(select a.salary from t_student a where a.class_id = 3 );

分页:一共有三种方式(挑选出23行数据)

1、rownum分页:select * from t_student

2、显示rownum[oracle分配的]

 SQL> select a1.*, rownum rn from (select * from t_student) a1;

3、用的二分的一种机制

SQL> select a1.*, rownum rn from (select * from t_student) a1 where rownum < 4 and rownum > 1;对不起在oraclerownum只认一次 行不通

正确方式:select * from (select a1.*, rownum rn from (select * from t_student) a1 where rownum < 4) where rn >= 2 ; 要指定查询列只需要修改红色部分

4、几个查询的变化:

A、要指定查询列只需要修改红色部分

B、排序同上修改SQL> select * from (select a1.*, rownum rn from (select stu.* , rownum rn1 from t_student stu order by stu.salary desc) a1 where rn1 < 4) where rn >= 2 ;

查询结果创建新表:

create table ss (VALUE_ID, VAR_NAME,CLASS_ID) as (select VALUE_ID, VAR_NAME,CLASS_ID from t_student);

create table ss as (select * from t_student);(复制整个表和数据)

合并查询:比andor这些操作快很多

1、union 取并集 select * from t_student where class_id = 2 union select * from t_student where value_id = 3;去掉重复部分

2、union all 不去掉重复的记录

3、intersect 取交集

4、minus取差集

创建新的数据库

1、使用工具:数据库配置工具

2、使用命令手工创建

Java编程操作oracle数据库使用jdbcodbc(不能操作连接远程只能本地),jdbc(能操作远程oracle数据库)使用sql包进行sql操作。

只读事务:

Set transaction read only;当前用户使用了只读事务,那么这个用户就只能查询到当前时刻的数据。

Sql函数:

1、字符函数

  lower(char)/upper(char):将字符串转换为小/大写 

  length(char)substr(char, m, n)取子串

首字母变小写其他变大写:

SQL> select lower(substr(var_name, 1, 1)) || upper(substr(var_name, 2, length(var_name))) from t_student;

repalce()替换函数

2、数学函数

  round(n, [m]):四舍五入保留m位小数

  trunc(n, [m]):截取数字

  mod(m, n):取余

  Floor(n):返回小于或等于n的最大整数

  Ceil():返回大于或等于的最小整数

3、日期函数

Oracle默认的日期格式是dd-mon-yy

Sysdate:返回系统时间

add_months(d,n):在某个日期上加上n个月

6个月前出生的人

SQL> select * from t_student where sysdate > add_months(date_bir, 6); 

last_months(month):返回指定日期在月份的最后一天

to_char():转换成指定格式的字符串

SQL> select * from t_student where sysdate > add_months(date_bir, 6);

系统函数:

1、sys_context()

参数:

terminal:当前会话客户所对应的终端标识符

language:语言

db_name:当前数据库名字

nls_date_formate:当前会话客户所对应的日期格式

Sessions_user:当前会话客户所对应的数据库名

Current_schema:当前客户所对应的默认方案名(一个用户对应一个方案)

Host:返回数据库所在的主机名

select sys_context('userenv', 'db_name') from t_student;

数据库管理:

1、sys用户:最高权限,拥有dba3)、sysdba1)、sysoper2)角色的权限。包括oracle数据库的基表、动态视图。不能以normal登录。

2、system用户:包含次级数据,有dbasysdba角色权限。如果以as sysdba就等同于sys用户

Sysdbasysoper的区别

数据库的逻辑备份与恢复:

1、只能在open状态下才能进行。

2、导出备份:

导出表结构:

Exp userid=scott/tiger@myoral tables=(emp, dept) file=d:\e1.dmp rows=n

直接导出:在最后加 direct=y;

导出方案:

1、exp userid=scott/tiger@myoral owner=scott file=d:\e2.dmp

2、System可以导出除sys以外任何方案

exp userid=system/manager@myoral owner=(system,scott) file=d:\e2.dmp导出2个方案

 导出数据库:

导入表:

导入方案:

数据字典:是数据库最重要的组成部分,包含数据库的一些系统信息,所有者是sys用户。

是只读表与视图的集合,在数据字典上只能执行查询,其维护与修改是有系统自动完成的。

就是有基表与动态视图(存放一些动态的数据)组成。数字字典视图类型user_xxxall_xxxdba_xxx三种类型。

动态性能视图:记载了例程启动后的相关信息

总结三者关系:

一个用户可以拥有多个角色,一个角色可以拥有多个权限。

select * from dba_roles;查询总共有多少个角色

select distinct  p.privilege from dba_tab_privs p;对象权限种数

Oralce表空间和数据文件:

1、oracle的逻辑结构包括表空间-->-->-->

2、表空间的作用:1、控制数据库占用的磁盘空间,其实就是能有效的使用磁盘空间

                 2dba可以将不同的数据部署到不同的位置,这样有利于提高IO性能,备份和管理等操作。怎么可以提高IO性能?本来要去读很多数据文件,但是可以直接读表空间就可以把所有的表空间的数据文件一次读出来。

3、建立表空间需要特权用户或者dba用户才可以。

 Create tbalespace (spacename) datafile'd:\*.dbf' size (<500M) uniform() size 20k;

4、使用表空间 creat table xxxx() tablespace (spacename);把表创建到指定的表空间,如果未指定就存在于system表空间中。

5、改变表空间的状态

 表空间脱机/联机/只读:alter tablespace 表空间名 offline/online/read only

6、删除表空间

Drop tablespace '表空间名' including contents and datafiles

Ps:查询表空间信息在dba_tablespaces表中查询,

查询数据文件在哪个表空间可以在dba_data_files中查询。

7、扩展表空间 

维护数据的完整性:三种方法:约束、触发器、应用程序。

约束:包括not nulluniqueprimary key(主键不能为空)、foreign key(外键)、check

create table goods(goodsId char(8) primary key,

  2  goodsname varchar2(30) not null,

  3  price num(10,2) check (price > 0),

  4  category varchar2(0),

  5  provider varchar2(30));

如果建表时忘记了加约束,使用alter table (tablename) modify (alumname) not null;

alter table (tablename) add constraint (约束名) unique(alumname);

删除约束:

创建索引:

create index name_index on t_student(var_name, var_id);

创建自定义角色:

SQL> creat role myrole not identified;

授权要用系统管理system以后才可以授权

SQL> grant creat session to myrole with admin option

SQL> grant delete on tablename to myrole;

将角色授予给用户:

SQL> grant myrole to username;

SQL> Drop role rolename

Java程序连接数据库实例

package com;

import java.sql.*;;

public class TestOracle {

/**

 * @param args

 */

public static void main(String[] args) {

// TODO Auto-generated method stub

Connection ct;

try{

//1、加载驱动

Class.forName("oracle.jdbc.driver.OracleDriver");

//2、得到连接

ct = DriverManager.getConnection("jdbc:oracle:thin:@10.153.98.18:1521:SZQX1","szidc","pwdidc");

//3、开始sql操作

Statement sm = ct.createStatement();

ResultSet rs = sm.executeQuery("select * from t_student");

//4、将查询的结果打印出来

while(rs.next()){

System.out.println(rs.getString(2));

}

//关闭资源

rs.close();

sm.close();

ct.close();

}

catch (Exception e){

e.printStackTrace();

}

}

}

Pl/sql编程

  1 create procedure hq_pro1 is 

  2  begin

  3  insert into t_student values(6, '清清', 3, to_date('19890613', 'yyyymmdd'), 10000, 19);

  4  end;

  5  /

如果编译报错:show error

如何调用该过程

1、exec 过程名 (参数1, 参数2.......;

2、call 过程名 (参数1, 参数2.......;

一个简单的块

 SQL> --声明一个变量

  1 declare v_name varchar2(100);

  2  begin

  3  select stu.var_name into v_name from t_student stu where    stu.value_id = 2;

  4  dbms_output.put_line('学生名字:' || v_name);

  5  end;

  6  /

 如果一次查询到多行把值给v_name这样是会报错的

一个整体的类JAVA流程的块

--声明一个变量

declare v_name varchar2(100);

begin 

--执行部分

select stu.var_name into v_name from t_student stu where stu.value_id = &no;

--在控制台显示

dbms_output.put_line('学生名字:' || v_name);

--例外处理

exception 

when no_data_found then

dbms_output.put_line('该学生不存在');

end;

一个过程实例

create or replace procedure hq_pro1(no numberis 

--声明一个变量

v_name varchar2(100);

begin 

--执行部分

update t_student stu set stu.var_name = '鸡鸡' where stu.value_id = no;

select stu.var_name into v_name from t_student stu where stu.value_id = no;

--在控制台显示

dbms_output.put_line('学生名字:' || v_name);

--例外处理

exception 

when no_data_found then

dbms_output.put_line('该学生不存在');

end;

JAVA中调用

package com;

import java.sql.*;

public class TestOracle {

   /**

 * @param args

 */

public static void main(String[] args) {

// TODO Auto-generated method stub

Connection ct;

try {

Class.forName("oracle.jdbc.driver.OracleDriver");

ct = DriverManager.getConnection("jdbc:oracle:thin:@10.153.98.18:1521:SZQX1""szidc""pwdidc");

CallableStatement cs = ct.prepareCall("{call hq_pro1(?)}");

cs.setInt(1, 2);

cs.execute();

cs.close();

ct.close();

catch (Exception e) {

// TODO: handle exception

e.printStackTrace();

}

}

}

--创建函数实例

create function fun1(no number) return number is 

ysal number(7, 2):=3000;

begin 

select 12*nvl(stu.salary , 0) into ysal from t_student stu where stu.value_id = no;

dbms_output.put_line('年工资=' || ysal);

return ysal;

end;

--pl\sql中执行

SQL> var salary number ;

SQL> call fun1(2) into:salary;

--java中调用

select fun1(2) from dual;

通过rs.getInt(1)获得返回值

--创建一个包

create package package_1 is 

--声明该包有一个过程和一个函数

procedure hq_pro1(no number);

function fun1(no numberreturn number;

end;

--给包实现包体

create package body package_1 is 

hq_pro1的实现部分

.....

Fun1的实现部分

.....

End;

调用包里面的函数or过程记得call 包名.函数名(参数)

开终端显示:

SQL> set serveroutput on;

2--创建表的组合变量类型

declare

--定义一个类似数组的表组合类型sp_tab_type,以整数作为下标

type sp_tab_type is table of t_student.var_name%type index by binary_integer;--以整数作为下标

--使用上面类型定义变量

sp_table sp_tab_type;

begin

select var_name into sp_table(0) from t_student where value_id = 2;

dbms_output.put_line('二班学生的名字:' || sp_table(0));

end;

--建一个包里面包含一个游标类型,就类似于java中的类

create or replace package test_package AS

type test_cursr is ref cursor;

end test_package;

--创建使用这个包中包体内容的过程

create or replace procedure test_procedure(v_class_id number,sp_cursor out test_package.test_cursr ) is

begin 

open sp_cursor for select stu.var_name from t_student stu where stu.class_id = v_class_id;

end;  

参照变量:

declare

--定义一个游标类型 

type sp_stu_cursor is ref cursor;

--定义一个游标类型的变量

test_cursor sp_stu_cursor;

v_name t_student.var_name%type;

v_id   t_student.value_id%type;

--执行 

begin 

open test_cursor for select stu.value_id, stu.var_name from t_student stu where stu.class_id = 2;

--循环  

(while可用来加条件)loop

     --取出游标中的内容

     fetch test_cursor into v_id, v_name;

     --退出循环条件

     exit when test_cursor%notfound;

     dbms_output.put_line('id号:' || v_id || '  学生名字:' || v_name);

end loop;

end;

--游标的另外一种定义方法

declare 

myrecord t_student%rowtype;

cursor tab_cur(v_id number) is select * from t_student t where t.value_id = v_id;

begin

open tab_cur(1);

loop

fetch tab_cur into myrecord;

exit when tab_cur%notfound ;

dbms_output.put_line(myrecord.value_id ||'  ,  '||myrecord.var_name); 

end loop;

close tab_cur;

end;

Goto语句

--编写一个分页过程,输入乘数参数表名、每页记录数、当前页,返回总记录数、总页数、结果集

 --创建一个包,包含一个游标类型

 create or replace package result_set as

 type table_cursor_type is ref cursor;

 end result_set;

 --创建过程

create or replace procedure pro_page

(v_tab_name in varchar2

v_page_record in number

v_cur_page in number

v_records out number

v_pages out number

res_cur out result_set.table_cursor_type) is

--定义变量

v_sql varchar2(1000);

v_begin number:=(v_page_record-1)*v_cur_page+1;--起始行数

v_end number:=v_page_record*v_cur_page;--结束行数

--执行部分

begin

--拼接sql语句,分页语句

v_sql:= 'select * from (select from (select stu1.*, rownum rn from '||v_tab_name 

||' stu1) stu2 where stu2.rn > '||v_begin

||') where rn <= '||v_end;

--把执行结果放到游标变量中

open res_cur for v_sql;

--拼接sql

v_sql:='select count(*) from'||v_tab_name;

--执行拼接好的sql语句

execute immediate v_sql into v_records; 

--注意取模不能用%

if mod(v_records, v_cur_page) = 0 then 

v_pages:=v_records/v_cur_page;--不能空格

else 

v_pages:=v_records/v_cur_page+1;

end if;

--关闭游标

close res_cur;

end;

declare

  cursor mycur is 

  select stu.var_name, cls.class_name from t_student stu ,t_class cls 

  where stu.class_id = 2 and stu.class_id = cls.class_id for update;

  v_myrecord t_student%rowtype;

  v_myclass  t_class.class_name%type;

begin

  open mycur;

  loop

       fetch mycur into v_myrecord.var_name, v_myclass;

       exit when mycur%notfound;

--视图的内容是改了是不会保存的,利用游标为判断条件

       update t_student stu set stu.class_id = 1 where current of mycur;

       dbms_output.put_line('名字: '||v_myrecord.var_name||'班级: '||v_myclass);

  end loop;

end;

游标的隐式游标

例外:预定义例外、非预定义例外、自定义例外

预定义例外:

No_data_found

declare v_name varchar2(100);

begin 

select stu.var_name into v_name from t_student stu where stu.value_id = &no;

dbms_output.put_line('学生名字:' || v_name);

--例外处理

exception 

when no_data_found then

dbms_output.put_line('该学生不存在');

end;

No_case_found

declare

      v_sal t_student.salary%type;

begin 

  select stu.salary into v_sal from t_student stu where stu.value_id=&nop;

  case  

  when v_sal<1000 then

  dbms_output.put_line('穷人');

  when v_sal<2000 then

  dbms_output.put_line('中资');

  end case;

exception

  when case_not_found then

  dbms_output.put_line('你们是富人');         

end;            for循环出再次打开

自定义例外:

declare

myexcp exception;

begin

       update t_student stu set stu.salary = stu.salary + 1000 where stu.value_id = &no

       --这是表示没有update

       if sql%notfound then

       --触发例外 

       raise myexcp;

       end if;

       exception

       when myexcp then

       dbms_output.put_line('没有更新');

end;

视图:

单表:create view myview as select * from t_student stu where stu.salary >3000;

双表:create or replace view myview1 as select stu.*, cls.class_name from t_student stu, t_class cls where stu.salary >3000 and cls.class_id = stu.class_id;

 

同义词:就是建立目标的一个别名。

公共:所有用户都可以使用

私有的:仅仅可以当前用户使用

Create or replace synonym stu for szidc.dept;

触发器

行级触发器

--创建一个删除触发器

create or replace trigger del_trig

after delete on t_class for each row

begin

delete from t_student where class_id = :old.class_id;

end del_trig;

触发器中常用的2个内存表,是增、删、改三个操作的暂存缓存

--更新操作触发器实例

create or replace trigger update_trig

after update of class_id on t_class for each row

begin

update t_student set class_id = :new.class_id where class_id = :old.class_id;

end;

触发器中不可以写rollback;那如果我们需要回退呢?

比如我们不允许删除某个记录,但是又不能回滚怎么办?

--抛出一个应用错误来实现

create or replace trigger del_trig

after delete on t_class for each row

begin

if :old.class_id = 2 then 

raise_application_error('-20000''不允许删除此记录');

end if;

end del_trig;

语句级触发器

不仅仅再是对某一行发生改变是做处理,而是只要你有某个动作就触发处理过程

create or replace trigger stu_trig

after delete or insert or update on t_student

begin 

if deleting then 

insert into log_tab values('删除成功!');

elsif inserting then

insert into log_tab values('插入成功!');

else

insert into log_tab values('更新成功!');

end if;

end;

--用触发器实现序列的功能

create or replace trigger stu_trig

before insert on t_student (for each row)--可以行级也可以语句级

declare

lid t_student.value_id%type;

begin

select max(value_id) into lid from t_student;

:new.value_id :=  lid + 1;

end;

替换触发器--只能操作视图

create or replace trigger myview_trig

instead of insert on v_myview for each row

Begin

Insert into t_student values(:new.value_id, :new.var_name, :new.class_id, :new.date_bir, :new.salary);

        insert into t_class values(:new.class_id, :new.class_name) ;

end;

INSTEAD OF 触发器更新视图 :

--创建一个视图

Create or replace view company_phone_book as 

Select first_name||', '||last_name name, email, phone_number, 

employee_id emp_id 

From hr.employees; 

尝试更新email和name 

update hr.company_phone_book 

set name='Chen1, Donny1' 

where emp_id=100 

create or replace trigger update_name_company_phone_book 

INSTEAD OF 

Update on hr.company_phone_book 

Begin 

Update hr.employees 

Set employee_id=:new.emp_id, 

First_name=substr(:new.name, instr(:new.name,',')+2), 

last_name= substr(:new.name,1,instr(:new.name,',')-1), 

phone_number=:new.phone_number, 

email=:new.email 

where employee_id=:old.emp_id; 

end; 

4、 系统事件触发器 

系统事件:数据库启动、关闭,服务器错误 

create trigger ad_startup 

after startup 

on database 

begin 

-- do some stuff 

end; 

alter trigger <trigger_name> disable; 

alter trigger <trigger_name> enable; 

事务处理: 

在触发器中,不能使用commit / rollback 

因为ddl语句具有隐式的commit,所以也不允许使用 

详细出处参考:http://www.jb51.net/article/18252.htm

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章