Declare
-- 声明变量 游标
I integer
BEGIN
-- 执行语句
-- 【异常处理】
END;
其中Declare部分用来声明变量或者游标(结果集类型变量),如果程序中无变量声明可以省略。
begin
-- Test statements here(-- 注释)
dbms_output.put_line('hello word');
end;
F8 执行结果:
CMD 命令窗口 模式运行:
:执行结束后并未输出结果,默认情况下,输出选项是关闭状态,我们需要开启一下,set serveroutput on
变量名 变量类型(变量长度) 例如:v_name varchar2(20);
—普通型变量:
变量赋值的方式有两种:
1 直接赋值语句 :=
v_name varchar2(20) :=‘lisi’;
2 语句赋值,使用select …into…赋值(语法select 值 into 变量)
select ename,sal into v_name,v_sal from emp where empno=7898;
例如:
打印人员信息,包括:姓名,薪水,地址
-- 打印人员信息,包括:姓名,薪水,地址
declare
-- Local variables here
-- 姓名
v_name varchar2(20) :='lisi';
-- 薪水
v_sal number;
-- 地址
v_addr varchar2(200);
i integer;
begin
-- Test statements here
dbms_output.put_line('hello word');
-- 直接赋值
v_sal :=1500;
-- 语句赋值
select '上海昆山' INTO v_addr from dual;
-- 输出语句
dbms_output.put_line('姓名:'||v_name||',薪水:'||v_sal||'地址:'||v_addr);
end;
— 引用变量
变量的类型和长度取决于表中字段的类型和长度。
通过表名.列名%TYPE 指定变量的类型和长度.
例如:v_name emp.ename%TYPE;
【实例】 查询emp 表中7839 员工的个人信息,打印姓名和薪水
-- 查询emp表中7839号员工的个人信息,打印姓名和薪水
declare
-- Local variables here
-- 姓名
v_name varchar2(20);
-- 薪水
v_sal number;
begin
-- Test statements here
-- 语句赋值
select ename,sal into v_name,v_sal from emp where empno=7898;
-- 输出语句
dbms_output.put_line('姓名:'||v_name||',薪水:'||v_sal);
end;
-- 查询emp表中7839号员工的个人信息,打印姓名和薪水
declare
-- Local variables here
-- 姓名
v_name emp.ename%TYPE;
-- 薪水
v_sal emp.sal%TYPE;
begin
-- Test statements here
-- 语句赋值
select ename,sal into v_name,v_sal from emp where empno=7898;
-- 输出语句
dbms_output.put_line('姓名:'||v_name||',薪水:'||v_sal);
end;
-- 查询emp表中7898号员工的个人信息,打印姓名和薪水
declare
-- Local variables here
-- 记录型变量
v_emp emp%ROWTYPE;
begin
-- Test statements here
-- 语句赋值
select * into v_emp from emp where empno=7897;
-- 输出语句
dbms_output.put_line('姓名:'||v_emp.ename||',薪水:'||v_emp.sal);
end;
BEGIN
IF 条件1 THEN 执行1
ELSIF 条件2 THEN 执行2
ELSE 执行3
END IF;
END;
注意关键字:ELSIF
— 实例:
判断 emp 表中记录是否超过20条,10-20之间,或者10条以下
-- 条件查询
declare
-- Local variables here
-- 记录型变量
v_count number;
begin
-- Test statements here
-- 语句赋值
select count(1) into v_count from emp ;
-- 输出语句
if v_count >20 then
dbms_output.put_line('大于20');
elsif v_count >10 then
dbms_output.put_line('大于10小于20');
else
dbms_output.put_line('小于10');
end if;
end;
BEGIN
LOOP
EXIT WHEN 退出循序条件
END_LOOP;
END;
— 【示例】 打印数字1-10
-- loop循环
declare
-- Local variables here
-- 变量
v_count number;
begin
-- Test statements here
-- 语句赋值
select count(1) into v_count from emp ;
-- 输出语句
loop
exit when v_count<0;
dbms_output.put_line(v_count);
v_count :=v_count-1;
end loop;
end;
结果:
— 2.FOR循环用法(1 … 10 表示连续区间)
语法介绍:
BEGIN
FOR 变量 IN inital_value .. final_value LOOP
执行语句;
END LOOP;
END;
下面是控制在一个流程的循环:
初始步骤首先被执行,并且只有一次。这一步可以声明和初始化任何循环控制变量。 接着,condition,initial_value… final_value 进行计算。如果为true,则执行循环体。如果为false,在循环体不执行,只是之后的for循环流量控制跳转到下一条语句。 循环体的执行后,计数器变量的值被增加或减少。 条件现在重新计算。如果为true,循环执行的过程重复(循环体,然后增加步,然后再次条件)。之后条件为false,则FOR-LOOP终止。
以下是PL/SQL for循环的一些特点:
initial_value 和 循环变量 或计算器 final_value 可以是字面值,变量或表达式,但必须计算结果为数字。否则,PL/SQL就会抛出预定义异常VALUE_ERROR。 initial_value不必为1; 但是循环计数器增量(或减量)必须为1。 PL/SQL允许动态确定在运行时的循环范围。
实例:
-- OR循环重复的控制结构,可以有效地编写需要执行的特定次数的循环。
declare
-- Local variables here
-- 声明变量
v_count number;
begin
-- Test statements here
-- 给变量赋值
select count(1) into v_count from emp ;
FOR v_count IN 0 .. 5 LOOP
dbms_output.put_line('数量:'||v_count);
end loop;
dbms_output.put_line('数量结束时:'||v_count);
end;
— 3. While(循环 条件成立时执行)
语法介绍:
BEGIN
WHILE 条件 LOOP
执行语句;
END LOOP;
END;
— 实例:
-- While 循环(条件成立时执行)
declare
-- Local variables here
-- 声明变量
v_count number;
begin
-- Test statements here
-- 给变量赋值
select count(1) into v_count from emp ;
while v_count >0 loop
dbms_output.put_line('数量:'||v_count);
v_count :=v_count-1;
end loop;
dbms_output.put_line('数量结束时:'||v_count);
end;
游标的使用方式:声明–> 打开—>读取—>关闭。
语法:
游标的属性:
游标的属性 | 返回值类型 | 说明 |
---|---|---|
%ROWCOUNT | 整型 | 获得FETCH 语句返回的数据行数 |
%FOUND | 布尔型 | 最近的FETCH语句返回一行的数据,则为真,否则为假 |
%NOTFOUND | 布尔型 | 与%FOUND属性返回值相反 |
%ISOPEN | 布尔型 | 游标已经打开时的值为真,否则为假。 |
其中**%NOTFOUND** 是在游标中找不到元素的时候返回TRUE..通常用来判断退出循环。
-- 使用游标查询emp 表中所有的员工的姓名和薪水,并依次打印出来。
declare
-- Local variables here
-- 声明游标
cursor c_emp is select ename,sal from emp;
-- 声明变量接收游标中的数据
v_name emp.ename%type;
v_sal emp.sal%type;
begin
-- Test statements here
-- 打开游标
OPEN c_emp;
-- 遍历循环
loop
-- 获取游标中的数据
FETCH c_emp into v_name,v_sal;
-- 退出循环
exit when c_emp%notfound;
-- 输出
dbms_output.put_line('ename:'||v_name||'sal:'||v_sal);
end loop;
-- 关闭游标
close c_emp;
end;
— 带参数的游标、
【示例:】使用游标查询并打印某部门的员工的姓名和薪资,部门编号为运行时输入
-- 使用游标查询并打印某部门的员工的姓名和薪资,部门编号为运行时输入
declare
-- Local variables here
-- 声明游标
cursor c_emp (v_empno emp.empno%type)is select ename,sal from emp where empno =v_empno;
-- 声明变量接收游标中的数据
v_name emp.ename%type;
v_sal emp.sal%type;
begin
-- Test statements here
-- 打开游标
OPEN c_emp(7898);
-- 遍历循环
loop
-- 获取游标中的数据
FETCH c_emp into v_name,v_sal;
-- 退出循环
exit when c_emp%notfound;
-- 输出
dbms_output.put_line('ename:'||v_name||'sal:'||v_sal);
end loop;
-- 关闭游标
close c_emp;
end;
CREATE OR REPLACE PROCEDURE 过程名称[(参数列表)] IS
BEGIN
END [过程名称];
-- 编写存储过程
create or replace procedure p_emp is
-- 声明变量
begin
dbms_output.put_line('Hello Word');
end p_emp;
运行之后再PLSQL中调用存储过程
-- PLSQL调用存储过程
declare
begin
-- PLSQL 调用存储过程
p_emp;
end;
执行结果:
注意:
第一个问题:is和as是可以互用的,用哪个都没有关系。
第二个问题:过程中没有declare关键字,declare用在语句块中。
2。带输入参数的存储过程
【示例】查询并打印某个员工(如7989号员工)的姓名和薪水–存储过程,要求调用的时候传入员工的编号,自动控制台打印。
-- 查询并打印某个员工(如7989号员工)的姓名和薪水
--存储过程,要求调用的时候传入员工的编号,自动控制台打印。
create or replace procedure p_emp ( in_empno IN emp.empno%type )is
-- 声明变量
v_name emp.ename%type;
v_sal emp.sal%type;
begin
--查询赋值
select ename,sal into v_name,v_sal from emp where empno=in_empno;
dbms_output.put_line('v_name:'||v_name||'v_sal:'||v_sal);
end p_emp;
-- 查询并打印某个员工(如7989号员工)的姓名和薪水--存储过程,
-- 要求调用的时候传入员工的编号,自动控制台打印。
declare
begin
-- PLSQL 调用存储过程
p_emp(7898);
end;
结果:
命令窗口调用:
3。带输入输出参数(返回值)的。
【示例】输入员工号查询某个员工信息,要求,将薪水作为返回值输出,给调用的程序使用。
-- 输入员工号查询某个员工信息,要求,
-- 将薪水作为返回值输出,给调用的程序使用。工的编号,自动控制台打印。
create or replace procedure p_emp ( in_empno IN emp.empno%type,o_sal out emp.sal%type)is
begin
--查询赋值
select sal into o_sal from emp where empno=in_empno;
end p_emp;
调用存储过程
-- 输入员工号查询某个员工信息,要求
-- 将薪水作为返回值输出,给调用的程序使用。。
declare
-- 声明变量用来接收参数。。。
v_sal emp.sal%type;
begin
-- PLSQL 调用存储过程
p_emp(7898,v_sal);
dbms_output.put_line(v_sal);
end;
如果一条语句无法实现结果集,比如需要多表查询,或者需要复杂逻辑查询,我们可以调用存储查询出你的结果;
分析JDK.API
CallableStatement prepareCall(String sql);
//创建一个调用数据库存储过程的CallableStatement 对象。
调用步骤:
Class.forName("oracle.jdbc.driver.OracleDriver");
String url="jdbc:oracle:thin:@localhost:1521:orcl";
String username="root";
String password="root";
Connection connection = DriverManager.getConnection(url, username, password);
String sql="{call p_emp(?,?)}";
CallableStatement call = connection.prepareCall(sql);
call.setInt(1, 7898);
call.registerOutParameter(2, OracleTypes.DOUBLE);
call.execute();
double sal = call.getDouble(2);
System.out.println(sal);
call.close();
connection.close();
总体测试方法:
public static void main(String[] args) throws Exception {
//1.加载驱动
Class.forName("oracle.jdbc.driver.OracleDriver");
//2.获取连接对象
String url="jdbc:oracle:thin:@localhost:1521:orcl";
String username="root";
String password="root";
Connection connection = DriverManager.getConnection(url, username, password);
//3.获取语句对象
String sql="{call p_emp(?,?)}";
CallableStatement call = connection.prepareCall(sql);
//4.设置输入参数
call.setInt(1, 7898);
//5.注册输出参数
call.registerOutParameter(2, OracleTypes.DOUBLE);
//6.执行存储过程
call.execute();
//7.获取输出参数
double sal = call.getDouble(2);
System.out.println(sal);
//8.释放资源
call.close();
connection.close();
}
@Test
public void oracleConnectTest() throws Exception{
//1.加载驱动
Class.forName("oracle.jdbc.driver.OracleDriver");
//2.获取连接
String url="dbc:oracle:thin:@localhost:1521:orcl";
String password="root";
String username="root";
Connection connection = DriverManager.getConnection(url, username, password);
//3.获取传输器
String sql="select * from emp";
PreparedStatement statement = connection.prepareStatement(sql);
//4.设置参数
//5.执行sql语句
statement.execute();
//6.获取结果集
ResultSet resultSet = statement.executeQuery();
//7.遍历结果集
while (resultSet.next()){
People people= new People();
people.setNumber(resultSet.getInt("empno"));
people.setName(resultSet.getString("ename"));
people.setSal(resultSet.getDouble("sal"));
System.out.println(people);
}
//关闭资源
resultSet.close();
statement.close();
connection.close();
}
POJO类:
class People{
private Integer number;
private String name;
private Double sal;
public Integer getNumber() {
return number;
}
public void setNumber(Integer number) {
this.number = number;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Double getSal() {
return sal;
}
public void setSal(Double sal) {
this.sal = sal;
}
@Override
public String toString() {
return "people{" +
"number=" + number +
", name='" + name + '\'' +
", sal=" + sal +
'}';
}
}
链接:https://pan.baidu.com/s/1mBgRKpBh3ZeVQL7wIj8kOA
提取码:tqiv