1. 程式人生 > >Oracle 儲存過程 \ 遊標簡單定義和使用

Oracle 儲存過程 \ 遊標簡單定義和使用



-- Created on 2018/10/12 by 32580 
declare 
  -- 定義變數 變數賦值方式為:  變數名 := 值
  i INTEGER ;
  sqls varchar2(500);
  user_id varchar2(36);
  log_id varchar2(36);
  cdate date; -- 本次建立時間
  fdate date; -- 山慈建立時間
  edate date; -- 本次推出時間
  -- logs SYS_LOG%ROWTYPE;
	
	-- 下面為定義遊標 這種方式為簡版 
--	cursor 關鍵詞 遊標名 [可選 遊標形參 遊標型別]  is  select * from table   --is 後面跟隨一個查詢語句 這樣就可以定義一個玩著的遊標了
  cursor log_user is select log.CREATE_BY  from sys_log_bak log where 1=1 and log.title in ('法官系統登入', '系統登入') and log.CREATE_BY = '213516324'  group by log.CREATE_BY ;
  cursor sel_sg(cid varchar2) is select log.* from sys_log_bak log where log.TITLE in ('法官系統登入', '系統登入') and log.CREATE_BY = cid order by log.CREATE_DATE desc ;
begin
  -- Test statements here
  i := 0;
  --  sqls :=  'select log.id from sys_log_bak log where log.TITLE in (''法官系統登入'', ''系統登入'') and log.CREATE_BY = :s order by log.CREATE_DATE asc '; 
	-- 定義一個sql 語句 語句中還有單引號(常量), 便用兩個單引號  如果需要佔位符 便用 ':' 頓號 + 字元 (字元可隨意),
  --	execute IMMEDIATE sqls into log_id using user_id   
	-- 執行儲存過程中的sql語句  execute immediate (關鍵詞) sqls (sql語句) into log_id (變數) 用於儲存當前查詢到的值,可以為多個,用 ',' 隔開, using 後面跟 需要插入佔位符中的值. 按照佔位符先後順序
	-- 但 這種執行的語句,只能返回單行, 多行便會報錯. 如果需要多行,需要使用遊標
  for us in log_user loop -- log_user 為遊標, 迴圈會自動開啟遊標  us為臨時變數名,自己任意起
      --Dbms_Output.put_line(temp.create_date); --輸出某個欄位,使用"變數名.列名"即可。
    cdate := null;
    fdate := null;
    Dbms_Output.put_line(us.CREATE_BY);
    for row_s in sel_sg(us.CREATE_BY) loop
			  log_id := row_s.id;
			  cdate := row_s.CREATE_DATE;
        if fdate is null then   -- 第一次 登入
						edate := cdate + 2/24;
				elsif (cdate - fdate) >= 2/24 then -- 2小時
				  edate := cdate + 2/24;
				elsif (cdate - fdate) >= 1/24 then -- 1
				  edate := cdate + 1/24;
				elsif (cdate - fdate) < 1/24 and (cdate - fdate) >= 30/(24*60) then  -- 半個小時
				  edate := cdate + 30/(24*60);
				elsif (cdate - fdate) < 30/(24 * 60) and (cdate - fdate) >= 10/(24 * 60) then --10分鐘
				  edate := cdate + 10/(24*60);
				elsif (cdate - fdate) < 10/(24 * 60) and (cdate - fdate) >= 1/(24 * 60) then --1分鐘
				  edate := fdate - 1/(24*60);
				elsif (cdate - fdate) < 1/(24 * 60) then 
				  edate := fdate - 2/(24*60*60);
				end if;
				fdate := row_s.CREATE_DATE;
		    EXECUTE IMMEDIATE ' update sys_log_bak bak set bak.EXIT_DATE = :d where bak.ID = :c ' using edate , log_id ;
        commit;    
		
    end loop;
       
  end loop;
end;