遊標

1、 遊標

   位於內存中的 "臨時表"。 具體以下:遊標是從數據表中提取出來的數據,以 臨時表 的形式存放到 內存中,在遊標中有一個 數據指針, 在初始狀態下指向的是首記錄,利用 fetch 語句能夠移動該指針,從而對遊標中的數據進行各類操做,而後將操做結果寫回到數據庫中。遊標的本質是一個結果集resultset,主要用來臨時存儲從數據庫中提取出來的數據塊。sql

2、 遊標的分類

      1. 顯式遊標:由用戶定義,須要的操做:定義遊標、打開遊標、提取數據、關閉遊標,主要用於對查詢語句的處理。數據庫

      2.顯式遊標的屬性oop

        (1) %NOTFOUND。表示遊標獲取數據的時候是否有數據提取出來,沒有數據返回TRUE,有數據返回false。常常用來判斷遊標是否所有循環完畢,如案例1%NOTFOUND爲true的時候,說明循環完畢,跳出LOOP循環。測試

        (2) %FOUND。正好和%NOTFOUND相反,當遊標提取數據值時有值,返回TRUE,不然返回FALSE。fetch

        (3) %ISOPEN。用來判斷遊標是否打開。spa

        (4) %ROWCOUNT。表示當前遊標FETCH INTO獲取了多少行的記錄值,用來作計數用的。指針

舉例:打印表hu_test中的指定字段code

--顯示遊標
declare 
cursor hu_test_cursor is select owner,object_type,created from hu_test;--定義遊標
v_owner hu_test.owner%type;
v_object_type hu_test.object_type%type;
v_created hu_test.created%type;
begin
    open hu_test_cursor;--打開遊標
    loop 
        fetch hu_test_cursor into  v_owner,v_object_type,v_created;--提取數據
        dbms_output.put_line('全部者:'||v_owner||' 類型是:'||v_object_type||' 建立時間:'||v_created);
    exit when hu_test_cursor%notfound;
  end loop;
      close hu_test_cursor;--關閉遊標
        EXCEPTION
   WHEN OTHERS THEN
     dbms_output.put_line(SQLCODE || ' : ' || SQLERRM);--返回錯誤消息
      dbms_output.put_line(dbms_utility.format_error_backtrace);--返回錯誤行
end;    

舉例:檢驗遊標是否打開,打開的話顯示提取行數orm

--檢驗遊標是否打開,打開的話顯示提取行數
declare 
cursor hu_test_cursor is select owner,object_type,created from hu_test;--定義遊標
v_owner hu_test.owner%type;
v_object_type hu_test.object_type%type;
v_created hu_test.created%type;
begin
	open hu_test_cursor;--打開遊標
	loop 
		fetch hu_test_cursor into  v_owner,v_object_type,v_created;--提取數據
		dbms_output.put_line('全部者:'||v_owner||' 類型是:'||v_object_type||' 建立時間:'||v_created);
    exit when hu_test_cursor%notfound;
  end loop;
	if(hu_test_cursor%isopen) then DBMS_OUTPUT.PUT_LINE('遊標已打開');
	DBMS_OUTPUT.PUT_LINE('讀取了'||hu_test_cursor%ROWCOUNT||'行');
	else
		DBMS_OUTPUT.PUT_LINE('遊標沒有打開');
	end if;	
	  close hu_test_cursor;--關閉遊標
		EXCEPTION
   WHEN OTHERS THEN
     dbms_output.put_line(SQLCODE || ' : ' || SQLERRM);--返回錯誤消息
      dbms_output.put_line(dbms_utility.format_error_backtrace);--返回錯誤行
end;

  3. 隱式遊標:由系統定義併爲它建立工做區域,而且隱式的定義打開提取關閉,隱式遊標的遊標名就是'SQL',屬性和顯示遊標相同,主要用於對單行select語句或dml操做進行處理。blog

        (1)SQL%ISOPEN:遊標是否開啓, true:開啓,false:關閉

        (2)SQL%FOUND:前一個 fetch 語句是否有值,true:有,false:沒有
        (3)SQL%NOTFOUND:與上述相反,常被用於 退出循環,true:沒有,false:有, null : 空。注意哦,只有 爲 true 時,才退出(當 第一次 fetch 爲 null 時,不會退出!)

        (4)SQL%ROWCOUNT:當前成功執行的數據行數(非總記錄數

舉例:用隱式遊標測試插入,更新,刪除,查詢等

--隱式遊標
declare 
v_count number;
begin
	insert into hu_test(owner,object_type,created) values('SYS','test',sysdate);
	IF SQL%FOUND THEN
      dbms_output.put_line('插入成功!');
			commit;
   END IF;
	update hu_test e set e.object_type='CLUSTER1' where e.object_type='CLUSTER';
	IF SQL%FOUND THEN
      dbms_output.put_line('更新成功!');
			commit;
   END IF;
	delete from hu_test e where e.object_id=3; 
	IF SQL%FOUND THEN
      dbms_output.put_line('刪除成功!');
			commit;
   END IF;
	select count(*) into v_count from hu_test;
	IF SQL%FOUND THEN
      dbms_output.put_line('總記錄爲: '||v_count); 
   END IF;
	IF SQL%ISOPEN THEN
      dbms_output.put_line('可手動查看');
   ELSE 
      dbms_output.put_line('沒法手動查看');
   END IF;
	EXCEPTION
   WHEN OTHERS THEN
      dbms_output.put_line(SQLCODE || ' : ' || SQLERRM);
      dbms_output.put_line(dbms_utility.format_error_backtrace);
end;

  4.遊標FOR循環:隱含的執行了打開提取關閉數據,代碼精簡不少,syntax:

FOR table_record IN table_cursor LOOP

  STATEMENT;

END LOOP;

舉例:遊標FOR循環

DECLARE
cursor hu_test_cursor is select owner,object_type,created from hu_test;
BEGIN
  FOR test_cursor IN hu_test_cursor LOOP
    dbms_output.put_line('全部者:'||test_cursor.owner||' 類型是:'||test_cursor.object_type||' 建立時間:'||test_cursor.created);
  END LOOP;
END;

這裏遊標FOR循環省去了對於取到的數據的變量的命名和賦值,同時若是所有打印則不用寫循環條件,代碼精簡了不少。

若是想讓代碼更加精簡,則能夠去掉對遊標的聲明引入子查詢便可,操做以下。

--更簡便的for循環
BEGIN
  FOR test_cursor IN (select owner,object_type,created from hu_test) LOOP
    dbms_output.put_line('全部者:'||test_cursor.owner||' 類型是:'||test_cursor.object_type||' 建立時間:'||test_cursor.created);
  END LOOP;
END;

  5.參數遊標,動態遊標1

舉例:輸入object_id查詢相關數據

--參數遊標
declare 
cursor hu_test_cursor(numid number) is	select owner,object_type,created from hu_test e where e.object_id=numid;
BEGIN
  FOR test_cursor IN hu_test_cursor(&numid) LOOP--這裏也能夠用一個變量來賦值
    dbms_output.put_line('全部者:'||test_cursor.owner||' 類型是:'||test_cursor.object_type||' 建立時間:'||test_cursor.created);
  END LOOP;
END;

  6.參數遊標,動態遊標2

--動態遊標
declare 
v_id hu_test.object_id%type;
v_sql varchar2(2000);
type test_cursor_type is ref cursor;
test_cursor test_cursor_type;
v_owner hu_test.owner%type;
v_object_type hu_test.object_type%type;
v_created hu_test.created%type;
BEGIN
	v_id:=20;
	v_sql:='select owner,object_type,created from hu_test e where e.object_id = :v_id';
	open test_cursor for v_sql using v_id;
	loop
	fetch test_cursor into v_owner,v_object_type,v_created;
  exit when test_cursor%notfound;
    dbms_output.put_line('全部者:'||v_owner||' 類型是:'||v_object_type||' 建立時間:'||v_created);
  END LOOP;
	close test_cursor;
	EXCEPTION
   WHEN OTHERS THEN
      dbms_output.put_line(SQLCODE || ' : ' || SQLERRM);
      dbms_output.put_line(dbms_utility.format_error_backtrace);
END;
相關文章
相關標籤/搜索