论坛首页 入门技术论坛

Oracle存储过程学习

浏览 72785 次
精华帖 (3) :: 良好帖 (3) :: 新手帖 (0) :: 隐藏帖 (2)
作者 正文
   发表时间:2008-12-07  

存储过程创建语法:

       create or replace procedure 存储过程名(param1 in type,param2 out type)

as

变量1 类型(值范围);

变量2 类型(值范围);

Begin

    Select count(*) into 变量1 from 表A where列名=param1;

    If (判断条件) then

       Select 列名 into 变量2 from 表A where列名=param1;

       Dbms_output。Put_line(‘打印信息’);

    Elsif (判断条件) then

       Dbms_output。Put_line(‘打印信息’);

    Else

       Raise 异常名(NO_DATA_FOUND);

    End if;

Exception

    When others then

       Rollback;

End;

 

注意事项:

1,  存储过程参数不带取值范围,in表示传入,out表示输出

2,  变量带取值范围,后面接分号

3,  在判断语句前最好先用count(*)函数判断是否存在该条操作记录

4,  用select 。。。into。。。给变量赋值

5,  在代码中抛异常用 raise+异常名

 

 

以命名的异常

命名的系统异常                          产生原因

ACCESS_INTO_NULL                   未定义对象

CASE_NOT_FOUND                     CASE 中若未包含相应的 WHEN ,并且没有设置

ELSE 时

COLLECTION_IS_NULL                集合元素未初始化

CURSER_ALREADY_OPEN          游标已经打开

DUP_VAL_ON_INDEX                   唯一索引对应的列上有重复的值

INVALID_CURSOR                 在不合法的游标上进行操作

INVALID_NUMBER                       内嵌的 SQL 语句不能将字符转换为数字

NO_DATA_FOUND                        使用 select into 未返回行,或应用索引表未初始化的 

 

TOO_MANY_ROWS                      执行 select into 时,结果集超过一行

ZERO_DIVIDE                              除数为 0

SUBSCRIPT_BEYOND_COUNT     元素下标超过嵌套表或 VARRAY 的最大值

SUBSCRIPT_OUTSIDE_LIMIT       使用嵌套表或 VARRAY 时,将下标指定为负数

VALUE_ERROR                             赋值时,变量长度不足以容纳实际数据

LOGIN_DENIED                           PL/SQL 应用程序连接到 oracle 数据库时,提供了不

正确的用户名或密码

NOT_LOGGED_ON                       PL/SQL 应用程序在没有连接 oralce 数据库的情况下

访问数据

PROGRAM_ERROR                       PL/SQL 内部问题,可能需要重装数据字典& pl./SQL

系统包

ROWTYPE_MISMATCH                宿主游标变量与 PL/SQL 游标变量的返回类型不兼容

SELF_IS_NULL                             使用对象类型时,在 null 对象上调用对象方法

STORAGE_ERROR                        运行 PL/SQL 时,超出内存空间

SYS_INVALID_ID                         无效的 ROWID 字符串

TIMEOUT_ON_RESOURCE         Oracle 在等待资源时超时 

   发表时间:2008-12-31  
请教如何用JDBC给存储过程传递数组类型的参数
0 请登录后投票
   发表时间:2008-12-31   最后修改:2008-12-31
yingxiongwudi 写道
请教如何用JDBC给存储过程传递数组类型的参数

以前的笔记......

A . 嵌套表

1. 声明数组类型
       create or replace type tab_array is table of varchar2(38);暂时不要在包中声明该类型

2. 创建存储过程
         -- 该例子存储过程是在包中创建的,包名 arraydemo
         procedure testArray(resNumber in tab_array,procResult out tab_array) is
         begin
             procResult := new tab_array();
             for i in 1..resNumber.Count loop
                procResult.EXTEND;
                procResult(i) := resNumber(i) || 'lucifer' || i;
             end loop;
         end;

3. Java调用代码
    //必须使用Oracle的连接和Statement,使用了连接池的必须通过一些方法获取原始的连接
    OracleConnection conn = null;
    OracleCallableStatement stmt = null;
    String[] param = { "1001", "1002", "1006" };
    stmt =(转换类型) conn.prepareCall("{call arraydemo.testArray(?,?)}");
    // 类型名必须大写
    ArrayDescriptor descriptor = ArrayDescriptor.createDescriptor("TAB_ARRAY", conn);
    stmt.setARRAY(1, new ARRAY(descriptor,conn,param));
    stmt.registerOutParameter(2, OracleTypes.ARRAY, "TAB_ARRAY");
    stmt.execute();
  
    ARRAY array = stmt.getARRAY(2);
    Datum[] data = array.getOracleArray();
    for (int i = 0; i < data.length; i++) {
        System.out.println(i + " : " + new String(data.shareBytes()));
    }
4 . 注意的问题及尚未解决的问题
    抛出:Non supported character set: oracle-character-set-852 异常---解决:添加 nls_charset12.jar 到classpath,该包在oracle/ora92/jdbc/lib目录下
    待解决问题:
    a) 如何调用在包声明的自定义类型
    b) 比较不同声明类型的优缺点,及使用场合
    嵌套表其它应用:http://zhouwf0726.itpub.net/post/9689/212253

B . 索引表
C . 内置数组
D . 游标方式
0 请登录后投票
   发表时间:2009-01-04  
yingxiongwudi 写道
请教如何用JDBC给存储过程传递数组类型的参数

import java.sql.*;

public class DBDeclareTest{
private Connection con = null;// 数据库连接
private java.sql.CallableStatement cs = null;//执行存储过程的接口

private int key;
private String name;

//在构造函数中构造连接
public DBDeclareTest(){
try {
Class.forName("com.microsoft.jdbc.sqlserver.SQLServerDriver");
con = DriverManager.getConnection("jdbc:microsoft:sqlserver://127.0.0.1:1433;databasename=pubs","sa","");
System.out.println ("con ok");
    }
    catch (Exception ex) {
    ex.printStackTrace();
    }
}

//调用无返回值的存储过程
public void getOK1(){
try {
String sql="{call pro_mypro1(?,?)}";
cs = con.prepareCall(sql);
cs.setInt(1,key);
cs.setString(2,name);
cs.executeUpdate();
System.out.println ("执行成功,可以休息了。。。。");
cs.close();
con.close();
    }
    catch (Exception ex) {
    ex.printStackTrace();
    }

}
//调用有返回值的存储过程
public void getOK2(){
try {
String sql = "{call pro_mypro2(?,?)}";
cs = con.prepareCall(sql);
//设置output外部传参
cs.registerOutParameter(1,java.sql.Types.BIT);
cs.setString(2,name);
cs.execute();
//获得output外部传参的值
int numOut = cs.getInt(1);
if(numOut ==1){
System.out.println ("数据表存在");
}else{
System.out.println ("数据表不存在!!!");
}
cs.close();
con.close();
    }
    catch (Exception ex) {
    ex.printStackTrace();
    }
}

//返回结果集的存储过程
public void getOK3(){
try {
String sql = "{call pro_mypro3(?,?)}";
cs = con.prepareCall(sql);
//设置output外部传参
cs.registerOutParameter(1,java.sql.Types.BIT);
cs.setString(2,name);
boolean flag = cs.execute();
System.out.println (flag);
if(flag){
System.out.println ("OKOKOKO");
ResultSet rs = cs.getResultSet();
ResultSetMetaData rsmd =rs.getMetaData();
     int numberOfColumns = rsmd.getColumnCount();
while(rs.next()){
for(int i=0;i<numberOfColumns;i++)
{
System.out.println (rsmd.getColumnName(i)+"  ");
System.out.println (rs.getObject(i)+"  ");
}
}
}else
{
System.out.println ("表名不存在:"+cs.getBoolean(1));
}
cs.close();
con.close();
    }
    catch (Exception ex) {
    ex.printStackTrace();
    }
}

public void setKey(int k){
this.key = k;
}
public int getKey(){
return this.key;
}
public void setName(String n){
this.name = n;
}
public String getName(){
return this.name;
}

}
0 请登录后投票
   发表时间:2009-02-13  
呵呵 存储过程还是不太明白 。。。。谢谢  回去慢慢研究
0 请登录后投票
   发表时间:2009-03-10  
songze39 写道

存储过程创建语法:

       create or replace procedure 存储过程名(param1 in type,param2 out type)

as

变量1 类型(值范围);

变量2 类型(值范围);

Begin

    Select count(*) into 变量1 from 表A where列名=param1;

    If (判断条件) then

       Select 列名 into 变量2 from 表A where列名=param1;

       Dbms_output。Put_line(‘打印信息’);

    Elsif (判断条件) then

       Dbms_output。Put_line(‘打印信息’);

    Else

       Raise 异常名(NO_DATA_FOUND);

    End if;

Exception

    When others then

       Rollback;

End;

 

注意事项:

1,  存储过程参数不带取值范围,in表示传入,out表示输出

2,  变量带取值范围,后面接分号

3,  在判断语句前最好先用count(*)函数判断是否存在该条操作记录

4,  用select 。。。into。。。给变量赋值

5,  在代码中抛异常用 raise+异常名

 

 

以命名的异常

命名的系统异常                          产生原因

ACCESS_INTO_NULL                   未定义对象

CASE_NOT_FOUND                     CASE 中若未包含相应的 WHEN ,并且没有设置

ELSE 时

COLLECTION_IS_NULL                集合元素未初始化

CURSER_ALREADY_OPEN          游标已经打开

DUP_VAL_ON_INDEX                   唯一索引对应的列上有重复的值

INVALID_CURSOR                 在不合法的游标上进行操作

INVALID_NUMBER                       内嵌的 SQL 语句不能将字符转换为数字

NO_DATA_FOUND                        使用 select into 未返回行,或应用索引表未初始化的 

 

TOO_MANY_ROWS                      执行 select into 时,结果集超过一行

ZERO_DIVIDE                              除数为 0

SUBSCRIPT_BEYOND_COUNT     元素下标超过嵌套表或 VARRAY 的最大值

SUBSCRIPT_OUTSIDE_LIMIT       使用嵌套表或 VARRAY 时,将下标指定为负数

VALUE_ERROR                             赋值时,变量长度不足以容纳实际数据

LOGIN_DENIED                           PL/SQL 应用程序连接到 oracle 数据库时,提供了不

正确的用户名或密码

NOT_LOGGED_ON                       PL/SQL 应用程序在没有连接 oralce 数据库的情况下

访问数据

PROGRAM_ERROR                       PL/SQL 内部问题,可能需要重装数据字典& pl./SQL

系统包

ROWTYPE_MISMATCH                宿主游标变量与 PL/SQL 游标变量的返回类型不兼容

SELF_IS_NULL                             使用对象类型时,在 null 对象上调用对象方法

STORAGE_ERROR                        运行 PL/SQL 时,超出内存空间

SYS_INVALID_ID                         无效的 ROWID 字符串

TIMEOUT_ON_RESOURCE         Oracle 在等待资源时超时 

 

0 请登录后投票
   发表时间:2009-03-15  
 
0 请登录后投票
   发表时间:2009-03-15  
看样子挺复杂的啊
0 请登录后投票
   发表时间:2009-04-03  
用select count(1)比较好,如果只是单纯记录记录条数。
0 请登录后投票
   发表时间:2009-04-26  
pl/sql 的基本语法不是这样吗?
DECLARE
   声明部分;
BEGIN
   执行部分;
EXCEPTION
   异常处理部分;
END;

怎么开始是 create or  replace?/??   why? 不明白?新手の
0 请登录后投票
论坛首页 入门技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics