orcl存储过程定义数组
① java调用存储过程,Oracle自定义类型作参数怎么写法
1. 存储过程以及类型定义如下:
--The array in oracle
CREATE OR REPLACE TYPE idArray AS TABLE OF VARCHAR2(20);
--package header
CREATE OR REPLACE PACKAGE Lib_Package AS
PROCEDURE Book_Check_Procere(ids IN idArray, exist OUT NUMBER);
END Lib_Package;
--package body
CREATE OR REPLACE PACKAGE BODY Lib_Package AS
PROCEDURE Book_Check_Procere( ids IN idArray, exist OUT NUMBER) AS v_Index BINARY_INTEGER; BEGIN v_Index:= ids.FIRST; LOOP SELECT COUNT(*) INTO exist FROM Lib_Duplicate WHERE status='Lent' AND book_id=ids(v_Index); EXIT WHEN v_Index=ids.LAST OR exist>0; v_Index:= ids.NEXT(v_Index); END LOOP;END Book_Check_Procere;
END Lib_Package;
2.在Java中调用上面的存储过程
(1) 在Oracle中定义数组类型idArray (2) 在java构造数组并转换成Oracle中定义的数组类型,调用存储过程
/** * 当要删除图书时,检查是否仍然有图书复本处于借出状态 */ public boolean checkBookStatus(String[] bookIds) throws DataAccessException {
boolean flag = false; Connection conn = null; OracleCallableStatement cstmt = null; ArrayDescriptor desc = null; ARRAY bookIdArray = null; int count = 0; String sql = "{call LIB_PACKAGE.Book_Check_Procere(?,?)}";
DbDriverManager dbManager = DbDriverManager.getInstance(); conn = dbManager.getConnection(Constants.DATABASE);
try { cstmt = (OracleCallableStatement) conn.prepareCall(sql);
//定义oracle中的数组类型 desc = ArrayDescriptor.createDescriptor("IDARRAY", conn); bookIdArray = new ARRAY(desc, conn, bookIds);
cstmt.setObject(1, bookIdArray, oracle.jdbc.OracleTypes.ARRAY); cstmt.registerOutParameter(2, Types.INTEGER); cstmt.execute(); count = cstmt.getInt(2);
log.info(this.getClass() + ".checkBookStatus: count = " + count);
DbOperHelp.closeStatement(this.getClass(), cstmt); DbOperHelp.closeConnection(this.getClass(), conn); } catch (SQLException e) {
log.error(this.getClass() + ".checkBookStatus-->SQLException: " + e.getMessage()); DbOperHelp.closeStatement(this.getClass(), cstmt); DbOperHelp.closeConnection(this.getClass(), conn); throw new DataAccessException( "When check the books, there is a SQLException: " + e.getMessage(), e.getCause()); }
if (count > 0) {
flag = true; }
return flag; }
② WebService调用oracle存储过程,传入数组参数
你要在webservice中编写相应的调用存储过程的接口,具体看你应用的什么语言技术。比如下面java调用存储过程如下:
Session session = HibernateSessionFactory.getSession();
//连接对象
Connection conn = null;
//数据集对象
ResultSet rs = null;
//用来取得表列明的 对象
ResultSetMetaData rsmd = null;
CallableStatement proc = null;
conn = session.connection();
conn.setAutoCommit(false);
try {
if (conn != null) {
proc = conn.prepareCall("{call 存储过程包名过程名(n个传入参数对应n个问号,返回参数或游标?占位) }");
// 如下过程PKG_GETDATA有4个传入参数,所有在程序包是PKG_QUERY
//proc = conn.prepareCall("{call PKG_QUERY.PKG_GETDATA(?,?,?,?,?) }");
proc.setString(1, 参数);
//依次按照传入参数顺序与?问号位置传入所有参数
//最后传入n个参数后一位的返回游标
//proc.registerOutParameter(n+1, oracle.jdbc.OracleTypes.CURSOR);
proc.execute();
rs = (ResultSet) proc.getObject(n+1);
conn.commit();
}
可以将上面代码写成一个公用的调用存储过程的通用接口。
别人调用你的webservice 可以具体的参数个数及顺序传递给你的接口,也可以传递一个object数组
③ oracle 存储过程 数组循环
declare
type typ_rec is record of (student.name%type, student.age%type); --集合变量
type typ_tab is table of typ_rec index by binary_integer; --以集合变量为单位的table数组
rec_sql typ_rec;
another_rec student%rowtype; --跟rec_sql一样
begin
--for循环里的rec_tmp不用定义,可以自动生成的
for rec_tmp in (select t.name, t.age from student t) loop
dbms_output.putline(rec_tmp.name || ' ''s age + 1 = ' || to_char(rec_tmp.age + 1) );
end loop;
exception
when others then
return;
end;
④ oracle 存储过程,如何传入一个数组
这个是不行的,数组内容必须首先在存储过程里定义好数组类型,然后给予定义好的数据类型定义数组型变量。存储过程的入参是做不到的。一般情况下,采用字符串的方式,并给每项用特定的分隔符的方式传入,然后在存储过程中按照分隔符解析出每一项,插到存储过程的定义的数组的每一项上去。
⑤ 【SQL】存储过程中如何定义数组
存储过程里定义不了数组。如果是sqlserver,那么你可以用表变量,游标来实现你的功能。
如果是sqlserver2005以上的版本,可以做clr存储过程,那里面是可以用数组的。
⑥ 关于oracle 存储过程 如何切割一个字符串 转化为字符数组,然后遍历该数组: 类似ab,12;cd,55;k,7
给你写了个包,包体代码如下:
CREATE OR REPLACE PACKAGE BODY Pkg_Bai IS
-- 自定义个数组类型
TYPE Typ_Str_Array IS TABLE OF VARCHAR2(200) INDEX BY BINARY_INTEGER;
PROCEDURE Prc_String_To_Array(Pv_i_String IN VARCHAR2,
Pv_i_Identifier IN VARCHAR2,
Pt_o_Array OUT Typ_Str_Array) IS
Lv_Tmpstr VARCHAR2(200);
Lv_Changed_String VARCHAR2(4000);
BEGIN
-- 初始化
Lv_Changed_String := Pv_i_String;
-- 拆分逻辑
-- 1.字符串中没有标识符
IF Instr(Pv_i_String, Pv_i_Identifier, 1, 1) = 0 THEN
Pt_o_Array(Pt_o_Array.Count + 1) := Pv_i_String;
ELSE
-- 2.字符串中有标识符
WHILE Instr(Lv_Changed_String, Pv_i_Identifier, 1, 1) > 0 LOOP
Lv_Tmpstr := Substr(Lv_Changed_String,
1,
Instr(Lv_Changed_String, Pv_i_Identifier, 1, 1) - 1);
Pt_o_Array(Pt_o_Array.Count + 1) := Lv_Tmpstr;
Lv_Changed_String := Substr(Lv_Changed_String,
Instr(Lv_Changed_String, Pv_i_Identifier, 1, 1) + 1,
Length(Lv_Changed_String));
END LOOP;
-- 3.最有一个被拆分出来的字符串中不含标识符
IF NOT Lv_Changed_String IS NULL THEN
-- 将最后一个保存
Pt_o_Array(Pt_o_Array.Count + 1) := Lv_Changed_String;
END IF;
END IF;
EXCEPTION
WHEN OTHERS THEN
NULL;
END;
PROCEDURE Prc_Test(Pv_i_Str IN VARCHAR2) IS
--定义数组
Lt_Array Typ_Str_Array;
Ln_Count NUMBER; -- 数组元素个数
Ln_Num NUMBER;
Lv_Value VARCHAR2(30);
BEGIN
Prc_String_To_Array(Pv_i_Str, ';', Lt_Array);
-- 循环数组
FOR i IN 1 .. Lt_Array.Count LOOP
-- 获取每个元素中数值
Ln_Num := To_Number(TRIM(Substr(Lt_Array(i), Instr(Lt_Array(i), ',', -1) + 1)));
IF Ln_Num > 20 THEN
Lv_Value := TRIM(Substr(Lt_Array(i), 1, Instr(Lt_Array(i), ',', -1) - 1));
INSERT INTO a (col_a) VALUES (lv_value);
END IF;
END LOOP;
END;
END Pkg_Bai;
调用Prc_Test来分隔字符串并按要求比较后插入a表。我测试过,没有问题。
需要注意的是,数据的要求:字符串中每组数据间使用英文小写分号分隔,同一组数据字母在前,数字在后,以英文小写逗号分隔。测试一下吧。
欢迎采纳,不采纳你都对不起我这20分钟。呵呵......