• Oracle


    本篇内容较多大家可以分几次看

    1.Oracle简介

    公司“甲骨文”,全球第一大数据库数据库厂商,第二大独立软件供应商

    一:发展史

    1970年    数据库起家

    1980年    ORACLE6版本

    1990年    ORACLE7版本,多元化产品,以数据库为优先发展方向

    1995年    ORACLE8版本

    1999年    ORACLE8i版本

    2001年    ORACLE9i release1

    2002年    ORACLE9i release2

    2003年    ORACLE10g版本

    2007年    ORACLE11g版本

    2009 年    甲骨文以每股9.5美元价格收购Sun公司总交易额74美元

    二:近些版本的特点

    Oracle10g

    1)支持网格计算(grid)达到负载均衡:多台节点服务器利用高速网络组成一个虚拟的高性能服务器,负载在整个网格中均衡,避免单点故障

    2)安装比9i工作量减少一半

    3)新增浏览器的企业管理器(Enterprise Manager

    Oracle11g

    .........

    Oracle12g

    ........

     

    2.Oracle安装

    一:系统要求(一般我们现在的电脑都满足这些条件)

    操作系统最好是windows server

    内存最好是256M

    硬盘空间最好是2G以上

    二:官网下的

    3.Oracle卸载

    一:停止所有与Oracle相关的服务

    二:使用OUIOracle Universal Installer)卸载Oracle软件。

     开始->程序->Oracle-OraDb110g_home1|Oracle installation product|Universal installer.

    三:删除注册表中的内容运行regedit命令,删除下面内容:

    HKEY_LOCAL_MACHINE|SOFTWARE|ORACLE注册表键,删除此键。

      HKEY_LOCAL_MACHINE|SYSTEM|CurrentControlSet|Services,删除Services键下所有以oracle为首的键。

    HKEY_LOCAL_MACHINE|SYSTEM|CurrentControlSet|Services|Eventlog|Application, 删除此键下所有以oracle为首的键。 

      HKEY_CLASSES_ROOT,删除此键下所有以OraOracleOrclEnumOra 为前缀的键。

      HKEY_CURRENT_USER|Software| Microsoft|Windows|CurrentVersion|Explorer|MenuOrder|Start Menu|Programs, 删除此键下所有以oracle为首的键。

      HKEY_LOCAL_MACHINE|SOFTWARE|ODBC|ODBCINST.INI注册表键,删除了Microsoft ODBC FOR ORACLE注册表键以外的所有有Oracle字样的键值。

      HKEY_LOCAL_MACHINE|SYSTEM|CurrentControlSet|Services,删除以OracleOraWeb为前缀的键。

    三:删除环境变量,PATH中含有Oracle的位置信息都删了

    四:文件系统中删除Oracle相关的文件与目录(app目录,CProgram FilesOracle

    如果C盘下的Oracle删不了重启计算机即可

    4.Oracle学习

    一:注意Oracle安装会自动的生成sys用户和system用户:

    sys用户是超级用户,具有最高权限,具有sysdba角色,有create database的权限,该用户默认的密码是change_on_install

    system用户是管理操作员,权限也很大。具有sysoper角色,没有create database的权限,默认的密码是manager

    一般讲,对数据库维护,使用system用户登录就可以拉

    也就是说syssystem这两个用户最大的区别是在于有没有create database的权限。

    二:管理工具

    Sql*plus

    在开始->程序->oracle oradb_home10g->application development->sql*plus

    在运行栏中输入: sqlplusw即可

    Sqlplus

    Dos下的Oracle管理工具功能与sql*plus相似

    在运行栏中输入 sqlplus;在oracle主目录ora10ginsqlplus.exe

    Pl/sql developer

    第三方软件,主要用于开发,测试,优化oracle

    Enterprise manager console(企业管理器)

    Web管理Oracle,一般端口号为11585500

    URLhttp://机器名:端口/em

     

    三:基本命令

    Sql*plus常用命令

    1)连接命令

    连接数据库:Conn[ection] 用户名/密码@网络服务名 [as sysdba[sysoper]]

    断开数据库:disc[onnect]

    修改密码:  passw[ord]

    退出:exit

    2)文件操作命令

    Start /@:运行sql脚本

    sql>@ d:a.sql或是sql>start d:a.sql

    Spool 将命令开始到spool off间的内容输出到指定文件中

    Sql>spool 要存放的文件地址(此时开始记录命令窗口中的命令)-spool off(存到指定文件的命令结束此时查看文件发现出现了很多命令)

    Edit:编辑sql文件

    3)交互式命令

    &可以弹出窗口让我们自己填

    Select * from emp where job=&job;

    Spool:将命令窗口中的命令存到指定文件中

    4)显示设置环境变量

    用来控制输出的各种格式如果希望永久的保存相关的设置,可以去修改glogin.sql脚本

    Linesize:set/show Linesize 查看设置输出一行宽度默认80

    Pagesize: set/show Pagesize 查看设置输出一页行数默认14

    4)用户管理

    注意:权限,角色,数据对象的解释

    权限分为系统权限,对象权限;系统权限:对数据库的相关操作(建用户,赋权限等),对象权限对数据对象的相关操作(select,insert,update,delete,all;

    角色是将权限封装在一起

    1)创建用户

    创建用户需要有dba权限才可以做(sys/system用户)

    A.简单方式

    Create user 名字 identified by 密码

    B.复杂方式

    Create user 名字 identified by 密码

    Default tablespace 默认表空间名

    Temporary tablespace 临时的表空间名

    Quota 最大用户可创建数据对象(表,索引,视图)

    2)修改密码

    自己修改密码没问题;别人修改密码需要有dba权限或者有修改用户的系统权限

    自己:Password 用户名

    别人:alter user 用户名 identified by 新密码

    3)删除用户

    Dba权限或者有alter user系统权限

    Dorp user 用户名【cascade】如果用户创建过表需要加上cascade

    4)赋权限

    希望xiaoming用户可以去查询emp
    希望xiaoming用户可以去查询scottemp
         grant select on emp to xiaoming
    希望xiaoming用户可以去修改scottemp
      grant update on emp to xiaoming
    希望xiaoming用户可以去修改/删除,查询,添加scottemp
      grant all on emp to xiaoming
    scott希望收回xiaomingemp表的查询权限
      revoke select on emp from xiaoming

    小明也想将对象权限(select on Scott.emp)分配给xiaohong

    Scott xiaoming赋权限时加with grant options

    grant select on emp to xiaoming with grant option;

    如果Scott将对象权限从xiaoming这撤销了,小红从xiaoming那获得对象权限也就没有了 

    5)使用profile管理用户口令

    Profile:是口令限制,资源限制的命令集合,当建立数据时,Oracle会自动创建default默认的profile文件,当创建用户如果没有指定profile,系统会默认指定defaultprofile文件

    A.账户锁定

    概述:指定scott用户最多只能尝试三次登录,锁定时间2

    SQL>create profile lock_account limit failed_login_attempts 3 password_lock_time 2;
    SQL> alter user scott profile lock_account; B账户解锁

    Alter user 被锁定的用户名 account unlock;

    C.终止口令

    概述:要用户每隔10天修改自家密码,宽限期2

    SQL> create profile myprofile limit password_life_time 10 password_grace_time 2;
    SQL> alter user 用户名profile myprofile;

    D.口令历史

    概述:当希望用户在修改密码时不使用以前的密码可使用口令历史,这样Oracle就会将口令的修改存到口令字典中,下次再更改密码时就会与旧密码作对照

    SQL>create profile password_history limit password_life_time 10 password_grace_time 2 password_reuse_time 10
    password_reuse_time //指定口令可重用时间即10天后就可以重用

    E.删除profile

              SQL> drop profile password_history casade
              注意:文件删除后,用这个文件去约束的那些用户通通也都被释放了。

              加了casade,就会把级联的相关东西也给删除掉

    ------------------------------------------休息一下------------------------------------------------

    四:表管理

      1)创建表

        Create table 表名(field1 datatype,field2 datatype)

        A:数据类型解析    

    分类 数据类型 说明
    文本,二进制类型

    char(20)

    varchar2(20)

    nchar(20)

    nvarchar2(20)

    clob(character large object)

    blob(binary large object)

     

    定长 最大2000字符

    变长 最大4000字符

    Unicode数据类型 ,定长 最大2000字符

    Unicode数据类型 ,变长 最大4000字符

    字符型大对象 ,最大8tb

    二进制数据 可以存放图片/声音 8tb

    数值类型 number(p,s)  p:整数位;s:小数位

    范围: 1 <= p <=38, -84 <= s <= 127 保存数据范围:-1.0e-130 <= number value < 1.0e+126 保存在机器内部的范围: 1 ~ 22 bytes

    时间日期

    data

    timestamp(n)

     包含年月日,时分秒。默认格式:DD-MON-YYYY。从公元前4712年1月1日到公元4712年12月31日的所有合法日期

    n的取值为0~9.表示指定TIMESTAMP中秒的小数位数。N为可选。如果n为0,timestamp与date等价[不推荐]

     

     

     

     

     

     

     

     

     

     

     

     

     

          

          表名和列的命名规则

            必须以字母开头

            长度不能超过30个字符

            不能使用oracle的保留字

            只能使用如下字符 A-Z,a-z,0-9,$,#等

        数值类型小习题:

          

           例子:

    1.创建两个表
    create table student (    ---表名 
              xh       number(4),   --学号 
              xm    varchar2(20),   --姓名 
              sex      char(2),     --性别 
              birthday date,         --出生日期 
              sal      number(7,2)   --奖学金 
    ); 
    --班级表 
    CREATE TABLE class( 
        classId NUMBER(2), 
        cName VARCHAR2(40) 
    ); 
    2.修改表
     添加一个字段
     alter table student add(classId number(2));
     修改一个字段长度
      alter table student modify(xm varchar2(30));
     修改字段类型或者名称(不能有数据)不建议这么做
      alter table student modify(xm char(30));
     删除一个字段 不建议这么做因为删了顺序就变了,加就没问题,加是加在后面
       alter table student drop column sal;
     修改表名 很少有这种需求
        rename table student to stu;
     删除表
        drop table student;
    3.添加数据
    所有字段都插入数据
    修改日期的默认格式(临时修改,数据库重启后仍为默认;如要修改需要修改注册表)
    修改后,可以用我们熟悉的格式添加日期类型:
    插入部分字段n 
    插入空值
    如果要查询student表中birthday为null的记录怎么写sql?
    4.修改数据
    用Update关键字
    5.删除数据
    Delete:删除数据结构还在数据还可以恢复因为它写日志所有速度慢,只需创建还原点savepoint a;处理的操作;rollback to a;
    drop:删除数和结构不写日志所以速度快,不能恢复
    
    

    五:查询

    新安装的数据库中scott用户拥有的表(emp,dept)我们可以那他们做例子

        1)oracle表基本查询    

    1.查看表结构
      desc emp;
    2.查询指定列
      这里值得一说的是distinct函数消除重复行
    3.打开显示操作时间的开关
      set timing on(测试后发现不能用不知道怎么回事)
    4.nvl,显示每个雇员的年工资
    思路:每位雇员每月可能还有奖金可能没有就出现null值解决null的问题就需要用到nvl函数了
    解决:select a.sal*13+nvl(a.comm,0) "年薪",a.ename,a.comm from emp a
    View Code
    5.like使用:%:表示0到多个字符  _:表示任意单个字符
    6.where条件中使用in
    SELECT * FROM emp WHERE empno in (7844, 7839,123,456); 
    7.is null
    SELECT * FROM emp WHERE mgr is null;
    8.order by 字段:排序默认asc
    问题:按照部门号升序而雇员的工资降序排列
    SELECT * FROM emp ORDER by deptno, sal DESC; 
      还可以使用列的别名来排序
    select ename, (sal+nvl(comm,0))*12 "年薪" from emp order by "年薪" asc; 
    9.clear清屏

      2)oracle复杂查询

    1.数据分组--max,min,avg,sum,count
    注意:select ename, max(sal) from emp;这语句执行的时候会报错,因为那里需要一样max是分组函数,ename不是
    2.group by 和having子句
      group by 对查询结果分组统计,having限制分组显示结果
        问题:如何显示每个部门的平均工资和最高工资?
    思路,每个部门明显分组用到group by
    select max(sal),min(sal),a.deptno from emp a group by a.deptno;
    View Code

       问题:显示每个部门的每种岗位的平均工资和最低工资?

    思路:每个部门的每种岗位两个分组
    select max(sal),min(sal) ,a.empno,a.job from emp a group by a.empno,a.job
    View Code

        问题:显示平均工资低于2000的部门号和它的平均工资?

    SELECT AVG(sal), MAX(sal), deptno FROM emp GROUP by deptno having AVG(sal) < 2000;
    View Code

     对数据分组的总结
      分组函数只能出现在选择列表、havingorder by子句中(不能出现在where)
      如果在select语句中同时包含有group by, having, order by 那么它们的顺序是group by, having, order by
      在选择列中如果有列、表达式和分组函数,那么这些列和表达式必须有一个出现在group by 子句中,否则就会出错。
        如SELECT deptno, AVG(sal), MAX(sal) FROM emp GROUP by deptno HAVING AVG(sal) < 2000;
        这里deptno就一定要出现在group by 中 

    3.多表查询 

      规定:多表查询的条件是 至少不能少于 表的个数-1 才能排除笛卡尔集

      问题:显示部门号为10的部门名、员工名和工资?

    思路:两表查询,两表建立连接,一个成员在莫一段位置
    select a.ename,a.sal,b.grade from emp a,salgrade b where a.sal between b.losal and b.hisal;
    View Code  

      问题:显示雇员名,雇员工资及所在部门的名字,并按部门排序?

     select a.ename,a.sal,b.dname from emp a,dept b where a.empno=b.deptno order by a.empno

      (注意:如果用group by,一定要把e.deptno放到查询列里面)

    4.自连接

      同一张表的连接查询

      问题:显示某个员工的上级领导的姓名?

    思路:这两表关键就是a表的mgr和b表ename要相同
    SELECT worker.ename, boss.ename FROM emp worker,emp boss WHERE worker.mgr = boss.empno AND worker.ename = 'FORD';
    View Code

    5.子查询 

      请思考:如何查询和部门10的工作相同的雇员的名字、岗位、工资、部门号 

    select * from emp where job in(select distinct job  from emp a where a.deptno=10)
    View Code 

      A:多行子查询

      在多行子查询中使用all操作符 

      问题:如何显示工资比部门30的所有员工的工资高的员工的姓名、工资和部门号?

    select * from emp a where a.sal>all(select sal from emp b where b.deptno=30 ) 
    View Code

      执行效率上, 函数高得多

      在多行子查询中使用any操作符

      问题:如何显示工资比部门30的任意一个员工的工资高的员工姓名、工资和部门号? 

    SELECT ename, sal, deptno FROM emp WHERE sal > ANY (SELECT sal FROM emp WHERE deptno = 30); 
    View Code

      B:多列子查询(查询结果多个列)多列多行查询的区别是:查询条件是一列和多列的区别

      请思考如何查询与SMITH的部门和岗位完全相同的所有雇员。 

    select * from emp a where (a.deptno,a.job)=(select deptno, job from emp where ename='SMITH' ) 
    View Code

      如何显示高于自己部门平均工资的员工的信息(很难的多想想)

    思路:看到这个题目一般大家都是蒙的,需要查分下,这里肯定是有子查询的,找到子查询,“自己部门平均工资”即可变为查询各个部门平均工资—》之后再原表与此表多表查询就很简单了
    select a.ename,a.sal,b.mysal from emp a,(select avg(sal) mysal,deptno from emp group by deptno) b where a.deptno=b.deptno and a.sal>b.mysal
    View Code

     注意:(给表取别名的时候,不能加as;但是给列取别名,是可以加as的) 

       3)分页查询

    按雇员的id号升序取出
    oracle的分页一共有三种方式
        1.根据rowid来分
          select * from t_xiaoxi where rowid in (select rid from (select rownum rn, rid from(select rowid rid, cid from t_xiaoxi order by cid desc) where rownum<10000) where rn>9980) order by cid desc;
        执行时间0.03
        2.按分析函数来分
          select * from (select t.*, row_number() over(order by cid desc) rk from t_xiaoxi t) where rk<10000 and rk>9980;
        执行时间1.01
        3.rownum来分
          select * from (select t.*,rownum rn from(select * from t_xiaoxi order by cid desc)t where rownum<10000) where rn>9980;
        执行时间0.1秒 

        应用最多的是rownum来分比较容易理解

    例如工资排序后查询6-10条数据

    select * from (select a.*,rownum rn from (select * from emp order by sal) a where rownum<=10) where rn>=6

    这里要先截取大行再封住小行从而获得分页效果

      4)自我复制数据(蠕虫复制)

    insert into mytable (id,name,sal,job,deptno)

    select id,name,sal,job,deptno from mytable;

    执行多次就能获得大数据

    6.合并查询

    多用于数据量大的合并多个查询结果

    unionunion allintersectminus

    Union:保留相同的;

    Union all:全部保留;

    Intersect:取得两个结果集的交集

    Minus:相当于做减法

    7.内连接外连接

    内连接:where两表查询就相当于内连接

    外连接:left jion,right jion,

    8.创建数据库实例

    1). 通过oracle提供的向导工具。
         database Configuration Assistant  【数据库配置助手】
      2).我们可以用手工步骤直接创建。

    ------------------------------------休息一下----------------------------------------------------

     

    1.java操作Oracle

     

    jdk从1.8开始,删除了jdbc-odbc桥,所以odbc的驱动是用不了的,建议重新安装jdk1.7或者更低的版本

    加载驱动之前需要导入jar包安装Oracle后在D:OracleappAdministratorproduct11.2.0dbhome_1jdbclib中找ojdbc.jar

    //加载驱动
    
    
    Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
    
    //得到连接
    
    Connection ct=DriverManager.getConnection("jdbc.odbc:testConnectOracle","scott","scott");
    
    
    //这里过后与SQL Server查询一样了
    
    Statement sm=ct.createStatement();
    
    ResultSet  rs=sm.executeQuery("select * from emp");
    
    while(rs.next()){
    
    System.out.println("用户:"+rs.getString(2));
    
    }

    再创建连接之前需要配置ODBC点击控制面板-->系统和安全-->管理工具-->数据源(ODBC),打开后点添加,如图:

    可以看到,有个Oracle in OraDb10g_home1的驱动,它e安装完后自动加上去的。 选中后,点完成,再填如下信息,如图:
    这样配好后基本就可以了,但为了安全起见,建议大家测试一下,点击 Test Connection按钮, 测试通过后点ok,然后数据源就生成了图:

    然后把数据源名称写进jdbc.odbc:里。

    这里要注意:jdbcodbc能不能远程连接呢?不能远程连接,也就是你这样写的话就意味着java程序和oracle数据库应该是在同一台机器上,因为这里没有指定IP地址,肯定默认就是本地。如果要远程连,就用jdbc,jdbc是可以远程连的。

    //jdbc模式可以远程连接的

    //加载驱动
    
    
    Class.forName("oracle.jdbc.driver.OracleDriver");
    
    //得到连接
    
    Connection ct=DriverManager.getConnection("jdbc:oracle:thin:@127.0.0.1:1521:orclbc:testConnectOracle","scott","scott");
    
    
    //这里过后与SQL Server查询一样了
    
    Statement sm=ct.createStatement();
    
    ResultSet  rs=sm.executeQuery("select * from emp");
    
    while(rs.next()){
    
    System.out.println("用户:"+rs.getString(2));
    
    }

    2.使用特定的格式插入日期值

    To_data(1998-09-12,YYYY-MM-DD)

    3.Oracle中的事务处理

    当执行事务操作时(dml语句),oracle会在被作用的表上加锁,防止其它用户修改表的结构。这里对我们的用户来来讲是非常重要的。
    .....其它进程排序,知道1号进程完成,锁打开,2号进程进入。依次进行,如果有进程级别较高的,可以插队。

    当执行用commit语句可以提交事务

    事务的几个重要操作n 
    设置保存点 savepoint a
    取消部分事务 rollback to a
    取消全部事务 rollback

    注意:这个回退事务,必须是没有commit前使用的;如果事务提交了,那么无论你刚才做了多少个保存点,都统统没有。
    如果没有手动执行commit,而是exit了,那么会自动提交

    例子:

    Connection ct=null;
    
    try {
    
    Class.forName("oracle.jdbc.driver.OracleDriver");
    
    
    ct = DriverManager.getConnection("jdbc:oracle:thin:@127.0.0.1:1521:orcl","scott","tiger");
    
    //加入事务
    
    ct.setAutoCommit(false);//设置默认不能提交
    
     
    
    Statement sm=ct.createStatement();
    
    sm.execute("update emp set sal=sal-100 where ename='SCOTT'");
    
    int i=7/0;
    
    //给smith的sal加上100
    
    sm.executeUpdate("update emp set sal=sal+100 where ename='SMITH'");
    
    ct.commit();//提交事务
    
    //关闭资源
    
    sm.close();
    
    ct.close();
    
    } catch (Exception e) {
    
    // TODO Auto-generated catch block
    
    try {
    
    ct.rollback();
    
    } catch (SQLException e1) {
    
    // TODO Auto-generated catch block
    
    e1.printStackTrace();
    
    }
    
    e.printStackTrace();
    
    }
    View Code

    设置只读事务

    set transaction read only;

     

    4.Oracle中的函数

    1)字符函数

    lower(char)

    upper(char)

    length(char)

    substr(char,m,n):取字符串的子串n代表取n个的意思

    replace(char1,search_string,replace_string)

    instr(char1,char2,[,n[,m]])取子串在字符串的位置

    2)数学函数

    cos,cosh,exp,ln, log,sin,sinh,sqrt,tan,tanh,acos,asin,atan,round,

    常用的:

    Round(n,[m]):四舍五入

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

    mod(m,n) :取m,n的模

    floor(n) 返回小于或是等于n的最大整数
     ceil(n) 返回大于或是等于n的最小整数

    对数字的处理,在财务系统或银行系统中用的最多,不同的处理方法,对财务报表有不同的结果

    3)日期函数

    默认情况下日期格式是dd-mon-yy 即12-7月-78

    Sysdata:放回系统时间

    Add_months(d,n)在d日期后加n个月后的日期

    last_day(d):返回指定日期所在月份的最后一天

    问题:查找已经入职8个月多的员工
    SQL> select * from emp where sysdate>=add_months(hiredate,8);
    问题:显示满10年服务年限的员工的姓名和受雇日期。
    SQL> select ename, hiredate from emp where sysdate>=add_months(hiredate,12*10);
    问题:对于每个员工,显示其加入公司的天数。
    SQL> select floor(sysdate-hiredate) "入职天数",ename from emp;
    or
    SQL> select trunc(sysdate-hiredate) "入职天数",ename from emp;
    问题:找出各月倒数第3天受雇的所有员工。
    SQL> select hiredate,ename from emp where last_day(hiredate)-2=hiredate;

    4)转换函数

    Oracle提供默认的转换但是默认的功能不足

    转换函数就能解决我们的问题了

    To_char()

    问题:日期是否可以显示 /分/秒
    SQL> select ename, to_char(hiredate, 'yyyy-mm-dd hh24:mi:ss') from emp;
    问题:薪水是否可以显示指定的货币符号
    SQL>


    yy:两位数字的年份 2004-->04
    yyyy:四位数字的年份  2004年
    mm:两位数字的月份 8月-->08
    dd:两位数字的天 30号-->30
    hh24: 8点-->20
    hh12:8点-->08
    mi、ss-->显示分钟秒

    9:显示数字,并忽略前面0
    0:显示数字,如位数不足,则用0补齐
    .:在指定位置显示小数点
    ,:在指定位置显示逗号
    $:在数字前加美元
    L:在数字前面加本地货币符号
    C:在数字前面加国际货币符号
    G:在指定位置显示组分隔符、
    D:在指定位置显示小数点符号(.)

    问题:显示薪水的时候,把本地货币单位加在前面
    SQL> select ename, to_char(hiredate, 'yyyy-mm-dd hh24:mi:ss'), to_char(sal,'L99999.99') from emp;
    问题:显示1980年入职的所有员工
    SQL> select * from emp where to_char(hiredate, 'yyyy')=1980;
    问题:显示所有12月份入职的员工
    SQL> select * from emp where to_char(hiredate, 'mm')=12;

    to_daten 
    函数to_date用于将字符串转换成date类型的数据。

      5)系统函数
        sys_contextn 
        terminal:当前会话客户所对应的终端的标示符
        lanuage: 语言
        db_name: 当前数据库名称
        nls_date_format: 当前会话客户所对应的日期格式
        session_user: 当前会话客户所对应的数据库用户名
        current_schema: 当前会话客户所对应的默认方案名
        host: 返回数据库所在主机的名称
        通过该函数,可以查询一些重要信息,比如你正在使用哪个数据库?
        select sys_context('USERENV','db_name') from dual;
        注意:USERENV是固定的,不能改的,db_name可以换成其它,比如select sys_context('USERENV','lanuage') from dual;又比如select sys_context('USERENV','current_schema') from dual;

    ------------------------------------休息一下---------------------------------------------

    5.数据库管理,表的逻辑备份与恢复

      

      最大区别:sysdba可以创建数据库,sysoper不可以创建数据库

      sysdba>sysoper>dba

      1)调试优化 数据库

        管理数据库参数可以调试数据库

      2) 显示初始化参数
        show parameter命令
           如何修改参数
        D:oracleadminmyoralpfileinit.ora文件中去修改比如要修改实例的名字

      3)数据库(表)的逻辑备份与恢复

        在导入和导出的时候,要到oracle目录的bin目录下

        A:导出:

          导出具体的分为:导出表,导出方案,导出数据库三种方式。
          导出使用exp命令来完成的,该命令常用的选项有:
            userid: 用于指定执行导出操作的用户名,口令,连接字符串
            tables: 用于指定执行导出操作的表
            owner        用于指定执行导出操作的方案
            full=y: 用于指定执行导出操作的数据库
            inctype: 用于指定执行导出操作的增量类型
            rows: 用于指定执行导出操作是否要导出表中的数据
            file: 用于指定导出文件名

          例子:

           导出表

    xp userid=scott/tiger@myoral tables=(emp,dept) file=d:e1.dmp 
    2.导出其它方案的表 
    如果用户要导出其它方案的表,则需要dba的权限或是exp_full_database的权限,比如system就可以导出scott的表 
    E:oracleora92in>exp userid=system/manager@myoral tables=(scott.emp) file=d:e2.emp 
    特别说明:在导入和导出的时候,要到oracle目录的bin目录下。 
    3. 导出表的结构 
    exp userid=scott/tiger@accp tables=(emp) file=d:e3.dmp  rows=n 
    4. 使用直接导出方式 
    exp userid=scott/tiger@accp tables=(emp) file=d:e4.dmp  direct=y 
    这种方式比默认的常规方式速度要快,当数据量大时,可以考虑使用这样的方法。 
    这时需要数据库的字符集要与客户端字符集完全一致,否则会报错... 
    View Code
    1. 导出自己的方案
      exp userid=scott/tiger@myorcl owner=scott file=d:scott.dmp
      2. 导出其它方案
      如果用户要导出其它方案,则需要dba的权限或是exp_full_database的权限,比如system用户就可以导出任何方案
      3.导出数据库

        exp userid=system/manager@myorcl owner=(system,scott) file=d:system.dmp

        增量备份(好处是第一次备份后,第二次备份就快很多了)

        B:导入

          imp常用的选项有
          userid: 用于指定执行导入操作的用户名,口令,连接字符串
          tables: 用于指定执行导入操作的表
          formuser: 用于指定源用户
          touser: 用于指定目标用户
          file: 用于指定导入文件名
          full=y: 用于指定执行导入整个文件
          inctype: 用于指定执行导入操作的增量类型
          rows: 指定是否要导入表行(数据)
          ignore: 如果表存在,则只导入数据

    exp userid=system/manager@myorcl full=y inctype=complete file=d:all.dmp
    
          1. 导入自己的表 
            imp userid=scott/tiger@myorcl tables=(emp) file=d:xx.dmp 
          2. 导入表到其它用户 
            要求该用户具有dba的权限,或是imp_full_database 
            imp userid=system/tiger@myorcl tables=(emp) file=d:xx.dmp touser=scott 
          3. 导入表的结构 
            只导入表的结构而不导入数据 
            imp userid=scott/tiger@myorcl tables=(emp) file=d:xx.dmp  rows=n 
          4. 导入数据 
            如果对象(如比表)已经存在可以只导入表的数据 
            imp userid=scott/tiger@myorcl tables=(emp) file=d:xx.dmp  ignore=y 
          导入方案n 
          导入方案是指使用import工具将文件中的对象和数据导入到一个或是多个方案中。如果要导入其它方案,要求该用户具有dba的权限,或者imp_full_database 
          1. 导入自身的方案 
            imp userid=scott/tiger file=d:xxx.dmp 
          2. 导入其它方案 
            要求该用户具有dba的权限 
            imp userid=system/manager file=d:xxx.dmp fromuser=system touser=scott 
            导入数据库n 
            在默认情况下,当导入数据库时,会导入所有对象结构和数据,案例如下: 
            imp userid=system/manager full=y file=d:xxx.dmp
    View Code

    6.数据字典和动态性能视图

      数据字典:有数据库的系统信息;动态视图:记载了历程启动后的相关信息

     

       数据字典记录了数据库的系统信息,它是只读表和视图的集合,数据字典的所有者为sys用户。
         用户只能在数据字典上执行查询操作(select语句),而其维护和修改是由系统自动完成的。
       这里我们谈谈数据字典的组成:数据字典包括数据字典基表和数据字典视图,其中基表存储数据库的基本信息,普通用户不能直接访问数据字典的基表。数据字典视图是基于数据字典基表所建立的视图,普通用户可以通过查询数据字典视图取得系统信息。数据字典视图主要包括user_xxx,all_xxx,dba_xxx三种类型。

     

        user_tables;n 
        用于显示当前用户所拥有的所有表,它只返回用户所对应方案的所有表
        比如:select table_name from user_tables;
          all_tables;n 
        用于显示当前用户可以访问的所有表,它不仅会返回当前用户方案的所有表,还会返回当前用户可以访问的其它方案的表:
        比如:select table_name from all_tables;
          dba_tables;n 
        它会显示所有方案拥有的数据库表。但是查询这种数据库字典视图,要求用户必须是dba角色或是有select any table系统权限。 

        例如:当用system用户查询数据字典视图dba_tables时,会返回system,sys,scott...方案所对应的数据库表。 

        1)用户名,权限,角色

          dba_users可以显示所有数据库用户的详细信息;
          dba_sys_privs,可以显示用户所具有的系统权限;
          ba_tab_privs,可以显示用户具有的对象权限;
          dba_col_privs可以显示用户具有的列权限;
          dba_role_privs可以显示用户所具有的角色。

        2)表空间

           建立数据表空间
          在建立数据库后,为便于管理表,最好建立自己的表空间
          create tablespace data01 datafile 'd: estdada01.dbf' size 20m uniform size 128k;
          说明:执行完上述命令后,会建立名称为data01的表空间,并为该表空间建立名称为data01.dbf的数据文件,区的大小为128k
          n 使用数据表空间 :create table mypart(deptno number(4), dname varchar2(14), loc varchar2(13)) tablespace data01;  

          使表空间脱机 :alter tablespace 表空间名 offline;
          使表空间联机 :alter tablespace 表空间名 online;
          只读表空间
          当建立表空间时,表空间可以读写,如果不希望在该表空间上执行updatedeleteinsert操作,那么可以将表空间修改为只读
          alter tablespace 表空间名 read only;
          (修改为可写是 alter tablespace 表空间名 read write;)

          删除表空间:drop tablespace ‘表空间’ including contents and datafiles;

          说明:including contents表示删除表空间时,删除该空间的所有数据库对象,而datafiles表示将数据库文件也删除。

          表空间扩展

          1. 增加数据文件
            SQL> alter tablespace sp01 add datafile ‘d: estsp01.dbf’ size 20m;
          2. 增加数据文件的大小
            SQL> alter tablespace 表空间名 ‘d: estsp01.dbf’ resize 20m;
            这里需要注意的是数据文件的大小不要超过500m
          3. 设置文件的自动增长。
            SQL> alter tablespace 表空间名 ‘d: estsp01.dbf’ autoextend on next 10m maxsize 500m; 

    7.约束  

      oracle中,约束包括:not null、 unique, primary key, foreign key,和check五种。

      例子:

    商店售货系统表设计案例n 
    现有一个商店的数据库,记录客户及其购物情况,由下面三个表组成:商品goods(商品号goodsId,商品名 goodsName,单价 unitprice,商品类别category,供应商provider); 
    客户customer(客户号customerId,姓名name,住在address,电邮email,性别sex,身份证cardId); 
    购买purchase(客户号customerId,商品号goodsId,购买数量nums); 

    请用SQL语言完成下列功能: 
    1. 建表,在定义中要求声明: 
    (1). 每个表的主外键; 
    (2). 客户的姓名不能为空值; 
    (3). 单价必须大于0,购买数量必须在1到30之间; 
    (4). 电邮不能够重复; 
    (5). 客户的性别必须是 男 或者 女,默认是男; 

    SQL> create table goods(goodsId char(8) primary key, --主键 
                goodsName varchar2(30), 
                unitprice number(10,2) check(unitprice>0), 
                category varchar2(8), 
                provider varchar2(30) 
         ); 
    SQL> create table customer( customerId char(8) primary key, --主键 
                name varchar2(50) not null,  --不为空 
                address varchar2(50), 
                email varchar2(50) unique, 
                sex char(2) default '' check(sex in ('''')), -- 一个char能存半个汉字,两位char能存一个汉字 
                cardId char(18) 
         ); 
    SQL> create table purchase( customerId char(8) references customer(customerId), 
                goodsId char(8) references goods(goodsId), 
                nums number(10) check (nums between 1 and 30) 
         ); 
    表是默认建在SYSTEM表空间的 
    View Code

    例子2

    如果在建表时忘记建立必要的约束,则可以在建表后使用alter table命令为表增加约束。但是要注意:增加not null约束时,需要使用modify选项,而增加其它四种约束使用add选项。 

    1. 增加商品名也不能为空 
    SQL> alter table goods modify goodsName not null; 
    2. 增加身份证也不能重复 
    SQL> alter table customer add constraint xxxxxx unique(cardId); 
    3. 增加客户的住址只能是’海淀’,’朝阳’,’东城’,’西城’,’通州’,’崇文’,’昌平’; 
    SQL> alter table customer add constraint yyyyyy check (address in (’海淀’,’朝阳’,’东城’,’西城’,’通州’,’崇文’,’昌平’)); 
    View Code

      1)删除约束

        当不再需要某个约束时,可以删除。

        alter table 表名 drop constraint 约束名称;
        特别说明一下:
        在删除主键约束的时候,可能有错误,比如:
        alter table 表名 drop primary key;
        这是因为如果在两张表存在主从关系,那么在删除主表的主键约束时,必须带上cascade选项 如像:
        alter table 表名 drop primary key cascade; 

      2)显示约束

        A.显示约束信息
          通过查询数据字典视图user_constraints,可以显示当前用户所有的约束的信息。
          select constraint_name, constraint_type, status, validated from user_constraints where table_name = '表名';
        B.显示约束列
          通过查询数据字典视图user_cons_columns,可以显示约束所对应的表列信息。
          select column_name, position from user_cons_columns where constraint_name = '约束名';
        C.当然也有更容易的方法,直接用pl/sql developer查看即可

      3)表级定义 列级定义
        A: 列级定义
          列级定义是在定义列的同时定义约束。
          如果在department表定义主键约束
          create table department4(dept_id number(12) constraint pk_department primary key,
          name varchar2(12), loc varchar2(12));
         B: 表级定义
          表级定义是指在定义了所有列后,再定义约束。这里需要注意:
          not null约束只能在列级上定义。
          以在建立employee2表时定义主键约束和外键约束为例:
          create table employee2(emp_id number(4), name varchar2(15),
          dept_id number(2), constraint pk_employee primary key (emp_id),
          constraint fk_department foreign key (dept_id) references department4(dept_id)); 

    ------------------------------------休息一下----------------------------------------------------

    11.pl/sql分类 -- 过程,函数,包,触发器

      标识规范:变量:v_;常量:c_;游标:_cursor;例外:e_开头的

      1)Pl/sal编程就是块编程

        pl/sql块由三个部分构成:定义部分,执行部分,例外处理部分。 

        如下所示:

    declare 
    /*定义部分——定义常量、变量、游标、例外、复杂数据类型*/ 
    begin 
    /*执行部分——要执行的pl/sql语句和sql语句*/ 
    exception 
    /*例外处理部分——处理运行的各种错误*/ 
    end; 
    定义部分是从declare开始的,该部分是可选的; 
    执行部分是从begin开始的,该部分是必须的; 
    例外处理部分是从exception开始的,该部分是可选的。 
    可以和java编程结构做一个简单的比较。

    例子:

    declare  
        --定义变量   
        v_ename varchar2(5);   
        v_sal  number(7,2);   
    begin  
        --执行部分   
        select ename,sal into v_ename,v_sal from emp where empno=&aa;   
        --在控制台显示用户名   
    dbms_output.put_line('用户名是:'||v_ename||' 工资:'||v_sal);   
        --异常处理   
    exception   
    when no_data_found then  
        dbms_output.put_line('朋友,你的编号输入有误!');   
    end;   
    
    View Code

      2)过程

        例子:

    创建:
    create or replace procedure sp_pro1 is  
    begin--执行部分   
    insert into mytest values('韩顺平','m1234');   
    end; 
    调用
    A:exec 过程名(参数值1,参数值2...); 
        B:call 过程名(参数值1,参数值2...);
    C:java中如何调用
    例子:
    import java.sql.*;   
    public class TestOraclePro{   
        public static void main(String[] args){   
               
            try{   
                //1.加载驱动   
                Class.forName("oracle.jdbc.driver.OracleDriver");   
                //2.得到连接   
                Connection ct = DriverManager.getConnection("jdbc:oracle:thin@127.0.0.1:1521:MYORA1","scott","m123");   
      
                //3.创建CallableStatement   
                CallableStatement cs = ct.prepareCall("{call sp_pro3(?,?)}");   
                //4.给?赋值   
                cs.setString(1,"SMITH");   
                cs.setInt(2,10);   
                //5.执行   
                cs.execute();   
                //关闭   
                cs.close();   
                ct.close();   
            } catch(Exception e){   
                e.printStackTrace();   
            }   
        }   
    }  
    View Code  

      3)函数

        函数用于返回特定的数据,当建立函数时,在函数头部必须包含return子句

    --输入雇员的姓名,返回该雇员的年薪   
    create function annual_incomec(name varchar2)   
    return number is  
    annual_salazy number(7,2);   
    begin  
        --执行部分   
        select sal*12+nvl(comm, 0) into annual_salazy from emp where ename=name;   
        return annual_salazy;   
    end;   
    / 
    如果函数创建有问题可以show error来查问题
    Pl/sql中调用函数
    SQLvar income number   
    SQL> call annual_incomec('scott') into: income;   
    SQL> print income  
    同样我们可以在java程序中调用该函数 
        select annual_income('SCOTT') from dual; 
        这样可以通过rs.getInt(l)得到返回的结果。
    View Code

      4)包

      逻辑上组合过程和函数,分为包规范包体两部分

    创建包:
    a.--创建一个包sp_package 
        b--声明该包有一个过程update_sal 
        c--声明该包有一个函数annual_income 
    Sql代码:
    create package sp_package is  
      procedure update_sal(name varchar2, newsal number);   
      function annual_income(name varchar2) return number;   
    end;  
    包的规范只包含了过程和函数的说明,但是没有过程和函数的实现代码。包体用于实现包规范中的过程和函数。 
        创建包体的Sql代码
    create or replace package body sp_package is  
      procedure update_sal(name varchar2, newsal number)    
      is  
      begin    
        update emp set sal = newsal where ename = name;   
      end;   
      function annual_income(name varchar2) return number is  
        annual_salary number;   
      begin  
        select sal * 12 + nvl(comm, 0) into annual_salary from emp   
         where ename = name;   
        return annual_salary;   
      end;   
    end;   
    /  
    调用包:都是调用包的成员call sp_package.update_sal('SCOTT', 1500); 
    View Code

      5)触发器

        常用的触发事件包括insert,update,delete语句,而触发操作实际就是一个pl/sql块。可以使用create trigger来建立触发器

    12.定义并使用变量,复合类型 

      标量类型,复合类型,参照类型,lob

     

      标识规范:变量:v_;常量:c_;游标:_cursor;例外:e_开头的

      1)标量类型(scalar)

        定义:name datatype [not null] [:=| default expr]

        其中datatype还可以用数据库表中列类型表示:emp.ename%type

        例子:

    例子:定义一个布尔变量,不能为空,初始值为false 
    v_valid boolean not null default false;
    SQL例子:
    declare  
      c_tax_rate number(3,2):=0.03;   
      --用户名   
      v_ename emp.ename%type;   
      v_sal number(7,2);   
      v_tax_sal number(7,2);   
    begin  
    --执行   
        select ename,sal into v_ename,v_sal from emp where empno=&no;   
    --计算所得税   
        v_tax_sal := v_sal*c_tax_rate;   
    --输出   
        dbms_output.put_line('姓名是:'||v_ename||'工资:'||v_sal||' 交税:'||v_tax_sal);   
    end;   
    /  
    View Code

      2)复合类型(composite)

        A:类似高级语言中的结构体,调用方式(类型名.成员名)

    例子:

    type emp_record_type is record(   
    
    
        name   emp.ename%type,   
    
    
        salary emp.sal%type,   
    
    
        title  emp.job%type);   
    
    
    --定义了一个sp_record变量,这个变量的类型是emp_record_type   
    
    
      sp_record emp_record_type;
    View Code

        B:类似高级语言中的数组,但是下标没有限制可以为负数

        C:嵌套表(nested table)

        D:变长数组

      3)参照类型(reference)

        游标变量(ref cursor)和对象类型变量(ref obj_type)

    A:游标变量
    例子:
    1.请使用pl/sql编写一个块,可以输入部门号,并显示该部门所有员工姓名和他的工资。 
        2.在1的基础上,如果某个员工的工资低于200元,就添加100元。 
    B:对象类型变量
    1.SQL
    declare  
    --定义游标sp_emp_cursor    
        type sp_emp_cursor is ref cursor;   
    --定义一个游标变量   
        test_cursor sp_emp_cursor;      
    --定义变量   
    v_ename emp.ename%type;    
    v_sal emp.sal%type;   
    begin  
    --执行   
    --把test_cursor和一个select结合   
    open test_cursor for select ename,sal from emp where deptno=&no;   
    --循环取出   
    loop   
        fetch test_cursor into v_ename,v_sal;   
        --判断是否test_cursor为空   
        exit when test_cursor%notfound;   
        dbms_output.put_line('名字:'||v_ename||' 工资:'||v_sal);   
    end loop;   
    end;   
    /  
    View Code

      4)lob(large object)

    13.pl/sql的进阶--控制结构(分支,循环,控制)

      1)三种分支语句:if—then,if – then – else,if – then – elsif – then 

      例子:编写一个过程,可以输入一个雇员名,如果该雇员的工资低于2000,就给该员工工资增加10%

    create or replace procedure sp_pro6(spName varchar2) is  
    --定义   
    v_sal emp.sal%type;   
    begin  
        --执行   
        select sal into v_sal from emp where ename=spName;   
        --判断   
        if v_sal<2000 then  
            update emp set sal=sal+sal*10where ename=spName;   
        end if;   
    end;   
    
    View Code

      2)循环

        A:loop循环语句以loop开头,以end loop结尾

    例子:案例:现有一张表users,表结构如下:
    用户id | 用户名
              |
    请编写一个过程,可以输入用户名,并循环添加10个用户到users表中,用户编号从1开始增加。

    create or replace procedure sp_pro6(spName varchar2) is  
    --定义  :=表示赋值   
        v_num number:=1;       
    begin  
        loop   
            insert into users values(v_num,spName);   
            --判断是否要退出循环   
            exit when v_num=10;   
            --自增   
            v_num:=v_num+1;   
        end loop;   
    end;   
    /  
    View Code

        B:while

        循环以while...loop开始,以end loop结束

    例子:

    案例:现有一张表users,表结构如下:
    用户id 用户名
    问题:请编写一个过程,可以输入用户名,并循环添加10个用户到users表中,用户编号从11开始增加。

    SQL:
    create or replace procedure sp_pro6(spName varchar2) is  
    --定义  :=表示赋值   
        v_num number:=11;       
    begin  
        while v_num<=20 loop   
        --执行   
           insert into users values(v_num,spName);   
           v_num:=v_num+1;   
        end loop;   
    end;   
    /   
    View Code

        C:for循环

    例子:
    begin  
      for i in reverse 1..10 loop   
        insert into users values (i, 'shunping');   
      end loop;   
    end; 
    View Code

    end; 

         D:顺序控制语句goto,null

          Goto:

          基本语法如下 goto lable,其中lable是已经定义好的标号名    

    例子:
    declare  
      i int := 1;   
    begin  
      loop   
        dbms_output.put_line('输出i=' || i);   
        if i = 1{} then  
          goto end_loop;   
        end if;   
        i := i + 1;   
      end loop;   
      <<end_loop>>   
      dbms_output.put_line('循环结束');   
    end; 
    View Code

          Null:类似于高级语句中的continue:直接将控制传递到下一条语句

    例子:
    declare  
      v_sal   emp.sal%type;   
      v_ename emp.ename%type;   
    begin  
      select ename, sal into v_ename, v_sal from emp where empno = &no;   
      if v_sal < 3000 then  
        update emp set comm = sal * 0.1 where ename = v_ename;   
      else  
        null;   
      end if;   
    end; 
    View Code

     ------------------------------------休息一下----------------------------------------------------

    14.PL/SQL分页

      一步一步来

      1)有返回值的存储过程完整例子(列表[结果集])

    例子:编写一个过程,输入部门号,返回该部门所有雇员信息。

    分析: 由于oracle存储过程没有返回值,它的所有返回值都是通过out参数来替代的,列表同样也不例外,但由于是集合,所以不能用一般的参数,必须要用pagkage了。所以要分两部分:
    A:创建一个包,在这个包中定义类型test_cursor游标
    create or replace package testpackage as  
      TYPE test_cursor is ref cursor;   
    end testpackage;
    B:创建存储过程
    create or replace procedure sp_pro9(spNo in number,p_cursor out testpackage.test_cursor) is  
    begin  
      open p_cursor for  
        select * from emp where deptno = spNo;   
    end sp_pro9;  
    
    最后在java中调用这个存储过程
    try{   
                //1.加载驱动   
                Class.forName("oracle.jdbc.driver.OracleDriver");   
                //2.得到连接   
                Connection ct = DriverManager.getConnection("jdbc:oracle:thin@127.0.0.1:1521:MYORA1","scott","m123");   
      
                //看看如何调用有返回值的过程   
                //3.创建CallableStatement   
                /*CallableStatement cs = ct.prepareCall("{call sp_pro9(?,?)}");   
      
                //4.给第?赋值   
                cs.setInt(1,10);   
                //给第二个?赋值   
                cs.registerOutParameter(2,oracle.jdbc.OracleTypes.CURSOR);   
      
                //5.执行   
                cs.execute();      
                //得到结果集   
                ResultSet rs=(ResultSet)cs.getObject(2);        
                while(rs.next()){   
                    System.out.println(rs.getInt(1)+" "+rs.getString(2));   
                }    
            } catch(Exception e){   
                e.printStackTrace();   
            } finally{   
                //6.关闭各个打开的资源   
                cs.close();   
                ct.close();   
            }   
    View Code

      2)编写分页过程

    Sql代码:
    select * from  
      (select t1.*, rownum rn from (select * from emp) t1 where rownum<=10)   
    where rn>=6
    开发一个包写存储过程
    create or replace package testpackage as  
      TYPE test_cursor is ref cursor;   
    end testpackage; 
    View Code

    开始编写分页的过程

    create or replace package testpackage as  
      TYPE test_cursor is ref cursor;   
    end testpackage;   
    --开始编写分页的过程   
    create or replace procedure fenye   
        (tableName in varchar2,   
         Pagesize in number,--一页显示记录数   
         pageNow in number,   
         myrows out number,--总记录数   
         myPageCount out number,--总页数   
         p_cursor out testpackage.test_cursor--返回的记录集   
        ) is  
    --定义部分   
    --定义sql语句 字符串   
    v_sql varchar2(1000);   
    --定义两个整数   
    v_begin number:=(pageNow-1)*Pagesize+1;   
    v_end number:=pageNow*Pagesize;   
    begin  
    --执行部分   
    v_sql:='select * from (select t1.*, rownum rn from (select * from '||tableName||') t1 where rownum<='||v_end||') where rn>='||v_begin;   
    --把游标和sql关联   
    open p_cursor for v_sql;   
    --计算myrows和myPageCount   
    --组织一个sql语句   
    v_sql:='select count(*) from '||tableName;   
    --执行sql,并把返回的值,赋给myrows;   
    execute inmediate v_sql into myrows;   
    --计算myPageCount   
    --if myrows%Pagesize=0 then这样写是错的   
    if mod(myrows,Pagesize)=0 then  
      myPageCount:=myrows/Pagesize;   
    else  
      myPageCount:=myrows/Pagesize+1   
    end if;   
    --关闭游标   
    close p_cursor;   
    end;   
    /  
    View Code

    java测试 

    try{   
                //1.加载驱动   
                Class.forName("oracle.jdbc.driver.OracleDriver");   
                //2.得到连接   
                Connection ct = DriverManager.getConnection("jdbc:oracle:thin@127.0.0.1:1521:MYORA1","scott","m123");   
      
                //3.创建CallableStatement   
                CallableStatement cs = ct.prepareCall("{call fenye(?,?,?,?,?,?)}");   
      
                //4.给第?赋值   
                cs.seString(1,"emp");   
                cs.setInt(2,5);   
                cs.setInt(3,2);   
      
                //注册总记录数   
                cs.registerOutParameter(4,oracle.jdbc.OracleTypes.INTEGER);   
                //注册总页数   
                cs.registerOutParameter(5,oracle.jdbc.OracleTypes.INTEGER);   
                //注册返回的结果集   
                cs.registerOutParameter(6,oracle.jdbc.OracleTypes.CURSOR);   
      
                //5.执行   
                cs.execute();    
      
                //取出总记录数   /这里要注意,getInt(4)中4,是由该参数的位置决定的   
                int rowNum=cs.getInt(4);   
      
                int pageCount = cs.getInt(5);               
                ResultSet rs=(ResultSet)cs.getObject(6);    
      
                //显示一下,看看对不对     
                System.out.println("rowNum="+rowNum);   
                System.out.println("总页数="+pageCount);   
         
                while(rs.next()){   
                    System.out.println("编号:"+rs.getInt(1)+" 名字:"+rs.getString(2)+" 工资:"+rs.getFloat(6));   
                }    
            } catch(Exception e){   
                e.printStackTrace();   
            } finally{   
                //6.关闭各个打开的资源   
                cs.close();   
                ct.close();   
            }   
    运行,控制台输出: 
    rowNum=19 
    总页数:4 
    编号:7369 名字:SMITH 工资:2850.0 
    编号:7499 名字:ALLEN 工资:2450.0 
    编号:7521 名字:WARD 工资:1562.0 
    编号:7566 名字:JONES 工资:7200.0 
    编号:7654 名字:MARTIN 工资:1500.0 
    View Code

     

    15.例外处理

     

      例外分为预定义例外,非预定义例外和自定义例外三种

      预定义例外用于处理常见的oracle错误 

      非预定义例外用于处理预定义例外不能处理的例外
      自定义例外用于处理与oracle错误无关的其它情况 

      1)预定义例外

        预定义例外有20多个预定义例外

        1.case_not_found:when子句中没有包含必须的条件分支发生例外

        2.cursor_already_open:重新打开已经打开的游标时,会隐含的触发

        3.dup_val_on_index:在唯一索引所对应的列上插入重复的值

        4.invalid_cursor:当试图在不合法的游标上执行操作时

        5.invalid_number:输入的数据有误时

        6. no_data_found :当执行select into 没有返回行

        7.too_many_rows:当执行select into语句时,返回超过了一行

        8.zero_divide:执行2/0语句时,则会触发该例外

        9.value_error:执行赋值操作时,变量的长度不足以容纳实际数据

        10.其他预定义例外是出现在pl/sql中的而不是oracle中发生的

            Login_denied:用户非法登录

            Not_logged_on:没有用户登录执行dml操作

            Storage_error:超过内存空间

            Timeout_on_resource:等待资源超时

    --定义
    V_name emp.ename%type;
    Begin
    --
    Select ename into v_ename from emp where empno=%gno;
    Dbms_output.put_line(‘名字:’||v_ename)
    Exception
    When no_data_found then
    Dbms_output.putline(‘编号没有!’);
    /
    执行输入一个不存在的编号,回显:编号没有!
    View Code

      2)非预定义例外

        比如在pl/sql块中执行dml语句时,违反了约束规定等等很少有这样的例外

      3)自定义例外

        自定义例外与oracle错误没有任何关联,它是由开发人员为特定情况所定义的例外

        例子:请编写一个pl/sql块,接收一个雇员的编号,并给该雇员工资增加1000元,如果该雇员不存在,请提示。

    自定义例外 
    create or replace procedure ex_test(spNo number)   
    is  
    --定义一个例外   
    myex exception;   
    begin  
    --更新用户sal   
    update emp set sal=sal+1000 where empno=spNo;   
    --sql%notfound这是表示没有update   
    --raise myex;触发myex   
    if sql%notfound then  
    raise myex;   
    end if;   
    exception   
    when myex then  
    dbms_output.put_line('没有更新任何用户');   
    end;   
    /  --自定义例外create or replace procedure ex_test(spNo number)is
    测试
    SQL> exec ex_test(56); 
    View Code

    没有更新任何用户

     

    16 oracle的视图 

      1)视图与表的区别n 
        表需要占用磁盘空间,视图不需要
        视图不能添加索引(所以查询速度略微慢点)
        使用视图可以简化,复杂查询
        比如:学生选课系统
          视图的使用利于提高安全性
        比如:不同用户查看不同视图

     

      2)创建修改视图

     

        创建视图:create view 视图名 as select 语句[with read only]

     

        创建或修改视图:create or replace view 视图名 as select 语句[with read only]

     

        删除视图:drop view 视图名

     

        当表结构复杂的时候我们可以用视图!

     

      例子为简化操作,用一个视图解决 显示雇员编号,姓名和部门名称

     

    Sql代码

     

    create view myview2 as select emp.empno,emp.ename,dept.dname from emp,dept where emp.deptno=dept.deptno;  

     

    create view myview2 as select emp.empno,emp.ename,dept.dname from emp,dept where emp.deptno=dept.deptno;

     

    视图之间也可以做联合查

    17.查询优化

      1)尽量用EXISTS代替IN操作

      2)用NOT EXISTS 或者外链接代替NOT IN

        因为NOT IN 不能应用表索引

      3)尽量不用“<>”或者!=

      

    QTH1`7Z$)T_8}K64Z)9L{_L

  • 相关阅读:
    jdk1.8新特性
    linux centos虚拟机安装
    linux基本命令介绍
    JavaScript与Java的区别
    jQuery UI的基本使用方法与技巧
    jQuery Ajax 实例 ($.ajax、$.post、$.get)
    .NET批量大数据插入性能分析及比较
    .NET中的CSV导入导出(实例)
    jquery中push()的用法(数组添加元素)
    .net如何后台批量删除
  • 原文地址:https://www.cnblogs.com/xiaoping1993/p/oracle.html
Copyright © 2020-2023  润新知