Oracle 存儲過程—為數傳遞變量


oracle 存儲過程的基本語法
create or replace procedure proc1(
p_para1 varchar2,
p_para2 out varchar2,
p_para3 in out varchar2
)as
v_name varchar2(20);
begin
v_name := '張三豐';
p_para3 := v_name;
dbms_output.put_line('p_para3:'||p_para3);
end;
注:創建語句:create or replace procedure 存儲過程名,如果沒有or replace語句,則僅僅是新建一個存儲過程。如果系統存在該存儲過程,則會報錯。Create or replace procedure 如果系統中沒有此存儲過程就新建一個,如果系統中有此存儲過程則把原來刪除掉,重新創建一個存儲過程。 
存儲過程名定義:包括存儲過程名和參數列表。參數名和參數類型。參數名不能重復, 參數傳遞方式:IN, OUT, IN OUT 
IN 表示輸入參數,按值傳遞方式。 
OUT 表示輸出參數,可以理解為按引用傳遞方式。可以作為存儲過程的輸出結果,供外部調用者使用。 
IN OUT 即可作輸入參數,也可作輸出參數。 
參數的數據類型只需要指明類型名即可,不需要指定寬度。 
參數的寬度由外部調用者決定。 
過程可以有參數,也可以沒有參數 
變量聲明塊:緊跟着的as (is )關鍵字,可以理解為pl/sql的declare關鍵字,用於聲明變量。 
變量聲明塊用於聲明該存儲過程需要用到的變量,它的作用域為該存儲過程。另外這里聲明的變量必須指定寬度。遵循PL/SQL的變量聲明規范。 
過程語句塊:從 begin 關鍵字開始為過程的語句塊。存儲過程的具體邏輯在這里來實現。 
異常處理塊:關鍵字為exception ,為處理語句產生的異常。該部分為可選 
結束塊:由end關鍵字結果。

示例:

create or replace procedure sp_name (
-- 入參、出參列表, 逗號分隔。
uid in varchar2, -- 不能帶長度信息
startDate in date, -- 第二個輸入參數
defaultVar in varchar2 default "", -- 默認參數,如果不傳,要注意參數的順序
isok out number, -- 輸出參數
result out varchar2 -- 第二個輸出參數
)
as
-- 變量聲明,每個聲明用分號結束,可以在聲明的同時初始化
var1 varchar2(11);
var2 number(2) := 123;

begin
-- 字符串拼接用 ||
dbms_output.put_line('isok:' || 'abc');

-- 調用其他存儲過程
sub_sp_name(param1, prarm2, outParam1, outParam2);

end; -- 存儲過程結束
---------------------

--1. 語句塊的定義

declare
  -- 變量聲明
  var1 number(2); -- 僅聲明
  var2 char(2) := 'var2'; -- 在聲明的同時初始化

begin
  -- 語句
end; -- 語句塊結束

--2. if語句

 

if a = 1 or b = 2 then
  
elsif c = 3 then

else
  
end if;

 

 

 

 

 

--3.  case分支控制語句

這里的dbms_output.put_line() 是輸出的方法,在dos里需要在這之前輸入set serveroutput on;才會輸出相應的信息

 

declare
num number(10) := 11;
begin
    case 
        when num = 10 then dbms_output.put_line( '我是10');
        when num = 11 then dbms_output.put_line( '我是11');
        else  dbms_output.put_line( '我不知道我是誰了');
    end case;
    
    case num
        when 0 then dbms_output.put_line( '我是10');
        when 1 then dbms_output.put_line( '我是11');
        else  dbms_output.put_line( '我不知道我是誰了');
    end case;
end;

 

 

 

 

 

--4. for 循環 
--for循環主要有兩個用處。

--4.1、 循環一個范圍
  declare
    i number(2);
  begin
    for i in 0 .. 9 loop
      dbms_output.put_line('i:' || i);
    end loop;
  end;

-- 4.2、遍歷隱式游標

 --隱式游標的好處是不需要手動關閉,方便

BEGIN
 FOR re IN (SELECT username FROM userinfo)  LOOP
  DBMS_OUTPUT.PUT_LINE(re.username);
 END LOOP;
END;


二、下面是存儲過程的使用:

我這里創建了一個表userinfo,

-- Create table創建表
create table userinfo
(
  id       varchar2(32) not null,
  username varchar2(20),
  password varchar2(20),
  sex      varchar2(2),
  sal number(20),
  insertdate date default sysdate
)
;
-- Add comments to the columns 
comment on column userinfo.id
  is 'id';
comment on column userinfo.username
  is '用戶名';
comment on column userinfo.password
  is '密碼';
comment on column userinfo.sex
  is '性別';
  comment on column userinfo.sal
  is '工資';
  comment on column userinfo.insertdate
  is '插入時間';

 

2.1創建插入數據的存儲過程並調用

 

CREATE OR REPLACE
--創建存儲過程,如果存在就更新,不存在就創建,插入一條數據
procedure proc_test(e_id       in varchar,
                    e_username in varchar,
                    e_password in varchar,
                    e_sex      in varchar,
                    e_sal      in number)
--這里的參數不要限定長度,否則會錯誤
 is
begin
  insert into userinfo
    (id, username, password, sex, sal)
  values
    (e_id, e_username, e_password, e_sex, e_sal);
end;

  --調用1
DECLARE
  id       varchar(32);
  username varchar(20);
  password varchar(20);
  sex      varchar(2);
  sal      number(20);
BEGIN
  id       := 'asdfasdfa';
  username := 'text11';
  password := 'pas';
  sex      := '男';
  sal      := 2000;
  proc_test(e_id       => id,
            e_username => username,
            e_password => password,
            e_sex      => sex,
            e_sal =>sal);
  commit;
END;

select * from userinfo;--查看數據插入成功

 

 

 

 

 

 

---調用2
begin
  proc_test(e_id => 'dd', e_username => 'A',e_password => 'aa', e_sex => 'd',e_sal => 1000);
  commit;
end;
--調用3
call  proc_test(e_id => 'dd', e_username => 'A',e_password => 'aa', e_sex => 'd',e_sal => 1000);
commit;

 

 

 

java中的調用:

 

public static void insert() throws ClassNotFoundException, SQLException {
		String url = "jdbc:oracle:thin:@localhost:1521:orcl";
		String name = "user2";
		String pwd = "user2";
		String Drivername = "oracle.jdbc.driver.OracleDriver";
		Class.forName(Drivername);
		Connection connection = DriverManager.getConnection(url, name, pwd);
		CallableStatement call = connection
				.prepareCall("call PROc_TEST(e_id => 'dd', e_username => 'A',e_password => 'aa', e_sex => 'd',e_sal => 1000)");
		// 執行存儲過程
		boolean b = call.execute();
		if (b = true) {
			System.out.println("插入成功!");
		}
		connection.close();
	}

 

 

 

 

--2. 創建帶返回參數的

 

--in是輸入入的參數,out是輸出的參數
   CREATE OR REPLACE procedure proc_test1(t in varchar,
                                                       r out varchar) as
   begin
     
     select count(*) into r from userinfo where username like t;
   end;
--調用,
 --在dos里執行多行語句是以'/'表示結束
  DECLARE outobj VARCHAR2(4);
       BEGIN
             proc_test1(t => 'A',r => outobj );
               dbms_output.put_line('outobj = ' || outobj);
       END;

java中的調用:

 

public static void one() throws ClassNotFoundException, SQLException {
		String url = "jdbc:oracle:thin:@localhost:1521:orcl";
		String name = "user2";
		String pwd = "user2";
		String Drivername = "oracle.jdbc.driver.OracleDriver";
		Class.forName(Drivername);
		Connection conn = DriverManager.getConnection(url, name, pwd);
		CallableStatement proc = conn
				.prepareCall("{ call PROC_TEST1(?,?) }"); // 存儲過程
		proc.setString(1, "%A%");// 設置第一個參數輸入參數
		proc.registerOutParameter(2, Types.VARCHAR);// 第二個參數輸出參數,是VARCHAR類型的
		proc.execute();// 執行
		String testPrint = proc.getString(2);// 獲得輸出參數
		System.out.println("=用戶名包含A的個數為=" + testPrint);
		conn.close();
	}

 

 

 

 

--3.創建帶查詢結果的

--3. 由於oracle存儲過程沒有返回值,它的所有返回值都是通過out參數來替代的,列表同樣也不例外,但由於是集合,所以不能用一般的參數,必須要用pagkage了.所以要分兩部分,

--3.1, 建一個程序包。如下:
create or replace package testpackage as
  type test_cursor is ref cursor;
end;

--3.2,建立存儲過程,存儲過程為:
create or replace procedure testc(p_cursor out testpackage.test_cursor) is
begin
  open p_cursor for
    select * from userinfo;
end;

java中的調用:

 

public static void select() throws ClassNotFoundException, SQLException {
		String url = "jdbc:oracle:thin:@localhost:1521:orcl";
		String name = "user2";
		String pwd = "user2";
		String Drivername = "oracle.jdbc.driver.OracleDriver";
		Class.forName(Drivername);
		Connection conn = DriverManager.getConnection(url, name, pwd);
		CallableStatement proc = conn.prepareCall(" call testc(?) "); // 存儲過程
		proc.registerOutParameter(1, oracle.jdbc.OracleTypes.CURSOR);// 設置輸出參數是一個游標.第一個參數,游標類型
		proc.execute();// 執行
		ResultSet rs = (ResultSet) proc.getObject(1); // 獲得第一個參數是一個游標,轉化成ResultSet類型
		while (rs.next()) // 獲得數據
		{
			System.out.println("id:" + rs.getString("id") + "\tusername:"
					+ rs.getString("username") + "\tinsertdate:"
					+ rs.getString("insertdate"));

		}
	}

 

 

 

4.創建可以調用其他存儲過程的存儲過程

 

-------------------------- 3.實例
create or replace procedure sp_name(defaultVar in varchar2 default 'A') -- 默認參數,如果不傳,要注意參數的順序
 as
  -- 變量聲明,每個聲明用分號結束。可以在聲明的同時初始化
  robj varchar2(4);
  var2 number(20) := 123;

begin
  -- 字符串拼接用 ||
  dbms_output.put_line('isok:' || 'abc');

  -- 調用其他存儲過程
  proc_test1(T => 'A', R => robj);
  dbms_output.put_line('R = ' || R);

end; -- 存儲過程結束

--調用

begin
  sp_name('A');

end;


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM