oracle遊標

1.遊標概念sql

 在PL/SQL塊中執行SELECT、INSERT、DELETE和UPDATE語句時,ORACLE會在內存中爲其分配上下文區(Context Area),即緩衝區。遊標是指向該區的一個指針,或是一種結構化數據類型。它提供了一種對具備多行數據查詢結果集中的每一行數據分別進行單獨處理的方法,是設計嵌入式SQL語句的應用程序的經常使用編程方式。數據庫

 

2.遊標使用編程

遊標分爲兩種;oracle

  1,隱式遊標ide

  2,顯示遊標,oop

 

A,隱式遊標fetch

隱式遊標是當執行sql語句時自動建立的,當沒有聲明顯示遊標時,程序是沒法控制隱式遊標的。ui

當執行DML語句(insert,update 和 delete)時,隱式遊標就會自動建立,對於insert操做,遊標控制插入的數據,對於delete,update,遊標會記錄影響的行數spa

注意:任何遊標都能訪問 sql%attribute_name .設計

 

遊標屬性

 

屬性

描述

%FOUND

 

若是insert,update,delete 執行影響了行數,或者select into 有返回的行數,意思就是有記錄被更新,則返回true,不然返回false.

%NOTFOUND

跟上面相反,沒有記錄被更新則返回true,不然返回false.

%ISOPEN

對於隱式遊標老是返回false,由於oracle在執行相關的sql語句後會自動關閉。

對於顯示遊標,若是被打開了,就返回true,不然返回false.

%ROWCOUNT

返回受影響的行數.當執行Insert,update 或delete語句時,或者是select into 時

 

隱式遊標屬性

屬性

SELECT

INSERT

UPDATE

DELETE

SQL%ISOPEN

 

FALSE

FALSE

FALSE

FALSE

SQL%FOUND

TRUE

有結果

 

成功

成功

SQL%FOUND

FALSE

沒結果

 

失敗

失敗

SQL%NOTFUOND

TRUE

沒結果

 

失敗

失敗

SQL%NOTFOUND

FALSE

有結果

 

成功

失敗

SQL%ROWCOUNT

 

返回行數,只爲1

插入的行數

修改的行數

刪除的行數

 

看例子的前提仍是先準備數據

 

drop table customer;
create table customer
(
name varchar(100) primary key,
age int,
address varchar(100),
salary decimal
)
delete from customer;
insert into customer values ('jack',22,'Singapore',5000.00);
insert into customer values ('rose',22,'Japan',2000.00);
insert into customer values ('Jet',32,'HongKong',7000.00);
insert into customer values ('John',30,'American',5000.00);
insert into customer values ('Merry',25,'Singapore',3000.00);
insert into customer values ('Peter',26,'China',1000.00);
insert into customer values ('Adi',27,'India',2400.00);

select * from customer

select * from customer where salary <3000
View Code

 

例1;

例1,
set serveroutput on;
DECLARE 
   total_rows number(2);
BEGIN
   UPDATE customer
   SET salary = salary + 500
   where salary < 3000;
   IF sql%notfound THEN
      dbms_output.put_line('no customers selected');
   ELSIF sql%found THEN
      total_rows := sql%rowcount;
      dbms_output.put_line( total_rows || ' customers selected ');
   END IF; 
END;
/
View Code

 

結果:

3 customers selected

查看數據會發現,數據庫更新了3條記錄。

大多數時候咱們仍是使用的顯示遊標,這樣更加容易去控制。

 

B,顯遊標

 

遊標的聲明:

    CURSOR cursor_name[(parameter[, parameter]…)] 
              [RETURN datatype]
    IS 
        select_statement;

 

 

實用顯示遊標會有如下4個步驟;

 

  • 聲明遊標初始化內存
  • 打開遊標分配內存
  • Fetch cursor 獲取記錄
  • 關閉遊標釋放內存

 

  1. 聲明遊標
CURSOR c1 is select name, salary from customer;

    2,打開遊標分配內存

OPEN c1;    

    3,獲取記錄

FETCH c1 INTO c_name, c_salary;

 4,關閉遊標

CLOSE c_1;

 

下面看一個簡單使用顯示遊標的完整例子

 

例2;

 

set serveroutput on;
DECLARE 
   c_salary customer.salary%TYPE;
   c_name customer.name%TYPE;
   CURSOR c1 is
   select name,salary from customer;
BEGIN
  open c1;
  loop
  fetch c1 into c_name,c_salary;
  exit when c1%notfound ;
   dbms_output.put_line(c_name||' '||c_salary);
  end loop;
  close c1;
END;
/
View Code

 

結果;

jack 5000
rose 2500
Jet 7000
John 5000
Merry 3000
Peter 1500
Adi 2900
View Code

 

 

PL/SQL語言提供了遊標FOR循環語句,自動執行遊標的OPEN、FETCH、CLOSE語句和循環語句的功能;當進入循環時,遊標FOR循環語句自動打開遊標,並提取第一行遊標數據,當程序處理完當前所提取的數據而進入下一次循環時,遊標FOR循環語句自動提取下一行數據供程序處理,當提取完結果集合中的全部數據行後結束循環,並自動關閉遊標。

 

  FOR index_variable IN cursor_name[(value[, value]…)] LOOP
    -- 遊標數據處理代碼
  END LOOP;

 

用for loop,能夠完成上面例2一樣的效果。

例3;

  

set serveroutput on;
DECLARE 
   c_salary customer.salary%TYPE;
   c_name customer.name%TYPE;
   CURSOR c1 is
   select name,salary from customer;
BEGIN
 for f in c1
  loop
   dbms_output.put_line(f.name||' '||f.salary);
  end loop;
END;
/
View Code

 

帶參數的遊標

set serveroutput on;
DECLARE 
   c_salary customer.salary%TYPE;
   c_name customer.name%TYPE;
   CURSOR c1(p_salary decimal default 3000) is
   select name,salary from customer where salary >= p_salary;
BEGIN
  --open c1(p_salary=>5000);
  open c1(5000); 
  loop
  fetch c1 into c_name,c_salary;
  exit when c1%notfound ;
   dbms_output.put_line(c_name||' '||c_salary);
  end loop;
  close c1;
END;
View Code

 

使用遊標更新和刪除數據(Select for update使用)

遊標修改和刪除操做是指在遊標定位下,修改或刪除表中指定的數據行。這時,要求遊標查詢語句中必須使用FOR UPDATE選項,以便在打開遊標時鎖定遊標結果集合在表中對應數據行的全部列和部分列。

 

爲了對正在處理(查詢)的行不被另外的用戶改動,ORACLE 提供一個 FOR UPDATE 子句來對所選擇的行進行鎖住。該需求迫使ORACLE鎖定遊標結果集合的行,能夠防止其餘事務處理更新或刪除相同的行,直到您的事務處理提交或回退爲止。

 

在多表查詢中,使用OF子句來鎖定特定的表,若是忽略了OF子句,那麼全部表中選擇的數據行都將被鎖定。若是這些數據行已經被其餘會話鎖定,那麼正常狀況下ORACLE將等待,直到數據行解鎖。

語法:

 

SELECT column_list FROM table_list FOR UPDATE [OF column[, column]…] [NOWAIT]

 

    若是另外一個會話已對活動集中的行加了鎖,那麼SELECT FOR UPDATE操做一直等待到其它的會話釋放這些鎖後才繼續本身的操做,對於這種狀況,當加上NOWAIT子句時,若是這些行真的被另外一個會話鎖定,則OPEN當即返回並給出:

ORA-0054 :resource busy  and  acquire with nowait specified.

 

例4;

set serveroutput on;
DECLARE 
   c_salary customer.salary%TYPE;
   c_name customer.name%TYPE;
   CURSOR c1(p_salary customer.salary%TYPE)
   is
   select name,salary from customer where salary >= p_salary
   for update of salary;
BEGIN
  open c1(5000);
  loop
  fetch c1 into c_name,c_salary;  
  exit when c1%notfound ;
   dbms_output.put_line(c_name||' '||c_salary);
   update customer set salary=salary+100 where current of c1; --更新當前遊標行對應的數據行
  end loop;
  close c1;
END;
/
View Code

 

 

這篇就先看到基礎的東西,遊標知識仍是比較多,但願起到拋磚引玉的效果。 

這篇文檔比較深刻,供參考

http://www.codeproject.com/Articles/580628/OracleplusPL-fSQLplusCursor

相關文章
相關標籤/搜索