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 是将一整张表的数据赋值给另一个表,然后就可以对表中的字段进行相应的操作
实例:
- 新建表和数据
-- 新建一个简单的学生表
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');
- 使用%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;
- 使用%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;
- 使用%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,以上是关于Oracle总结三的主要内容,如果未能解决你的问题,请参考以下文章
Android 逆向加壳技术简介 ( 动态加载 | 第一代加壳技术 - DEX 整体加固 | 第二代加壳技术 - 函数抽取 | 第三代加壳技术 - VMP / Dex2C | 动态库加壳技术 )