Oracle学习 第12天
—— PL/SQL 编程(过程 & 块)
过程的概念
创建存储过程(一)
CREATE [OR REPLACE] PROCEDURE 过程名(参数1 参数类型, 参数2 参数类型, ……) IS --或者AS 初始化变量; BEGIN 执行SQL语句; END; /
★:注意:
1、过程参数的定义方式与函数参数定义的方式不同。过程的参数定义是参数名在前,参数类型在后。
2、上述基本语法中 斜杠/ 的意义。
因为在脚本中,可能存在多条SQL语句,如果没有斜杠,则遇到分号就会执行,而在脚本定义中,不需要马上执行。
该符号多用于创建创建存储过程,其意义为:执行之前的SQL脚本。
在PL/SQL等客户端中,可以使用执行选中代码,就不必使用/。
3、IS 与 BEGIN 关键字之间的部分,仅仅用于声明变量,可以初始化,但不允许赋值;
4、传入的输入参数不允许作为赋值目标;
示例1(IS 与 BEGIN 之间可以声明变量)
SQL> CREATE OR REPLACE PROCEDURE pro_test(v_empno NUMBER) 2 IS 3 v_sal NUMBER; -- 定义变量 4 BEGIN 5 SELECT sal INTO v_sal FROM emp WHERE empno = v_empno; 6 END; 7 8 / Procedure created
示例2(IS 与 BEGIN 之间可以声明并初始化变量)
SQL> CREATE OR REPLACE PROCEDURE pro_test(v_empno NUMBER) 2 IS 3 v_sal NUMBER := 100; -- 定义变量 并初始化 4 BEGIN 5 SELECT sal INTO v_sal FROM emp WHERE empno = v_empno; 6 END; 7 / Procedure created示例3( IS 与 BEGIN 之间不可以对变量进行赋值)
SQL> CREATE OR REPLACE PROCEDURE pro_test(v_empno NUMBER) 2 IS 3 v_sal NUMBER; -- 定义变量 4 v_sal := 100; -- 对变量赋值 5 BEGIN 6 SELECT sal INTO v_sal FROM emp WHERE empno = v_empno; 7 END; 8 / Warning: Procedure created with compilation errors SQL> show error Errors for PROCEDURE SCOTT.PRO_TEST: LINE/COL ERROR -------- -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 4/7 PLS-00103: 出现符号 "="在需要下列之一时: constant exception <an identifier> <a double-quoted delimited-identifier> table long double ref char time timestamp interval date binary national character nchar 符号 "<an identifier>" 被替换为 "=" 后继续。 SQL>
示例4:-- 创建一个过程,其功能是删除EMP表中EMPNO为‘1234’的用户。
SELECT * FROM emp;
CREATE [OR REPLACE] PROCEDURE pro_test(eno VARCHAR2) -- CREATE OR REPLACE : 如果该过程不存在则创建,如果存在则更新替换 IS BEGIN DELETE FROM emp WHERE empno=eno; END; SELECT * FROM emp;
调用存储过程
EXEC 过程名(参数1, 参数2, ……);
CALL 过程名(参数1, 参数2, ……);
★:注意:在命令行中,可以直接使用EXEC调用存储过程。
但是在 PL/SQL 客户端中。SQL WINDOWS 窗口是无法直接执行EXEC命令的(会报错:无效的SQL命令)
需要在COMMAND WINDOW窗口下执行。
SELECT * FROM EMP;
▲ :说明:在COMMAND 窗口编写过程时,如果遇到报错,默认是不会显示错误内容的。
可以使用 SHOW ERROR 命令来查询具体报错内容。
创建存储过程(二)
建立存储过程时,还可以直接明确指定输入参数(IN)或者输出参数(OUT)。
输入参数可以将数据传递到执行部分。
输出参数可以将数据传递到应用的环境。
基本语法:
CREATE [OR REPLACE] PROCEDURE 过程名(变量 IN 变量类型……, 变量 OUT 变量类型) IS BEGIN 执行语句; END; /★ 注意:在不明确指定 IN 或 OUT 时,默认的是输入参数,即 IN 。
JAVA中调用存储过程
SQL> create or replace procedure pro_test(v_empno IN number, v_name IN varchar2, v_sal number) IS 2 begin 3 insert into emp(empno, ename, sal) values(v_empno, v_name, v_sal); 4 end; 5 / Procedure created
public class TestProcedure { public static void main(String[] args) { Connection ct = null; CallableStatement cs = null; try { // 加载驱动 Class.forName("oracle.jdbc.driver.OracleDriver"); //得到连接 ct = DriverManager.getConnection("jdbc:oracle:thin:@127.0.0.1:1521:ORCL", "scott", "scott"); /* sql 语句 固定写法 : * 大括号{}包含 * * {call 过程名(占位符, 占位符, ……)} * * ?为占位符,需要传几个参数就写几个问号 ★ 这里的参数指 IN 参数。 OUT 参数 一会儿另行演示 * */ String sql = "{call pro_test(?,?,?)}"; // 创建 CallableStatement 接口引用对象 cs = ct.prepareCall(sql); //对占位符 ? 赋值 注意:?的个数是从 1 开始计数 cs.setInt(1, 7777); // 第一个?赋值 7777 cs.setString(2, "jack"); // 第二个?赋值jack cs.setFloat(3, 4000.89F); // 第三个?赋值Float类型的 4000.89 //执行 execute 方法用来执行任何种类的 SQL 语句 ,返回一个 boolean 类型 cs.execute(); } catch (Exception e) { // TODO: handle exception e.printStackTrace(); } finally { //关闭资源 (本例省略) } } }
PL/SQL编程规范
1、单行注释: -- 内容
2、多行注释: /* 内容 */
3、变量: v_ 作为前缀。如 v_name
4、常量: c_ 作为前缀。如 c_class
5、游标: _cursor 作为后缀。 如 student_cursor
6、例外: e_ 作为前缀。 如 e_error
块(Block)
块是PL/SQL的基本程序单元。编写PL/SQL程序实际上就是编写PL/SQL块。
可以在一个PL/SQL块中嵌套其他的PL/SQL块来实现一些复杂的功能。
块的意义类似于其他编程语言中的类(class)。但是写法有很大的不同。
首先,块中的定义与执行是完全分开的,这与其他编程语言的类中可以随时定义变量的写法完全不同。
块 由三部分构成:定义部分、执行部分、例外部分。其结构非常严格。
块的基本结构如下:
/*定义部分(可选) -- 定义常量、变量、游标、其他数据类型等*/ DECLARE /*执行部分(必须) -- 要执行的SQL语句或PL/SQL语句*/ BEGIN /*例外部分(可选) -- 处理运行时可能产生的各种错误*/ EXCEPTION END; -- 结束标志Oracle中, 也提供了很多的常用开发包(基本上都是以 dbms_ 为前缀)。其中包含了一些过程。
示例1:
-- 在PL/SQL客户端的Command Window下打印输出 Hello World
SQL> / SQL> set serveroutput on; -- ★ 默认打印台是关闭的,我们需要先设置打开。后面的实例省略该步骤 SQL> / SQL> begin 2 dbms_output.put_line('Hello World!'); 3 end; 4 / Hello World! PL/SQL procedure successfully completed
示例2:
-- 查询emp表中编号为7900的员工姓名,并将姓名赋值给一个变量。
块的写法如下:
SQL> declare -- 声明变量的关键字 2 v_name varchar2(20); -- 变量名 变量类型 ★ 这里不仅需要指定类型,还需要指定长度。 3 begin -- 执行体开始 4 select ename into v_name from emp where empno = &empno; -- 此处 &empno 的写法 会弹出窗口要求用户输入 empno 的值 -- 从 emp 表中 查询 enamel 字段 赋值给 v_name 变量 。查询条件为 empno = 弹出对话框后用户输入的值 5 dbms_output.put_line('The name is '||v_name); -- 输出 The name is 变量v_name的值 6 end; -- 执行体结束 7 / -- 执行上面脚本 The name is JAMES PL/SQL procedure successfully completed
SQL> create procedure pro_test(in_empno number) 2 IS 3 v_name varchar2(20); 4 BEGIN 5 select ename into v_name from emp where empno = in_empno; 6 dbms_output.put_line('The name is '||v_name); 7 end; 8 / Procedure created SQL> exec pro_test(7900); The name is JAMES PL/SQL procedure successfully completed
★ 注意:
在定义块时,变量不仅仅需要指定类型,还需要指定长度;
在定义过程时,参数只需要指定类型,不需要指定长度;
示例3:
-- 查询emp表中编号为1234的员工姓名,实际上该员工并不存在,我们需要让他执行异常处理。
SQL> declare 2 v_name varchar2(20); 3 begin 4 select ename into v_name from emp where empno = &empno; 5 end; 6 / declare v_name varchar2(20); begin select ename into v_name from emp where empno = 1234; end; ORA-01403: 未找到任何数据 ORA-06512: 在 line 4
可以看出,Oracle中默认的有提供一些异常处理机制,在没有找到数据时会有“ORA-01403:未找到数据”提示。
但是,这对于普通的用户来说,并不是所有的Oracle提示都能看的懂,所以,我们需要尝试着让Oracle在发生异常时,执行我们自己定义的语句。
异常部分的基本语法:
EXCEPTION WHEN 异常名称 THEN 执行代码; WHEN 异常名称2 THEN 执行代码2;
SQL> declare 2 v_name varchar2(20); 3 begin 4 select ename into v_name from emp where empno = &empno; 5 dbms_output.put_line('员工姓名:'||v_name); 6 exception 7 when no_data_found then 8 dbms_output.put_line('没有找到数据,您输入的员工号可能有误'); 9 end; 10 / 没有找到数据,您输入的员工号可能有误 PL/SQL procedure successfully completed
示例中异常的处理代码仅仅是打印了自定义的一句话。
当然也可以写其他的执行语句,比如:如果没有找到该员工,就新增一条信息?
同样是可以的。只需要在第8行后加入 INSERT INTO 的SQL语句即可。