语句块
declare num1 number := 20; num2 number := 30; begin dbms_output.put_line(mod(num2, num1)); -- 10 end;
异常处理
%type--->该变量的数据类型与已经声明变量的类型或者表中列的类一致
%rowtype --->来表示一行数据
declare v_user tb_user%rowtype; --表示表中的一行数据 begin select * into v_user from tb_user where user_id = 120; -- 数据的输出: 变量名称.列名 -- 输出姓名 v_user.user_name dbms_output.put_line('编号:' || v_user.user_id || ' 姓名:' || v_user.user_name); dbms_output.put_line('没有异常'); -- 异常出现时,后面的代码无法执行 exception when others then-- others 类似java中的exception dbms_output.put_line('查询不到数据'); end;
条件判断
1、条件逻辑
1)
if 布尔类型 then
符合条件的代码;
end if;
2)
if 布尔类型表达式 then
符合条件的代码
else
上面条件不满足而执行的代码
end if;
3)
if 布尔类型表达式 then
符合条件的代码
elsif 布尔类型表达式 then
符合条件的代码
else
上面条件不满足而执行的代码
end if;
2、 循环
1) loop 循环 :
loop
重复执行的代码
end loop;
如果结束循环则使用exit
2) loop endloop 循环
while 条件 loop
重复执行的代码;
end loop;
3)for 变量 in [reverse] 最小值 .. 最大值 loop
重复执行的代码
end loop;
declare v_num number :=0; v_num2 number :=0; begin for v_num in 1 .. 9 loop for v_num2 in 1 .. v_num loop dbms_output.put(v_num2||'*'||v_num||'='||(v_num*v_num2)||' '); end loop; dbms_output.put_line(''); end loop; end;
游标:
把select语句查询出来的结果保存在内存中,然后利用循环等手段来获取该内存中的数据,由于数据是保存在内存中,所以速度快,但是对于大批量数据来说,会占用大量的内存可能导致oracle软件的运行变得更加缓慢。游标适合保存查询量少的数据。
declare cursor myCursor is select * from tb_user;-- 把tb_user表中的数据保存在内存中,这块内存的名称叫myCursor v_user tb_user%rowtype; begin -- 1.打开游标 open 游标名字 游标只有先打开后才能使用 open myCursor; -- 2.从游标中提取数据 loop fetch myCursor into v_user; if myCursor%notfound then -- 当遍历到最后一条数据时,%notfound--->false exit ;-- 结束循环 end if; --可以输出一下数据 dbms_output.put_line(v_user.user_name); end loop; --3.关闭游标 close 游标名称 close myCursor; end;
循环
declare cursor myCursor is select * from tb_user; v_user tb_user%rowtype; begin open myCursor; while true loop -- 必须先进入while loop循环 fetch myCursor into v_user; if myCursor%notfound then -- 当遍历到最后一条数据时,%notfound--->false exit ;-- 结束循环 end if; dbms_output.put_line(v_user.user_name); end loop; close myCursor; end;
带参数的显式游标
declare cursor myCursor(v_name varchar2) is select * from tb_user where user_name = v_name; v_user tb_user%rowtype; begin -- 打开游标时,传入实参 open myCursor('张三3'); loop -- 从游标中提取数据 fetch myCursor into v_user; if myCursor%notfound then exit;--退出循环 end if; dbms_output.put_line(v_user.user_id); end loop; close myCursor; end;
ref游标
declare --声明ref游标的类型 type refCursor is ref cursor; -- 声明ref游标变量 myCursor refCursor; -- v_name varchar2(30) v_user tb_user%rowtype; begin open myCursor for select * from tb_user; -- 在打开游标时才传入select语句 -- ref游标与显式游标最大的不同点在于ref游标的select语句是在open时才 确定的 loop fetch myCursor into v_user; if myCursor%notfound then exit; end if; dbms_output.put_line(v_user.age); end loop; -- 输出有多少条数据 dbms_output.put_line(myCursor%rowcount); close myCursor; end;
declare type refCursor is ref cursor return tb_user%rowtype; -- 声明一个ref游标类型,并指定返回类型 myCursor refCursor; v_user tb_user%rowtype; begin open myCursor for select * from tb_user; loop fetch myCursor into v_user; if myCursor%notfound then exit; end if; dbms_output.put_line(v_user.age); end loop; close myCursor; end;
存储过程:
入参
create or replace procedure pro2(v_name in varchar2) is v_age number; begin select age into v_age from tb_user where user_name=v_name; dbms_output.put_line(v_name||'的年龄'||v_age); exception when others then dbms_output.put_line('查询出错!'); end;
出参
create or replace procedure pro3(v_count out number) is begin select count(*) into v_count from tb_user;--查询用户的总记录数 -- count(*)的效率和count(user_id)的效率是一样的 end; declare v_count number; begin pro3(v_count); dbms_output.put_line(v_count); end;
in out --- 同一变量即是输入参数又是输出参数
-- 输入一个数字,获取其倍数 create or replace procedure pro4(v_num in out number) is begin v_num := v_num*2; end; declare num number := 10; begin pro4(num); dbms_output.put_line(num); end;
create or replace procedure pro5(v_name in varchar2) is cursor myCursor(v_name2 varchar2) is select * from tb_user where user_name like v_name2; v_user tb_user%rowtype; begin open myCursor(v_name); loop fetch myCursor into v_user; if myCursor%notfound then exit; end if; dbms_output.put_line('编号:'||v_user.user_id||' 姓名:'||v_user.user_name); end loop; close myCursor; end;
declare begin pro5('%张%'); end;
函数---自定义函数
-- 函数的定义和存储过程的定义是类似的,使用函数时,就不能使用out和 in out模式了
-- 自定义具有加法功能的函数,传入一个数字,加上100,返回其结果 create or replace function addNum(v_num in number) return number -- 函数的返回类型 is -- 局部变量 begin return v_num+100; end; -- 使用 select addnum(1000) from dual; select * from tb_user where age > addnum(100); select user_name,addnum(age) from tb_user;
-- 用户输入两个数字,返回值较大的数字 create or replace function compare(v_num1 in number,v_num2 in number) return number is begin if v_num1 > v_num2 then return v_num1; else return v_num2; end if; end;
包
包的使用: 包中变量的使用: 包名.变量名称
-- 存储过程: 包名.存储过程名称[(参数)]
-- 函数: 包名.函数名称();
-- 第一步: 创建包头 create package package3 is -- 声明 procedure pro1; -- 声明一个存储过程 end; -- 第二步:创建包体 create or replace package body package3 is procedure pro1 is -- 存储过程的实现 v_name2 varchar2(30); begin v_name2 :='张三'; dbms_output.put_line(v_name2); end; begin null; -- 不想写代码,直接使用null值替代 end; declare begin package3.pro1; -- 调用包中的存储过程!! end;
-- 1.建包头 create or replace package package5 is function multi(v_num1 in number,v_num2 in number)return number; --函数的声明 end; -- 2.建包体,写函数的实现!! create or replace package body package5 is function multi(v_num1 in number ,v_num2 in number) return number is begin return v_num1*v_num2; end; begin null; end; -- 调用包中的函数 declare v_result number :=0; begin v_result := package5.multi(100,100); dbms_output.put_line(v_result); end;
-- 在包中写游标 create or replace package package6 is -- 声明一个显示游标 cursor myCursor is select * from tb_user; end; create or replace package body package6 is v_user tb_user%rowtype; begin open myCursor; loop fetch myCursor into v_user; if myCursor%notfound then exit; end if; dbms_output.put_line(v_user.user_name); end loop; close myCursor; end;