Oracle基本知识点


                                              Oracle知识点

services.msc     打开服务器
grant to  给...授权
revoke from  给什么撤回权限

三部曲:
1、创建表空间
2、创建用户
3、授权(connect 连接,resource 开发权限)   grant...to
   撤回 revoke...from


* 增删查改  分页 标识列

创建表空间
创建用户
授权


数据文件:  .DBF
控制文件:  .CTL
日志文件:  .LOG


Package bodies
Triggers     触发器
Users   用户
Synonyms    同义词
Tablespaces  表空间   


1.not null 非空约束
2.primary key 主键约束
3.unique 唯一约束,值不能重复(空值除外)
4.check 条件约束,插入的数据必须满足某些条件
5.foreign key 外键


-----------主键约束
CREATE TABLE TB_01
(
       SID NUMBER PRIMARY KEY,--给学号添加主键约束
       SNAME VARCHAR2(22),
       SEX VARCHAR2(7)
);


-----------条件约束
CREATE TABLE TB_03
(
       SID NUMBER PRIMARY KEY,
       SNAME VARCHAR2(22),
       SEX VARCHAR2(7) CHECK(SEX BETWEEN '男' AND '女') --给性别添加条件约束
);


----------唯一约束

CREATE TABLE TB_04
(
       SID NUMBER PRIMARY KEY,
       SNAME VARCHAR2(22) UNIQUE,--给学生姓名添加唯一约束
       SEX VARCHAR2(7)
);


----------默认约束
CREATE TABLE TB_05
(
       SID NUMBER DEFAULT 1,
       SNAME VARCHAR2(22),
       SEX VARCHAR2(7)
);


----------非空约束
CREATE TABLE TB_06
(
       SID NUMBER,
       SNAME VARCHAR2(22) NOT NULL,--给姓名添加非空约束
       SEX VARCHAR2(7)
);


第二课

数据定义语言  DDL    (create创建  alter修改  drop删除)
数据操作语言  DML    (insert插入  select查询  delete删除  update修改)
事务控制语言  TCL    (commit提交  savepoint还原点  rollback回滚)
数据控制语言  DCL    (grant授权  revoke撤回授权)


Oracle数据类型的类别

                 
数据类型:字符    数值    日期时间   raw/longraw   lob
字符数据类型: char  varchar2  long
整数值:number  
日期: date    timestamp

*伪列:rowid  rownum (row下划线number)


Oracla内置函数
--S2重点
--求4-6条记录
select * from(
       select a.*,rownum rid from emp a
) b where b.rid between 4 and 6

--row_number()  over()
--求薪水在4-6位的员工
select * from(
       select a.*,row_number() over(order by sal desc) as rid from emp a
) b where b.rid between 4 and 6

第三课 内置函数
----1、转换函数
select sysdate from dual;  --获取系统当前时间
select systimestamp from dual; --更为精确


----2、日期函数
select add_months(sysdate,3) from dual;  --距离3个月之后的日期
select add_months(sysdate,-3) from dual;  --距离3个月之前的日期
select add_months(to_date('2008-08-08','yyyy-mm-dd'),3) from dual;

--求两个日期之间的月份差  前-后
select months_between(sysdate,to_date('2018-03-26','yyyy-mm-dd')) from dual;

--取年/月/日
select extract(year from sysdate) from dual;

--运用1;求二月份入职的员工
select * from emp where extract(month from hiredate)=2;

--运用2:求各个月份入职的员工人数
select extract(month from hiredate),count(*) from emp group by extract(month from hiredate);

--last_day   取本月的最后一天
select last_day(sysdate) from dual;

--取下一个星期六的日期
select next_day(sysdate,'星期六') from dual;

--round    只要过了12点就往后挪一天  四舍五入
select round(to_date('2008-08-08 16:11:11','yyyy-mm-dd hh24:mi:ss')) from dual;

--只截取年月日
select trunc(to_date('2008-08-08 16:11:11','yyyy-mm-dd hh24:mi:ss')) from dual;

--3、数学函数
--取大于它的最小整数
select ceil(34.56) from dual;

--取小于它的最大整数
select floor(34.56) from dual;

--取余数
select mod(11,15) from dual;
select round(345.678,2) from dual;--保留两位小数

--四舍五入
select round(345.678,-1) from dual;--是整数在后面四舍五入   是负数在前面四舍五入

--取指定位置的有效数字
select trunc(345.678,2) from dual;

--正数返回1  负数返回-1  0返回0
select sign(324) from dual;

--4、字符函数
--首字母大写
select initcap('iloveyou') from dual;
--全小写
select lower('ILOVEYyou') from dual;
--全大写
select upper('ILOVEYyou') from dual;

--去除左边指定字符
select ltrim('abcdefg','a') from dual;

--去除右边指定字符   不能隔一个去除
select rtrim('abcdefg','f') from dual;

--替换
select replace('iloveyou','i','she') from dual;

--从第五位开始找第一个d 位置
select instr('abcdefdg','d',5) from dual;

--从第二位开始截取5 位
select substr('dsfsdafagaa',2,5) from dual;

--拼接
select concat('laotie','傻了') from dual;

--取对应字符的ASCII 码 a :97  A:65  B:66
select ascii('a') from dual;

--取ASCII对应的字符
select chr(66) from dual;

--左填充    右填充
select lpad('abcd',7,'x') from dual;
select rpad('abcd',7,'x') from dual;

--求的是字符长度
select length('好好学习daydayup') from dual;

--取对应关系
select decode('a','a',1,'k','o',5675) from dual;
select decode('o','a',50,'k',34,'o',5725) from dual;

--综合运用
--如果员工的薪水大于3000 则输出‘需要纳税’  等于3000  输出‘刚刚好’  小于3000 ‘回去看牛’
select sal,decode(sign(sal-3000),1,'需要纳税',0,'刚刚好',-1,'回去看') from emp;

第四课  
--PL_SQL
声明部分、可执行部分和异常处理部分

控制结构:
    条件控制:if语句   case语句
    循环控制:loop循环   while循环   for循环
    顺序控制:goto语句    null语句

type  引用hiredate数据类型
towtype  行类型   引用emp的所有类型


第五课

游标 Cursor (-b-)

1.什么是游标?
2.游标的种类(属性、隐式/显示/REF)
3.如何创建游标
4.如何使用游标
5.动态语句拼接


===========================================

1.什么是游标?
游标(cursor)是数据库系统在内存中开设的一个数据缓冲区,存放SQL语句的执行结果。每个游标区都有一个名字,用户可以用SQL语句逐一从游标中获取记录,并赋给变量做进一步处理。

  --它是什么时候产生?    当执行DML SQL语句时;
  --它用来存放什么?    结果集;
  --它有名字吗?        有,SQL或用户给它取名;
  --它如何操作?        用Fetch语句逐一从游标中获取记录,并赋给变量进一步处理;
  --可以同时开几个?    可同时开多个,具体数量由数据库初始化参数OPEN_CURSORS定义。

  1.1 作用
      用于定位结果集的行。
      用来遍历结果集。

  1.2 特点
      一次提取一行给变量用于进一步处理。
      通过循环,将结果集都遍历完。

2.游标的种类
  游标分为静态游标(隐式和显式)和REF游标(+游标变量)。

  2.1 游标的状态
      %found    -- sql语句影响了一行或多行时为true;
      %notfound -- sql语句没有影响任何行时为true(常用,没找到为T,就退出)
      %rowcount -- sql语句影响的行数;
      %isopen   -- 游标是否打开,始终为false。


  2.2 静态游标:结果集已经确实(静态定义)的游标。
 
  (1) 隐式游标
      在PL/SQL中执行DML SQL(Insert/Delete/Update/Select)语句时自动创建;
      自动声明、打开和关闭,其名SQL(注:所有的隐式游标名都叫“SQL”);

  例示:使用游标的属性
    Begin
        Update emp Set sal=5000 Where empno=7369;
        If SQL%found Then
        dbms_output.put_line('表已更新');
        End if;
    End;

  提示:在Java中,如对表进行了增/删/改操作,结果会返回个int n,
    我们通过 n>0 或 n=0 来判断SQL代码是否执行成功。
    这个n 即SQL%RowCount属性。


  (2) 显示游标
      用于处理Select时返回多行的查询;
      增/删/改时不会用显示游标;
      需要手动的去做声明、打开、提取、关闭操作。

  例示:显示游标操作
    declare
    --①声明游标:划分存储区域,注意此时并没有执行Select语句。
    cursor c_name is
        select sal from emp where empno=7369;
    my_sal emp.sal%type;
    begin
        --②打开游标:执行select语句,获得结果集存到游标中,此时游标指向结果集头,而不是第一条记录。
        open c_name;
        --③获取记录:移动游标取一条记录
        fetch c_name into my_sal;
        dbms_output.put_line(my_sal);
        --④关闭游标:将游标放入缓冲池中,没有完全释放资源,可重新打开。
        close c_name;
    end;


  课堂练习:
    ㈠ 使用游标获取emp表中empno=7488的薪水;
    ㈡ 使用游标获取emp表中empno=7488的收入;
    ㈢ 使用游标获取emp表中所有记录;
    ㈣ 使用游标显示emp、dept表中员工编号、姓名、所在部门;


  --带参数的显示游标
    declare
    cursor c_name(dno number) is
        select * from emp where deptno=dno;
    my_a emp%rowtype;
    begin
        open c_name(10);  --打开游标,并传值
        loop
        fetch c_name into my_a;
        exit loop c_name%notfound;
        dbms_output.put_line('名字:'||my_a.ename);
        end loop;
        close c_name;
    end;


  --For循环游标
  作用:简化游标处理代码(简化打开、提取、关闭)。
  语法:
    for r_index in cursor_name loop
    ……
    end loop;

  例示:For循环游标操作
    declare
    cursor c_name is
        select * from emp;
    begin
        for i in c_name loop
        dbms_output.put_line(i.ename||'  '||i.job);
        end loop;
    end;

  注释:如同foreach语句一样,i默认为行类型(%rowtype),自动打开、提取、关闭。


  --带参数的For循环游标
    declare
    cursor c_name(dno number) is
        select * from emp where deptno=dno;
    begin
        for i in c_name(30) loop
        dbms_output.put_line(i.ename||'  '||i.job);
        end loop;
    end;

(!_0_!)大神提示:
    以上几种显示游标,For循环游标最为有效和简单;
    但在游标的使用方法上,推荐第一种,希望大家把游标的步骤理解清楚。


  --游标的嵌套问题
    固名思义,就是在游标中嵌套一个游标。

  例示:列出所有部门的人员信息。
    结果如下:
    部门号:10  部门名称:****
        编号:**    姓名:**
        编号:**    姓名:**
        ……
    部门号:20  部门名称:****
        编号:**    姓名:**
        编号:**    姓名:**
        ……

    分析:1.创建部门游标,先将部门信息列出来;
          2.在循环取部门信息时,再创建打开员工表游标,进行读取。

    代码:
    declare
    cursor mydc is select * from dept;
    mydr dept%rowtype;
    cursor myec(dno number) is select * from emp where empno=dno;
    myer emp%rowtype;

    begin
        open mydc;
        loop
        fetch mydc into mydr;
        exit loop mydc%notfound;
        dbms_output.put_line('部门号:'||mydr.deptno||' 部门名称:'||mydr.dname);

        --员工信息
        open myec(mydr.deptno);   --打开带参的游标
        loop
            fetch myec into myer;
            exit loop myec%notfound;
            dbms_output.put_line('  编号:'||myer.empno||'  姓名:'||myer.ename);
        end loop;
            close myec;
        end loop;
        close mydc;
    end;

  --用For循环游标简化
    declare
    cursor mydc is select * from dept;
    cursor myec(dno number) is select * from emp where empno=dno;
    begin
            for i in mydc loop
        dbms_ouput.put_line('部门号'||i.deptno||' 部门名称:'||i.dname);

        for j in myec(i.detpno) loop
            dbms_output.put_line('  编号'||j.empno||'  姓名:'||j.ename);
        end loop;

        end loop;
    end;


========================================================

  2.3 REF游标 + 游标变量
      REF游标也叫动态游标,动态SQL执行时产生;
      REF游标更应该被称之为游标类型,而游标变量则为该类型的游标

  (1) 创建REF游标+游标变量语法:
    type REF_CURSOR_NAME is REF cursor
    [return 返回类型];
    游标变量  REF_CURSOR_NAME;


      例示:创建个REF游标类型
        type ref_name is REF cursor;   --定义弱游标类型,名字叫ref_name
        c_name  ref_name;           --设定游标变量c_name为ref_name类型


  (2) REF游标分类:
      强类型----有return
      弱类型----无return
      相对来说,弱类型更为灵活。

      例示:声明强类型REF游标+游标变量
        declare
        type c_type is ref cursor
        return emp%rowtype;
        c_name  c_type;

 
  (3) 打开游标变量语法:
    open CURSOR_NAME for 查询结果集;

  --用REF游标+游标变量显示数据
    declare
    type my_t is ref cursor
    return emp%rowtype;        --声明一个游标类型
    myc my_t;            --定义一个REF类型的游标变量
    myr emp%rowtype;

    begin
        open myc for select * from emp;
        loop
        fetch myc into myr;
        exit when myc%notfound;
        dbms_output.put_line(myr.ename);
        end loop;
        close myc;
    end;


=================================================

游标变量的优点和限制:
1.游标变量功能强大,可以简化数据处理;
2.游标变量优点:
    a.可从不同的select语句中提取结果集;
    b.可以作为过程的参数进行传递;
    c.可以引用游标的所有属性;
    d.可以进行赋值运算;
3.游标变量的限制:
    a.不能在程序包中声明游标变量;
    b.for update子句不能与游标变量一起使用;
    c.不能使用比较运算符。


==================================================


5.动态语句拼接 :n
  设定一个游标变量来执行动态的sql语句。
  数据库管理员、设计师常用的知识点。

  语法:
    open 游标名 for 'select … :1 …';
    using 变量名;

  --例示:
    open c_name for 'select * from emp where sal>:1 order by sal desc'
    using p_sal;

    --sal>:1动态拼接(相当于JDBC中的?占位符)
    --将p_sal这个变量代入select中“:1”位置处
    --如有多个动态拼接处,请设置:2,:3,……,同时using 后面变量用逗号分隔。


  --例示:
    DECLARE
    r_emp emp%ROWTYPE;
    TYPE c_type IS REF CURSOR;
    cur c_type;
    p_salary NUMBER;

    BEGIN
        p_salary:=2500;
        OPEN cur FOR 'select * from emp where sal>:1 order by sal desc'
        USING p_salary;
        DBMS_OUTPUT.PUT_LINE('薪水大于'|| p_salary ||'的员工有:');

        LOOP
        FETCH cur INTO r_emp;
        EXIT WHEN cur%NOTFOUND;
        DBMS_OUTPUT.PUT_LINE('编号:'|| r_emp.empno||'姓名:'||r_emp.ename||'薪水:'||r_emp.sal);
        END LOOP;
          CLOSE cur;
    END;

猜你喜欢

转载自blog.csdn.net/cms18374672699/article/details/82597250