Oracle总结三

Posted 唐微港

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Oracle总结三相关的知识,希望对你有一定的参考价值。

PLSQL

数据类型

数据类型

  • Number 数字型
  • Int 整数型
  • Pls_integer 整数型,产生溢出时出现错误
  • Binary_integer 整数型,表示带符号的整数
  • Char 定长字符型,最大255个字符
  • Varchar2 变长字符型,最大2000个字符
  • Long 变长字符型,最长2GB
  • Date 日期型
  • Boolean 布尔型(TRUE、FALSE、NULL三者取一)
  • 在PL/SQL中使用的数据类型和Oracle数据库中使用的数据类型,有的含义是完全一致的,有的是有不同的含义的。

定义方式

基本数据类型定义方式

注意:声明是要放在declare和begin之间的,不能随便放在其他位置。

  • 变量名 类型标识符 [not null]:=值;
    declare
        age number(4):=10; --长度为4,初始值为10
    begin
        -- commit; 
    end;
常量数据类型定义方式
  • 常量名 constant 类型标识符 [not null]:=值;
 declare
        pi constant number(10):=3.1415926;--为pi的数字型常量,长度为10,初始值为3.1415926
    begin
        -- commit;
    end;

运算表达式

算术

+(加法)、-(减法)、*(乘法)、/(除法)、**(乘方)

例:

    set serveroutput on 
    declare
       res integer;
    begin
       res:=10+3*4-20+5**2;
       dbms_output.put_line('运算结果是:'||to_char(res));
    end;/

set serveroutput on 只需要申明一次即可,后续就不需要在申明

dbms_output只能输出字符串类型,所以需要将最终的结果转为字符串,而且需要在控制窗口运行而不是sql窗口!!!

字符

连接运算符 “||”

例:

   set serveroutput on 
   declare
    begin
       dbms_output.put_line('连接'|| '运算符');
    end;/

关系

< 小于
> 大于
= 等于(不是赋值运算符:=<= 小于等于
>= 大于等于
!= 不等于 或<>
like 类似于
in 在……之中
between 在……之间

注意:关系型表达式运算符两边的表达式的数据类型必须一致。

逻辑

  • NOT:逻辑非
  • AND:逻辑与
  • OR:逻辑或

注意:运算的优先次序为NOT、AND和OR。

申明类型

值拷贝(赋值)

set serveroutput on
declare
       v_number1 number := 100;
       v_number2 number;
   begin
       v_number2:=v_number1; --将v_number2的值直接赋值给v_number1
       v_number1:=200;
       dbms_output.put_line(v_number1); --200
       dbms_output.put_line(v_number2); --100
   end;

记录类型的record

定义一个组合record(),其中可以放多种类型的声明,这些类型可以通过组合名获取,有点类似于对象。使用的时候可以直接 组合名.变量名即可使用。

 set serveroutput on
 declare
       type t_first is record(
            id number(6),
            name varchar2(20)
       );
       -- 给表取别名为v_first,也可以直接使用表记录名
       v_first t_first; 
  begin
     v_first.id:=1022;
     v_first.name:='tang';
     dbms_output.put_line(v_first.id);
     dbms_output.put_line(v_first.name);
  end;

表类型变量table

type 表类型 is table of 类型 index by binary_integer;

类型可以是前面的类型定义,index by binary_integer子句代表以符号整数为索引,这样访问表类型变量中的数据方法就是“表变量名(索引符号整数)”。table类型,相当于java中的Map容器,就是一个可变长的数组,key(符号整数索引)必须是整数,可以是负数,value(类型)可以是标量,也可以是record类型。可以不按顺序赋值,但必须先赋值后使用。

  • 一维表类型变量
set serveroutput on
 declare
      type t_tb is table of varchar2(20) index by binary_integer;
      v_tb t_tb;
   begin
      v_tb(100):='hello';
      v_tb(98):='world';
      dbms_output.put_line(v_tb(100));
      dbms_output.put_line(v_tb(98));
   end;    
set serveroutput on
   declare
        type t_rd is record(id number,name varchar2(20));
        type t_tb is table of t_rd index by binary_integer;
        t_new t_tb;
   begin
        t_new(100).id:=1;
        t_new(100).name:='hello';
        --dbms_output.put_line(t_new(100).id);
        --dbms_output.put_line(t_new(100).name);
        dbms_output.put_line(t_new(100).id||'    '||v_tb2(100).name);
   end;
  • 多维表类型变量
 declare
      type tabletype1 is table of testtable%rowtype index by binary_integer;
      table1 tabletype1;
   begin
       select * into table1(60) from tempuser.testtable where recordnumber=60;
       dbms_output.put_line(table1(60).recordnumber||table1(60).currentdate);
   end;

%type和%rowtype

  • %type 为了让PL/SQL中变量的类型和数据表中的字段的数据类型一致,Oracle 9i提供了%type定义方法。这样当数据表的字段类型修改后,PL/SQL程序中相应变量的类型也自动修改。
  • %rowtype 是将一整张表的数据赋值给另一个表,然后就可以对表中的字段进行相应的操作

实例:

  1. 新建表和数据
    -- 新建一个简单的学生表
    create table student(
       STUDENT_NO number,
       STUDENT_NAME varchar2(20),
       STUDENT_AGE number(3,0),
       STUDENT_SEX varchar2(10)
    );
    
    -- 给表中插入一条数据
   insert into student(STUDENT_NO,STUDENT_NAME,STUDENT_AGE,STUDENT_SEX)           values(12301,'susu',23,'BOY');
  1. 使用%type查找单个字段
set serveroutput on
declare
       变量1 表名.字段1%type;
    begin
       select 字段1 into 变量1 from student where rownum=1;
       dbms_output.put_line(变量1);
    end;
set serveroutput on
declare
       v_name student.STUDENT_NAME%type;
    begin
       select STUDENT_NAME into v_name from student where rownum=1;
       dbms_output.put_line(v_name);
    end;
  1. 使用%type查找多个字段
declare
        变量1 表名.表字段1%type;
        变量2 表名.表字段2%type;
        变量3 表名.表字段3%type;
    begin
      select 表字段1,表字段2,表字段3 into 变量1,变量2,变量3 from 表名 where rownum=1;
      dbms_output.put_line(v_no||'  '||v_name||'  '||v_age);
    end;
declare
        v_no student.student_no%type;
        v_name student.student_name%type;
        v_age student.student_age%type;
    begin
      select student_no,student_name,student_age into v_no,v_name,v_age from student where rownum=1;
      dbms_output.put_line(v_no||'  '||v_name||'  '||v_age);
    end;
  1. 使用%rowtype赋值表

语法:

 set serveroutput on
    declare
       声明变量名 表名%rowtype;
    begin
       select * into 声明变量名 from 表名 where rownum=1;
       dbms_output.put_line(声明变量名.表字段||'  '||声明变量名.表字段||'  '||声明变量名.表字段);
end;
 set serveroutput on
    declare
       v_student student%rowtype;
    begin
       select * into v_student from student where rownum=1;
       dbms_output.put_line(v_student.student_no||'  '||v_student.student_name||'  '||v_student.student_age);
end;

注意:只有insert,update,delete,select 可以使用以上的两种方式。

流程控制

判断

if

语法:

declare
       flag boolean:=true;
begin if 条件 then
         dbms_output.put_line('ok');
      end if;
end;

例子:

declare
       flag boolean:=true;
begin if flag then
         dbms_output.put_line('ok');
      end if;
end;
if else

语法:

declare
        flag boolean:=true;
begin
     if 条件 then
        dbms_output.put_line('ok');
     else -- 不满足则
        dbms_output.put_line('false');
     end if; -- 结束判断
end;

例子:

declare
        flag boolean:=true;
begin
     if flag then
        dbms_output.put_line('ok');
     else
        dbms_output.put_line('false');
     end if;
end;
if elsif else

语法:

declare
        str varchar2(20):='tang';
begin
     if 条件 then
        dbms_output.put_line('tang');
     elsif 条件 then
        dbms_output.put_line('wei');
     else -- 不满足则
        dbms_output.put_line('gang');
     end if; -- 结束判断
end;

例子:

declare
        str varchar2(20):='tang';
begin
     if str='tang' then
        dbms_output.put_line('tang');
     elsif str='wei' then
        dbms_output.put_line('wei');
     else
        dbms_output.put_line('gang');
     end if;
end;

循环

loop

需要先申明变量

语法:

set serveroutput on
declare
       声明变量 binary_integer :=0;
begin
     loop
         exit when 声明变量>10; -- 满足条件就退出否则就继续执行
         声明变量 :=声明变量+1;
         dbms_output.put_line('hehe');
     end loop; -- 结束循环
         dbms_output.put_line('ok');
end;

例子:

set serveroutput on
declare
       num binary_integer :=0;
begin
     loop
         exit when v_i>10;
         num :=num+1;
         dbms_output.put_line('hehe');
     end loop;
         dbms_output.put_line('ok');
end;
while

需要先申明变量

语法:

declare
       申明变量 binary_integer:=0;
begin
       while 申明变量<10 loop -- 满足条件继续执行
             dbms_output.put_line('hello'||num );
             申明变量:=申明变量+1;
       end loop; -- 结束循环
       dbms_output.put_line('over');
end;

例子:

declare
       num binary_integer:=0;
begin
       while num<10 loop
             dbms_output.put_line('hello'||num );
             num:=num+1;
       end loop;
       dbms_output.put_line('over');
end;
for

不需要申明变量

语法:

begin
     for 任意标识 in 待循环值 loop -- 开启训话标志
         dbms_output.put_line('hello'||i);
     end loop; -- 结束循环标志
         dbms_output.put_line('循环结束');
end;

例子:

begin
     for i in 0..10 loop
         dbms_output.put_line('hello'||i);
     end loop;
         dbms_output.put_line('循环结束');
end;

异常

异常定义

  • 异常申明
异常名 EXCEPTION;
  • 抛出异常
 RAISE 异常名
  • 异常处理
exception
when 自定义抛出的异常名 then 
  dbms_output.put_line('sqlcode='||sqlcode);
  dbms_output.put_line('sqlerrm='||sqlerrm);
 when others then
   dbms_output.put_line('sqlcode='||sqlcode);
   dbms_output.put_line('sqlerrm='||sqlerrm);

异常分类

  • 内部异常

​ 又分为预定义异常(有错误号+常量定义) 和 非预定义例外 (仅有错误号,无常量定义)

1. 常见预定于异常

 ```sql

–- NO_DATA_FOUND (没找到数据)

–- TOO_MANY_ROWS (列数超过范围)

–- INVALID_CURSOR (初始化错误)

–- ZERO_DIVIDE (被除数不能为0)

–- DUP_VAL_ON_INDEX (重复键值)

– VALUE_ERROR (数据赋值错误)
```

演示实列:

set serveroutput on
declare
  v_result number(3);
begin
  v_result := 10 / 0; -- 模拟异常
  dbms_output.put_line('异常之后的代码将不再执行!'); -- 模拟异常后不再执行
  exception -- 异常体
  when zero_divide then
    dbms_output.put_line('被除数不能为0!');
    dbms_output.put_line(SQLCODE || '----' || SQLERRM);
  when others then
    dbms_output.put_line('其他未知异常');
  ROLLBACK;
end;
  • 自定义异常

演示实列

set serveroutput on
declare
  v_data number; -- 定义一个数字类型的变量
  v_myexp exception; -- 定义一个异常变量
begin
  v_data :=&inputData; -- 手动输入数据
if v_data>1 and v_data<100 then
  raise v_myexp; -- 满足条件就抛出异常
  dbms_output.put_line('模拟异常抛出后不在往下执行');-- 模拟异常抛出后不在往下执行
else
  dbms_output.put_line('输入数据超出范围');
end if; -- 结束判断
exception
when v_myexp then -- 当有自定义的异常被抛出时就执行以下的逻辑
  dbms_output.put_line('输入的数据在1~100之间');
  dbms_output.put_line('sqlcode='||sqlcode);
  dbms_output.put_line('sqlerrm='||sqlerrm);
end;

注意: 发生异常时,有时候希望了解当时发生的Oracle错误号和相关描述信息,Oracle 提供了两个内置函数 SQLCODE 和 SQLERRM 分别用来返回Oracle 错误号和错误描述。

  • 语法:
  declare
            异常名 exception; -- 申明异常
    begin
            dbms_output.put_line('hello');
            raise 异常名; -- 使用raise抛出异常,抛出后跳转到自定义的myException ,执行其里面的								逻辑处理,再跳到end处,结束PL/SQL块,raise接后面的语句不会继续执行。
            dbms_output.put_line('world');
            dbms_output.put_line(1/0);
    exception
            when 异常名 then -- 满足抛出的异常时执行
            	dbms_output.put_line('异常处理');
                dbms_output.put_line(sqlcode); --当前会话执行状态,错误编码
                dbms_output.put_line(sqlerrm); --当前错误信息
            when others then -- 不满足抛出的异常时执行
                dbms_output.put_line('error');
    end;

多异常处理

同时定义多个异常处理方式

set serveroutput on
declare 
    a int; 
    ex_1 exception;
    ex_2 exception;
    ex_3 exception;
begin
   a:=&inputData;
   if a=1 then
    raise ex_1;
   elsif a=2 then 
      raise ex_2;
   else
   	  raise ex_3;
    end if;
    
    exception
      when ex_1 then
         dbms_output.put_line('捕获错误1');
      when ex_2 then 
         dbms_output.put_line('捕获错误2');
      when ex_3 then 
         dbms_output.put_line('捕获错误3');
      end;

others异常处理

declare 
    a  int:=0; 
    ex_1 exception;
begin  
   if a=0 then
    raise ex_1;
    end if;
     
    exception 
      when others then
        dbms_output.put_line('捕获了全局错误');
 end;

游标

游标是一块内存区域,可以用以提高数据库数据处理速度。游标的工作机制是一种能从包括多行数据记录的结果集中每次提取一行记录的机制,即游标提供了在逐行的基础上操作表中数据的方法,有些许类似Java中迭代器。

游标的类型

  • 隐式游标:在 PL/SQL 程序中执行DML SQL 语句时自动创建隐式游标;

  • 显式游标:显式游标用于处理返回多行的查询;

  • REF 游标:REF 游标用于处理运行时才能确定的动态 SQL 查询的结果;

游标的属性

游标的属性分为以下几类。

  • %found:布尔型属性,当最近一次提取游标操作 FETCH成功则为 TRUE,否则为 FALSE;,如果对未打开的游标使用则报ORA-1001异常。

  • %notfound:与%found行为相反。

  • %isopen:判断游标是否打开打开时返回true。

  • %rowcount:数字型属性,返回已从游标中读取的记录数。若未打开就引用,返回ORA-1001。

游标的处理方式

​ 在做查询的操作时,显式游标主要是用于对查询语句的处理,;而对于DML,如修改、删除、更新操作,则由 ORACLE 系统自动地为这些操作设置游标并创建,对于隐式游标的操作,如定义、打开、取值及关闭操作,都由 ORACLE 系统自动地完成,无需用户进行处理。

流程

set serveroutput on
declare
		变量1,变量2 ....
          cursor 游标名 is select ... ; -- 申明游标
    begin
          open 游标名; -- 开启游标
          fetch 游标名 into 变量 -- 将游标中取出的值赋值给变量
          dbms_output.put_line(sqlerrm);
          close 游标名; -- 关闭游标
          dbms_output.put_line(sqlerrm);
    end;

完整流程实例

declare
          v_student student%rowtype;
          cursor c_student(v_id binary_integer) is select * from student where student_no>v_id;
    begin
          open c_student(10);
          fetch c_student into v_student;
          close c_student;
          dbms_output.put_line(v_student.student_name);
    end;

使用实列

游标也类似于JDBC中的resultSet集合

普通游标
set serveroutput on
declare
  cursor emp_cursor is select ename, sal from emp where sal < 1000; -- 申明游标emp_cursor1
  v_name emp.ename%type; -- 申明 v_name并赋值结构
  v_sal  emp.sal%type;-- 申明 v_sal并赋值结构
begin
  open emp_cursor; -- 开启游标
  loop
    fetch emp_cursor into v_name, v_sal; -- 从游标中获取值
    exit when emp

以上是关于Oracle总结三的主要内容,如果未能解决你的问题,请参考以下文章

oracle 中的语句,老是被提示除数为0,但是数据库中是有数据的!是否写法上出问题了! 请大家帮忙看看

3596三除数

java调用oracle存储过程,返回值的内容是ORA-01476: 除数为 0,怎么纠错?

3596三除数

277三除数

277三除数