1.写出plsql程序的结构 并说明每一部分的作用
2.写出 表名.字段名%type 的含义 以及 表名%rowtype 的含义
3.把下面的java 代码 翻译成 PLSQL的语法
if(a > b){
}else if(a > c){
}else{
}
4.使用while 循环 把一个变量的值 从 1 输出到 10
5.写出PLSQL中的游标的使用步骤 并写出每一步的关键代码
------------------------------------------------------------------------------
1.定义一个游标 用来存放 s_emp 表中的 id first_name salary.
提取这个游标的前两条数据 并打印。
declare
cursor empcursor is select id,first_name name,salary from s_emp;
var_emp empcursor%rowtype;
begin
open empcursor;
fetch empcursor into var_emp;
dbms_output.put_line(var_emp.id||':'||var_emp.name||':'||var_emp.salary);
fetch empcursor into var_emp;
dbms_output.put_line(var_emp.id||':'||var_emp.name||':'||var_emp.salary);
close empcursor;
end;
/
2.如何提取出 游标中所有的数据?
游标属性
游标名 % found 当提取游标数据时 如果提取到了新数据 则这个属性返回TRUE。
如果没有提取到新数据则返回FALSE。注意这个属性使用有两个前提 第一游标
必须处于打开状态 否则就报非法游标的错,第二游标必须fetch 否则返回NULL。
游标名 % notfound 当提取游标数据时 如果提取到了新数据 则这个属性返回FALSE。
如果没有提取到新数据则返回TRUE。注意这个属性使用有两个前提 第一游标
必须处于打开状态 否则就报非法游标的错,第二游标必须fetch 否则返回NULL。
使用简单循环 结合 notfound 属性遍历游标
declare
cursor empcursor is select id,first_name name,salary from s_emp;
var_emp empcursor%rowtype;
begin
open empcursor;
loop
fetch empcursor into var_emp;
-- 当提取不到新数据时 就结束循环
exit when empcursor%notfound;
dbms_output.put_line(var_emp.id||':'||var_emp.name||':'||var_emp.salary);
end loop;
close empcursor;
end;
/
使用while循环 结合 found 属性 遍历上面的游标
declare
cursor empcursor is select id,first_name name,salary from s_emp;
var_emp empcursor%rowtype;
begin
open empcursor;
fetch empcursor into var_emp;
while empcursor%found loop
dbms_output.put_line(var_emp.id||':'||var_emp.name||':'||var_emp.salary);
fetch empcursor into var_emp;
end loop;
close empcursor;
end;
/
3. 游标的其它属性 (了解)
游标名%isopen 判断游标是否打开 如果是打开状态则返回 TRUE 否则返回false 。
注意 打开的游标不能再打开 关闭的游标 不能再关闭。
游标名%rowcount 游标指针偏移量 记录提取数据的指针偏移了多少
4.for 循环 遍历游标 --- 智能循环
自动定义变量 自动打开游标 自动提取数据 自动关闭游标
declare
cursor empcursor is select id,first_name name,salary from s_emp;
begin
for var_emp in empcursor loop
dbms_output.put_line(var_emp.id||':'||var_emp.name||':'||var_emp.salary);
end loop;
end;
/
5.带参游标
定义游标时 可以给游标设计参数 并且这些参数 可以在游标对应的select语句中使用
通过 我们打开游标时 传入实参就可以像正常游标一样去遍历了。
plsql 中参数不能加长度修饰 但是 可以使用 表名.字段名%type。
/*带参游标*/
declare
cursor empcursor(var_id number) is select id,first_name name,
salary from s_emp where id>var_id;
var_emp empcursor%rowtype;
begin
open empcursor(10);
fetch empcursor into var_emp;
while empcursor%found loop
dbms_output.put_line(var_emp.id||':'||var_emp.name||':'||var_emp.salary);
fetch empcursor into var_emp;
end loop;
close empcursor;
end;
/
/*for +带参游标*/
declare
cursor empcursor(var_id number) is select id,first_name name,
salary from s_emp where id>var_id;
begin
for var_emp in empcursor(15) loop
dbms_output.put_line(var_emp.id||':'||var_emp.name||':'||var_emp.salary);
end loop;
end;
/
6.参考游标 ref cursor
6.1 动态sql的思路
本质是游标对应的sql语句 是一条字符串
语句是字符串 则 在程序运行的过程中 sql语句可以根据条件发生改变。
6.2 ref cursor 的使用 步骤
a.定义一个参考游标 游标类型
type 参考游标类型 is ref cursor;
b.使用这个类型定义一个游标变量
游标变量 参考游标类型;
c.打开游标变量 传入对应的字符串
open 游标变量 for sql字符串;
6.3 案例
/*if 拼接字符串 参考游标*/
declare
type myrefcursor is ref cursor;
empcursor myrefcursor;
sqlstr varchar2(200);
id s_emp.id%type:=10;
salary s_emp.salary%type:=2000;
type emptype is record(
id s_emp.id%type,
name s_emp.first_name%type,
salary s_emp.salary%type
);
var_emp emptype;
begin
sqlstr:='select id,first_name name,salary from s_emp where 1=1 ';
if id is not null then
sqlstr:=sqlstr||' and id<' || id;
end if;
if salary is not null then
sqlstr:=sqlstr||' and salary < ' || salary;
end if;
dbms_output.put_line(sqlstr);
-- 打开游标变量时 传入对应的字符串
open empcursor for sqlstr;
loop
fetch empcursor into var_emp;
exit when empcursor%notfound;
dbms_output.put_line(var_emp.id||':'||var_emp.name||':'||var_emp.salary);
end loop;
end;
/
/*占位符参考游标*/
declare
type myrefcursor is ref cursor;
empcursor myrefcursor;
sqlstr varchar2(200);
id s_emp.id%type:=10;
salary s_emp.salary%type:=2000;
type emptype is record(
id s_emp.id%type,
name s_emp.first_name%type,
salary s_emp.salary%type
);
var_emp emptype;
begin
sqlstr:='select id,first_name name,salary from s_emp where id < :b0 and salary < :b1';
/* 当出现 :开头的占位符时 使用 using 传入实参 */
open empcursor for sqlstr using id,salary;
loop
fetch empcursor into var_emp;
exit when empcursor%notfound;
dbms_output.put_line(var_emp.id||':'||var_emp.name||':'||var_emp.salary);
end loop;
end;
/
7.异常 (了解)
7.1 异常的分类
编译时异常 语法错误
运行时异常 程序运行的过程中产生的错误
7.2 举例
declare
var_name s_emp.first_name%type;
begin
select first_name into var_name from s_emp where id=111;
dbms_output.put_line(var_name);
end;
/
一个程序执行 可能出现异常 也可能不出现异常
7.3 如何处理
异常处理 就是提前写好 程序的问题处理方案
declare
var_name s_emp.first_name%type;
begin
select first_name into var_name from s_emp where id=11;
dbms_output.put_line(var_name);
exception
when NO_DATA_FOUND then
dbms_output.put_line('no emp found');
when TOO_MANY_ROWS then
dbms_output.put_line('select too many emp');
when others then
-- sqlcode 的意思是sql的状态码 sqlerrm 的意思是 sql error message 简写
dbms_output.put_line('have exception'||':'||SQLCODE||':'||SQLERRM);
end;
/
8.过程 procedure 10*10*10
8.1 什么是过程
完成特定逻辑的一组代码的逻辑封装 。
8.2 写一个plsql 的功能 定义两个整数变量 打印这两个变量的最大值
declare
var_x number:=20;
var_y number:=50;
begin
if var_x < var_y then
dbms_output.put_line(var_y);
else
dbms_output.put_line(var_x);
end if;
end;
/
这叫匿名块 直接可以执行 复用只能拷贝 这样后期维护和管理比较复杂
8.3 把上面的匿名块 改造成 过程
create or replace procedure getmax(var_x number:=20,var_y number:=50)
is
begin
if var_x < var_y then
dbms_output.put_line(var_y);
else
dbms_output.put_line(var_x);
end if;
end;
/
create or replace procedure 过程名(参数 参数类型:=默认值,参数 参数类型:=默认值)
is
/* 这就是之前的申明区*/
begin
end;
/
8.4 如何调用
call 过程名(参数);
execute 过程名(参数);
这两种 了解一下 call 调用无参的也必须加() execute 调用无参可以不加()
在实际开发中 以直接调用为主
begin
/* 在匿名块中直接调用 匿名块可以调用过程 哪过程也可以调用过程 */
getmax(111,222);
end;
/
8.5 写一个存储过程 设计两个整数参数 打印这两个参数的最小值 并使用匿名块验证功能。
create or replace procedure getmin(var_x number:=0,var_y number:=1)
is
begin
if var_x < var_y then
dbms_output.put_line(var_x);
else
dbms_output.put_line(var_y);
end if;
end;
/
begin
getmin();
getmin(11,9);
end;
/
8.6 写一个存储过程 设计三个整数参数 打印这前两个参数的最小值 并且把前两个参数的和
存入第三个参数中。
static void getNum(int x){
x=10000;
}
int main(){
int x=1;
getNum(x);
x
}
static void getString(String x){
x="abc";
}
int main(){
String x=new String("a");
getString(x);
x
}
static void getString(StringBuffer x){
x.append("abc");
}
int main(){
StringBuffer x = new StringBuffer("a");
getString(x);
x
}
plsql中默认的参数 是in 参数 只能读不能写
如果希望存储过程带回值 则使用out 参数
create or replace procedure getmin_and_sum(var_x in number,var_y number,
var_z out number)
is
begin
dbms_output.put_line('var_z='||var_z);
if var_x < var_y then
dbms_output.put_line(var_x);
else
dbms_output.put_line(var_y);
end if;
var_z:=var_x+var_y;
end;
/
注意:调用 带有out 参数的过程时,out模式的参数 必须是变量
declare
var_z number:=100;
begin
getmin_and_sum(1,9,var_z);
dbms_output.put_line(var_z);
end;
/
参数的模式:
in 默认的 只负责给存储过程传入值
out 只负责给存储过程传出值
in out 既能给存储过程传入值 又能传出值
写一个存储过程 设计二个整数参数 打印这两个参数的最小值 并且把前两个参数的和
存入第二个参数中。
create or replace procedure getmin_and_sum(var_x in number:=1,
var_y in out number)
is
begin
if var_x < var_y then
dbms_output.put_line(var_x);
else
dbms_output.put_line(var_y);
end if;
var_y:=var_x+var_y;
end;
/
8.7 如何调用一个大家不熟悉的存储过程
查看存储过程 desc 过程名;
desc getmin_and_sum;
a.获取参数的名字
b.参数的类型
c.参数的模式 如果有out 修饰 则必须是变量
d.参数是否有默认值 要获取具体的默认值 测试 查看公司文档 查看源代码
select text from user_source where name='GETMIN_AND_SUM';
参数的位置赋值
declare
var_y number:=10;
begin
getmin_and_sum(1,var_y);
dbms_output.put_line(var_y);
end;
/
参数的名字赋值 可以改变赋值的顺序 参数名=>参数的值 (了解)
declare
var_y number:=9;
begin
getmin_and_sum(var_y=>var_y,var_x=>1);
dbms_output.put_line(var_y);
end;
/
8.8 设计一个存储过程 可以传入一个参数 n 这个参数代表从1 加到的数
还有一个参数可以存储 前n项的 和。 调用这个存储过程验证功能。
如 n = 10 1+2+3+4+5+6+7+8+9+10=55
create or replace procedure getNumN(n in number,var_sum out number)
is
begin
var_sum:=0;
for i in 1..n loop
var_sum:=var_sum+i;
end loop;
end;
/
declare
var_sum number:=100;
begin
getNumN(100,var_sum);
dbms_output.put_line('var_sum='||var_sum);
end;
/
declare
var_sum number:=100;
begin
getNumN(var_sum=>var_sum,n=>100);
dbms_output.put_line('var_sum='||var_sum);
end;
/
9.函数
9.1 过程和函数的区别
a.第一关键字不同 过程是 procedure 函数是 function
b.函数有返回值类型 和 返回值 而过程没有
c.调用方式不同 过程可以直接调用 函数必须组成表达式才能调用
9.2 语法
create or replace function 函数名(参数名 参数类型:=值,参数名 参数类型:=值)
return 返回值类型
is
-- 定义类型 定义变量
begin
if 条件 then
return 值;
end if;
end;
/
9.3 设计一个plsql 函数 有两个整数参数 返回两个参数的最大值
drop procedure getmax;
create or replace function getmax(var_x in number,var_y number)
return number
is
begin
if var_x < var_y then
return var_y;
end if;
return var_x;
end;
/
这只是 测试
select getmax(1,100) from dual;
真正的调用 有匿名块 或者 有名块调用
begin
dbms_output.put_line(getmax(1,999));
if getmax(1,999) > 900 then
dbms_output.put_line('ggggg');
end if;
end;
/
9.4 设计一个函数 有两个整数参数 返回参数的最大值 并且把两个参数的和存入第二个参数中
调用这个函数 验证函数的功能。