`

oracle----块编程

阅读更多
1.块的构成:---这里不是存储过程哈。。。。
定义部分,执行部分,例外处理部分

declear --可选  相当于java   int a=1;定义部分啦

begin     --这里其实可以看成静态块,动态块,方法块 看成{ } 就可以了

execption --可选  在块里面当然可以try catch

end;     


2.实例2----打印hello wrold

set serveroutput on --打开输出选项
begin
  dbms_output.put_line('hello world'); //dbms_output是一个包,put_line是一个过程
end;


3.包含定义部分和执行部分
declare
  v_ename varchar2(5);   //相当于String ename;
  v_sal   number(7,2);
begin
  select ename ,sal into v_ename,v_sal from emp where empno=&no;
  dbms_output.put_line('雇员名:'||v_ename||'  工资'||v_sal);  
end;

&表示要接收从控制台输入的变量

注意:这里变量的目的是在多个执行部分可以用到,他可以跨越多条语句

------- 加上例外
注意:如果在控制台输入的参数,比如说empno=77在表里面查不到,那么就会将空值放到
变量里面去,那么会抛异常,注意,oracle中的exception块相当于java中的catch块,他不需要写try块
declare
  v_ename varchar2(5);   //相当于String ename;
  v_sal   number(7,2);
begin
  select ename ,sal into v_ename,v_sal from emp where empno=&no;
  dbms_output.put_line('雇员名:'||v_ename||'  工资'||v_sal);  
exception
when no_data_found then
dbms_output.put_line('朋友,你的编号输入有误');  
end;


4。块编程简单分类: 过程(存储过程),函数,触发器,包。也就是说这四种东西里面都有块


5。命名规范:
1。当定义变量时,建议用v_作为前缀v_sal
2.当定义常量,建议用c_做前缀c_rate
3.当定义游标时,建议用_cursot作为后缀,emp_cursor
4.当定义例外时,建议用e_作为前缀 e_error

6。如何调用
在数据库中可以这样调用: 
     exec sp_pro1(参数1,参数2)
或者
     call sp_pro1(参数1,参数2)
但是在java中调用存储过程只能用call.....

-------------------------存储过程----------------------------------------------------------
1.创建存储过程--存储过程中有块结构
create or replace procedure sp_pro1 is
 begin
  insert into mytest ('zwz','m1234');
 end;
 /   --斜杠的意思是执行

 但是出错了,我们通过show error可以查看错误信息
 
 SQL Statement ignored ,缺少select 关键字
 
 意思就是说我们这条sql少了些关键字,仔细观察,原来少了 values这个关键字
 
 改:create or replace procedure sp_pro1 is
 begin
  insert into mytest values('zwz','m1234');
 end;
 / 

2。// 注意,不应该指定类型大小 newSal number相当于 int newSal ,newSal number(3,2)相当于 Float f = new Float(); //分配空间了哈
create procedure sp_pro3(spName varchar2,newSal number) is
--下面就是按照块的规则写就是了
begin
  update emp set sal=newSal where ename=spName;
end;

--------------------输入与输出参数-------------------------------------------------
3。单个结果返回
//如果使用了out,那么就可以把它当做变量来使用,into到变量里面,在java中就可以拿到了
create or replace procedure sp_pro8
(spno in number,spName out varchar2) is
begin
 select ename into spName from emp where empno=spno; 
end;
在java中这样来拿值
CallableStatement cs = ct.prepareCall("{call sp_pro8(?,?)}");
cs.setInt(1,7788);//给第一个参数赋值
cs.registerOutParameter(2,oracle.jdbc.OracleTypes.VARCHAR);
cs.execute();
String name = cs.getString(2); //得到第二个参数的返回值


4。多结果集 ---使用游标,其实就是ResultSet

----返回一个List,而不是单个数据
由于oracle存储过程没有返回值,他的所有返回值都是通过out参数来替代的,
列表同样也不例外,但由于是集合,所以不能用一般的参数,必须要用package了,所以要分成两部分

create or replace package test1 as 
type test_cursor is ref cursor;
end test1;  //创建了一个包test1,在包里面声明了一个游标类型 test_cursor

create or replace package sp_pro9
(spNo in number,p_cursor out test1.test_cursor) is
begin
   open p_cursor for select * from emp where deptno = spNo;
end;

--如何在java中调用游标
CallableStatement cs = ct.prepareCall("{call sp_pro9(?,?)}");
cs.setInt(1,10);
cs.registeroutParameter(2,oracle.jdbc.OracleTypes.CURSOR);
cs.execute();

ResultSet rs = (ResultSet)cs.getObject(2); 


----------------------if/else--------------------------------------------------------
理论:

条件分支
if---then  对应  if(){}  其实then就相当于java中的{}
if---then--else 对应
 if(){
 }else{
 }
if---then--elsif---else  
对应 if(){
} else if(){
} else{}

1。if---then 例子

编写一个过程,可以输入一个雇员名,如果该雇员的工资低于2000,就给改雇员工资增加10%
create or replace procedure pro_sp4(spName varchar2) is

v_sal emp.sal%type;  --%type是变量定义的一种方法,v_StudentID students.id%type意思是:变量v_StudentID与表students中id字段的数据类型一致
begin
select sal into v_sal from emp where ename=spName;
if v_sal <2000 then
 update emp set sal=sal+sal*1.1 where ename=spName;
end if;
end;

2。if---then--else例子
编写一个过程,可以输入一个雇员名,如果该雇员的补助不是0就在原来的基础上增加100;如果补助为0
就把补助设为200
//create or replace procedure pro_sp4(spName in varchar2) is 这里比下面多了一个in,这个in是可以省略的,意思是可以输入
create or replace procedure pro_sp4(spName varchar2) is

v_comm emp.comm%type; 
begin
select comm into v_comm from emp where ename=spName;
if v_comm <> 0 then
 update emp set comm=comm+100 where ename=spName;
else
  update emp set comm=comm+200 where ename=spName;
end if;
end;

3。if---then--elsif---else例子

编写一个过程,可以输入一个雇员编号,如果该雇员的职位是president,就给他的工资增加1000,如果该雇员的职位是manager就给他的工资加500,其他雇员加200

create or replace procedure sp_pro6(spNo number) is
v_job emp.job%type;
begin

 select job into v_job from emp where empno=spNo;
 if v_job = 'president' then
   update emp set sal = sal+1000 where empno = spNo;
 elsif v_job='manager' then
   update emp set sal = sal+500 where empno = spNo;
 else
   update emp set sal = sal + 200 where empno = spNo;
 end if;
 
end;


-------------------case when--then end case-----------------------------------------------------------------
SQL> declare
  2   v_sal emp.sal%type;
  3   v_ename emp.ename%type;
  4  begin
  5    select ename,sal into v_ename,v_sal from emp
  6    where empno=&emp_no;
  7   case
  8      when v_sal<1000 then
  9       update emp
 10        set comm=100
 11       where ename=v_ename;
 12      when v_sal<2000 then
 13       update emp
 14        set comm=80
 15        where ename=v_ename;
 16      when v_sal<6000 then
 17        update emp
 18         set comm=50
 19        where ename=v_ename;
 20      end case;
 21  end;
 22  /
原值    6:   where empno=&emp_no;
新值    6:   where empno=7369;



------------------------循环----------------------------------------------------

理论:
循环:
for    ---for 

do{}       ---相当于loop---exit when
while();

while(){}  ---相当于 while ---loop

1。loop---exit when例子

编写一个过程,可以输入用户名,并循环添加10个用户到users表中,用户编号从1开始增加
create or replace procedure sp_pro7(spName varchar2) is
--定义
v_num number := 1;
--执行
begin
  loop
    insert into users values(v_num,spName);
    --判断循环是否退出
    exit when v_num=10;
    --自增
    v_num:=v_num+1;
  end loop;

end;

2。while ---loop例子

create or replace procedure sp_pro7(spName varchar2) is
--定义
v_num number := 1;
--执行
begin
  while v_num <=20 loop
     insert into users values(v_num,spName);
     v_num = v_num+1;
  end loop;

end;

3。for例子

--for的好处是不用定义变量,而且也是隐含的i++ ,相当于java中的增强for
begin 
  for i in reverse 1..10 loop
    insert into users values(i,'zwz');
  end loop;  
end;

SQL> declare result int;
  2  begin
  3    for i in 1..5 loop
  4      for j in 1..5 loop
  5        result:=i*j;
  6       exit when result=100;
  7       exit when result=50;
  8      end loop;
  9     dbms_output.put_line(result);
 10    end loop;
 11  end;
 12  /

--顺序控制语句---goto(不建议使用,破坏了封装,相当于汇编语言的特性),null
SQL> declare i int:=1;
  2  begin
  3    loop
  4      insert into temp values(i);
  5      if i=20 then  goto end_loop;  --这里goto 到end_loop标签下面
  6      end if;
  7      i:=i+1;
  8     end loop;
  9    <<end_loop>> ---直接跳到这个标签这里了
 10   dbms_output.put_line('循环结束');
 11  end;
 12  /



null语句只是为了提高程序的可读性
SQL> run
  1  declare
  2  v_sal emp.sal%type;
  3  v_ename emp.ename%type;
  4  begin
  5  select ename,sal into v_ename,v_sal from emp
  6   where empno=&emp_no;
  7   if v_sal<3000 then
  8    update emp
  9     set comm=sal*0.1
 10    where ename=v_ename;
 11  else
 12    null; --否则什么也不做
 13  end if;
 14* end;
if v_sal < 3000 then
.....;
else 
 null;   --其实这里的else null;完全可以不用
 end if;  

------------------------execption-------------------------------------------------------

SQL> set serveroutput on
SQL> declare
  2    emp_name emp.ename%type;
  3  begin
  4    select ename into emp_name from emp;
  5  EXCEPTION
  6    when too_many_rows then
  7     dbms_output.put_line('出错了,不允许返回多行!');
  8  end;
  9  /
when too_many_rows then  ---返回多行
when no_data_found then   ---数据不存在
 when value_error then   ----值不合法,比如我要一个int你给我一个varchar,我要5位,你给我7位 dbms_output.put_line('要存储在姓名中的值过长');


自定义异常
SQL>  declare
  2    sal_error  exception; ---申明异常
  3    emp_comm   emp.comm%type;
  4  begin
  5   select NVL(comm,0) into emp_comm from emp
  6    where empno=&emp_no;
  7   if emp_comm>1000 then
  8     raise sal_error;  ----抛出
  9   end if;
 10  EXCEPTION
 11    when sal_error then  ---接住
 12      dbms_output.put_line('奖金超出范围');
 13* end;

引发应用程序错误:
SQL> declare
  2     emp_no  emp.empno%type;
  3     emp_comm emp.comm%type;
  4     comm_exception  exception;
  5  begin
  6    emp_no:=7369;
  7    select nvl(comm,0) into emp_comm from emp
  8    where empno=emp_no;
  9   if emp_comm=0 then
 10     raise comm_exception;
 11   else
 12     dbms_output.put_line('奖金为:' || emp_comm );
 13   end if;
 14  EXCEPTION
 15    when comm_exception then
 16       raise_application_error(-20001,'未指定奖金的值'); --直接抛给java
 17  end;
 18  /
在oracle端的效果是
*
ERROR 位于第 1 行: 
ORA-20001: 未指定奖金的值
ORA-06512: 在line 16 


分享到:
评论

相关推荐

    oracle-instantclient12.1-basic-12.1.0.2.0-1.x86_64.rpm

    Oracle Instant Client支持多种编程语言的数据库连接,如C、C++、Java和Python等,通过其提供的API接口,开发者可以构建自己的数据库应用。同时,它还提供了ocijdbc.jar,使得Java开发者可以使用JDBC(Java Database...

    oracle-instantclient.11.2.zip

    - ODBC (Open Database Connectivity):提供了一个标准的应用程序编程接口,使得不同平台上的应用程序可以访问Oracle数据库。 - JDBC (Java Database Connectivity):Java API,让Java应用程序能够与Oracle数据库...

    oracle-instantclient11.2-devel-和-sqlplus.rpm.zip

    Oracle Instant Client是Oracle公司提供的一款轻量级的数据库连接工具,它允许应用程序无需完整安装Oracle Database Server即可与Oracle数据库...正确安装和配置后,开发者可以高效地进行Oracle数据库相关的编程工作。

    cx_Oracle-5.2.1-11g.win-64--py2.7.exe.zip

    它支持Oracle的所有主要特性,包括游标、事务管理、PL/SQL块执行、绑定变量、批量操作、LOB处理等。cx_Oracle的安装通常涉及到下载对应的二进制文件,如提供的cx_Oracle-5.2.1-11g.win-amd64-py2.7.exe,然后在...

    oracle-instantclient11.2-sqlplus-11.2.0.4.0-1.x86_64

    1. **oci.dll/oci.so**:Oracle Call Interface (OCI) 库,它是Oracle数据库编程接口,用于C/C++应用程序与Oracle数据库之间的通信。 2. **sqlplus**:这是一个命令行工具,允许用户直接执行SQL语句和PL/SQL块,...

    oracle-instantclient-21

    SQL*Plus是Oracle提供的一个命令行工具,用于执行SQL查询、PL/SQL块以及数据库管理任务。通过这个组件,用户可以直接在命令行界面中输入SQL语句,执行查询、创建表、备份数据等操作。21.3.0.0.0版本的SQL*Plus包含了...

    cx_Oracle-6.1.tar.gz

    在Python编程中,与各种数据库的交互是常见的需求之一,其中Oracle数据库作为大型企业级数据库系统,其稳定性和性能得到了广泛认可。cx_Oracle库就是专门为Python设计的一个接口,使得Python程序员能够方便地连接和...

    oracle-PROC编程学习笔记

    Oracle PROC允许程序员在C程序中嵌入PL/SQL代码,通过预编译过程将PL/SQL块转换为C函数或过程,然后在C程序中调用这些函数,从而实现高效的数据访问和处理。这种方式不仅提高了性能,还能利用C语言的灵活性和控制力...

    Oracle PL-SQL编程详解.pdf

    Oracle PL/SQL编程详解主要涵盖了数据库编程的关键方面,旨在帮助开发者深入理解如何利用PL/SQL进行高效、模块化的数据库应用开发。PL/SQL是Oracle数据库系统专用的一种过程化编程语言,它结合了SQL的查询能力并扩展...

    oracle-database-11g-plsql-编程实战笔记.doc

    ### Oracle Database 11g PL/SQL 编程实战知识点 #### 1. SQL 命令分类 在 Oracle Database 11g 中,SQL 命令主要分为以下几类: - **DML(Data Manipulation Language)数据操作语言**: - `SELECT`:用于从...

    Oracle-PLSQL-编程语法详解-触发器.docx

    Oracle PL/SQL 中的触发器是数据库管理系统中一种强大的工具,用于响应特定的数据库事件并自动执行预定义的代码块。触发器与存储过程相似,都是包含PL/SQL代码的逻辑单元,但触发器的执行是隐式的,由特定的数据库...

    Oracle--vb代码.rar

    5. 错误处理:VB提供了`On Error`语句进行错误处理,当发生错误时,程序会跳转到指定的错误处理代码块。 6. 连接池管理:为了提高性能,VB可以使用连接池。这允许重复使用已打开的数据库连接,而不是每次需要时都...

    oracle-plsql编程

    Oracle PL/SQL编程是Oracle数据库系统中的核心编程语言,它结合了SQL的查询能力与过程式编程语言的特点,使得开发者能够编写复杂的业务逻辑和数据库操作。在这个“Oracle PL/SQL编程”的主题中,我们将深入探讨PL/...

    oracle-instantclient-11.2客户端

    2. **OCI**:Oracle Call Interface是Oracle数据库提供的C语言编程接口,让开发者可以在C或C++程序中直接调用Oracle数据库功能。oci.h头文件和对应的库文件是实现这个接口的关键。 3. **ODBC**:作为数据库独立的...

    oracle-ocjp808-题库.zip

    Oracle Certified Professional, Java SE 8 Programmer (OCJP 8) 是Java开发人员广泛认可的一项专业认证,它证明了持证者对Java编程语言有深入的理解和熟练的应用能力。"oracle-ocjp808-题库.zip" 文件显然包含了与...

    Oracle-PLSQL编程.ppt

    Oracle PL/SQL 编程 Oracle PL/SQL 是 Oracle 大型数据库技术中的一个核心组件,是一种高级程序设计语言,专门为 Oracle 数据库而设计。PL/SQL 语言是对标准 SQL 语言进行了过程化扩展的语言,具有模块化的程序设计...

    DBD-Oracle-1.28.tar

    DBD::Oracle 是Perl编程语言中用来连接和操作Oracle数据库的模块。这个模块允许Perl程序员使用DBI接口来执行SQL查询、事务处理、游标操作等,提供了与Oracle数据库进行交互的高效且灵活的方法。在DBD::Oracle中,你...

    oracle-instantclient11.2.rar

    - "oracle-instantclient11.2-sqlplus-11.2.0.4.0-1.x86_64.rpm" 包含了SQL*Plus,这是一个命令行工具,用户可以使用它来执行SQL语句、PL/SQL块以及管理Oracle数据库。SQL*Plus是数据库管理员和开发人员常用的工具...

Global site tag (gtag.js) - Google Analytics