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分鍾。呵呵......