1. 高手求助。 oracle資料庫的帶參數游標問題。
cursor pdct-parameter-cur (id VARCHAR,price NUMBER)
IS SELECT * FROM PRODUCTINFO
WHERE PRODUCTID LIKE ID \\ '%'
AND proctprice>price;
聲明了一個帶參數游標,
WHERE PRODUCTID LIKE ID || '%' 這里是把參數ID實際值後面增加一個「%」通配符,用來like匹配。如果ID傳進來值為'123456',那個條件就相當於WHERE PRODUCTID LIKE '123456%' 。
2. oracle sql語句中的游標,函數和存儲過程的區別
游標有顯示游標和隱式游標之分,顯示游標需要自己去定義,declare cursor(這個自己看書去吧),這樣使用游標一條條地取值使用。而隱式游標針對所有的select語句都是的。
函數和存儲過程幾乎沒有區別,只是前者有返回值,後者沒有,如果後者定義了出參,那就和函數的功能是一樣的了。
3. oracle plsql 練習 要用到游標
唉,又是大學生吧,自己不動腦筋.發個例子你看看.
declare
v_num number := &input;
v_last_num number := 0;
v_result varchar(2000) := '';
begin
loop
v_last_num := mod(v_num,10);
v_result := v_result || to_char(v_last_num);
v_num := v_num - v_last_num;
exit when v_num=0;
v_num := v_num / 10;
end loop;
dbms_output.put_line(v_result);
end;
第六章 游標(cursor)管理
create SYNONYM emp for scott.emp;
--作用:
declare
v_ename emp.ename%type;
begin
select ename into v_ename
from emp;
dbms_output.put_line(v_ename);
end;
--顯式游標的定義和遍歷
--通過無條件的循環來遍歷游標
declare
--1.定義游標
cursor c_emp_cursor
is select ename from emp;
v_ename emp.ename%type;
begin
--2.打開游標
open c_emp_cursor;
--3.遍歷游標
loop
fetch c_emp_cursor into v_ename; --rs.next();
exit when c_emp_cursor%NOTFOUND;
dbms_output.put_line(v_ename);
end loop;
--4.關閉游標
close c_emp_cursor;
end;
--用WHILE循環來遍歷游標
declare
cursor c_emp_cursor
is select * from emp;
v_row emp%rowtype;
begin
open c_emp_cursor;
fetch c_emp_cursor into v_row;
while c_emp_cursor%FOUND loop
dbms_output.put_line(v_row.ename || ' ' || v_row.empno);
fetch c_emp_cursor into v_row;
end loop;
close c_emp_cursor;
end;
--FOR循環遍歷游標的方式
declare
cursor c_emp_cursor
is select * from emp;
begin
for v_row IN c_emp_cursor loop
dbms_output.put_line(v_row.empno || ' ' || v_row.ename);
end loop;
end;
--定義參數類型的游標
declare
cursor c_emp_cursor(p_deptno emp.deptno%type)
is select ename from emp where deptno=p_deptno;
v_ename emp.ename%type;
begin
open c_emp_cursor(&input);
loop
fetch c_emp_cursor into v_ename;
exit when c_emp_cursor%NOTFOUND;
dbms_output.put_line(v_ename);
end loop;
close c_emp_cursor;
end;
--為游標指定返回類型1-rowtype
declare
cursor c_emp_cursor
return emp%rowtype --強制類型
is select * from emp;
begin
for v_row IN c_emp_cursor loop
dbms_output.put_line(v_row.empno);
end loop;
end;
--為游標指定返回類型2-記錄(Record)類型
declare
--定義一個記錄類型
type t_emp_record is record
(
empno emp.empno%type,
ename emp.ename%type
);
v_emp_record t_emp_record;
cursor c_emp_cursor
return v_emp_record --強制類型
is select empno,ename from emp;
begin
open c_emp_cursor;
loop
fetch c_emp_cursor into v_emp_record;
exit when c_emp_cursor%NOTFOUND;
dbms_output.put_line(v_emp_record.empno);
dbms_output.put_line(v_emp_record.ename);
end loop;
close c_emp_cursor;
end;
--如何通過游標來修改數據
declare
--通過游標修改數據要上行級鎖
cursor c_emp_cursor
is select * from emp where deptno=20 for update;
begin
for v_row In c_emp_cursor loop
delete from emp
where current of c_emp_cursor;
end loop;
commit;
end;
select * from emp;
--REF引用類型的游標描述
declare
type t_ref_cursor is ref cursor;
v_ref_cursor t_ref_cursor;
begin
open v_ref_cursor
for select * from emp;
close v_ref_cursor;
open v_ref_cursor
for select * from dept;
close v_ref_cursor;
end;
--1.隱式游標(SQL)的使用
--用途:因為資料庫系統在做insert,delete,update,select這些操作的時候
--都是通過游標去完成的,所以,在做操作之前我們的資料庫系統都會隱式
--的打開一個游標,在執行操作完畢之後隱式的關閉游標,那麼每次的操作的結果
--都會保存在一個叫做SQL的隱式游標中,我們可以通過操作這個隱式游標來獲取
--資料庫操作的信息
begin
delete from emp where deptno=10;
dbms_output.put_line(SQL%ROWCOUNT);
end;
第七章 存儲過程(Procere)和包(Package)
SQLServer - 存儲過程 (output參數 return)
Oracle -存儲過程(out參數) 函數(return)
--1.存儲過程
create or replace procere print(msg varchar2)
is
begin
dbms_output.put_line(msg);
end;
--1.1 調用存儲過程
execute print('helloworld');
--1.2
create or replace procere findEmp(p_empno emp.empno%type)
is
v_ename emp.ename%type;
begin
select ename into v_ename
from emp where empno=p_empno;
print(v_ename);
exception
when no_data_found then
print('未發現指定員工.');
end;
--1.3 傳遞參數
create or replace procere myabs(p_num1 IN number,p_num2 OUT number)
is
begin
if p_num1 >0 then
p_num2 := p_num1;
else
p_num2 := (0 - p_num1);
end if;
end;
--調用
declare
v_result number;
begin
myabs(-987,v_result);
print(v_result);
end;
create or replace procere change_num(p_num1 IN OUT number,p_num2 IN OUT number)
is
v_temp number;
begin
v_temp := p_num1;
p_num1 := p_num2;
p_num2 := v_temp;
end;
--調用
declare
v_num1 number :=111;
v_num2 number :=222;
begin
change_num(v_num1,v_num2);
print(v_num1);
print(v_num2);
end;
--2.函數(FUNCTION)
create or replace function myabs1(p_num1 number)
return number
is
begin
if p_num1 >= 0 then
return p_num1;
else
return (0 - p_num1);
end if;
end;
begin
print(myabs1(-999));
end;
create or replace function findEmp1(p_empno emp.empno%type)
return emp.ename%type
is
v_ename emp.ename%type;
begin
select ename into v_ename
from emp
where empno=p_empno;
return v_ename;
exception
when no_data_found then
print('未發現員工');
end;
begin
print(findEmp1(7499));
end;
--3.包(Package)-包(package-定義)和包體(package body-實現)
create or replace package mypkg
is
procere print(msg varchar2);
function findEmp(p_empno number)
return emp.ename%type;
end;
create or replace package body mypkg
is
procere print(msg varchar2)
is
begin
dbms_output.put_line(msg);
end;
function findEmp(p_empno number)
return emp.ename%type
is
v_ename emp.ename%type;
begin
select ename into v_ename
from emp
where empno=p_empno;
return v_ename;
exception
when no_data_found then
print('未發現員工');
end;
end;
--4.通過函數返回結果集
create or replace function findAllEmps
return SYS_REFCURSOR
is
v_ref_cursor SYS_REFCURSOR;
begin
open v_ref_cursor
for 'select * from emp';
return v_ref_cursor;
end;
我上學時候練慣用的
4. oracle中游標的使用
這樣的問法好籠統,不過,還是把我整理的給你看看吧~個人整理,無復制的哦~
A:分類:
1:隱式游標:非用戶明確聲明而產生的游標. 你根本看不到cursor這個關鍵字.
2:顯示游標:用戶明確通過cursor關鍵字來聲明的游標.
3:引用游標:
B:什麼是隱式游標:
1:什麼時候產生:
會在執行任何合法的SQL語句中產生.他不一定存放數據.也有可能存放記錄集所影響的行數.
如果執行SELECT語句,這個時候游標會存放數據.如果執行INSERT、UPDATE、 DELETE會存放記錄影響的行數.
C:隱式游標叫什麼名字:
名字叫sql
關於sql的游標變數到底有哪些呢?
作用:返回最近一次執行SQL語句所涉及的游標相關信息.因為每執行一次SQL語句,都會產生一個隱式游標.那麼當前執行的SQL語句就是當前的隱式游標.
sql%found
sql%notfound
sql%rowcount
sql%isopen
D:關於隱式游標的例子:
create table 學生基本信息表
(
StuID number(2),
StuName varchar2(20)
)
alter table 學生基本信息表 add constraint PK_STUID primary key(StuID)
declare
num number:=0;
begin
num:=#
delete from 學生基本信息表 where StuID=num;
if sql%notfound then
dbms_output.put_line('該行數據沒有發現');
else
dbms_output.put_line('數據被發現並刪除,影響的行數為:'||sql%rowcount);
end if;
end;
E:關於顯示游標的例子:
1:如何定義顯示游標
declare cursor <cursor_name> is [select語句];
declare cursor mycur is select empno,ename,job from scott.emp;
2:如何打開游標:
open <cursor_name>;
open mycur;
3:如何通過游標來讀取數據
fetch <cursor_name> into <variable_list>
4:如何關閉游標:
close <cursor_name>;
close mycur;
注意:在Oracle中,不需要顯示銷毀游標.因為在Oracle中,很多東西是由JAVA寫的.Oracle會自動銷毀游標.
5:舉例:
declare
cursor mycur is select empno,ename,job from emp; --創建游標
vempno emp.empno%type;
vename emp.ename%type;
vjob emp.job%type;
begin
open mycur;--打開游標
fetch mycur into vempno,vename,vjob;--使用數據
dbms_output.put_line('I Found You!'||mycur%rowcount||'行');
dbms_output.put_line('讀取的數據為'||vempno||' '||vename||' '||vjob);
close mycur;
end;
因為只讀出來一條,所以要遍歷一下:
declare
cursor mycur is select empno,ename,job from emp;
vempno emp.empno%type;
vename emp.ename%type;
vjob emp.job%type;
begin
open mycur;
loop—循環,遍歷
fetch mycur into vempno,vename,vjob;
exit when mycur%notfound;
if mycur%found then
dbms_output.put_line('讀取的數據為'||vempno||' '||vename||' '||vjob);
end if;
end loop;
dbms_output.put_line('I Found You!'||mycur%rowcount||'行');
close mycur;
end;
6:通常情況下我們在讀取表數據的時候,我們需要動態的去查詢.所以能不能在Oracle中給游標帶參數呢?可以!
1):如何定義帶參數的游標:
declare cursor <cursor_name>(參數名稱 參數類型描述) is select xxxxx from bbbbb where aaa==??? and ccc=???;
2):例子:
游標是一個集合,讀取數據有兩種方式
第一種方式: open fetch close
第二種方式: for 一但使用了for循環 ,在循環剛剛開始的時候,相當於執行open,在處理循環的時候,相當於執行fetch,在退出循環的時候,相當於執行了close
Declare cursor query(vname varchar) is select empno,ename,job from emp where ename like'%'||vname||'%';
三種游標的例子:
--
DECLARE
CURSOR TEST_CUR IS
SELECT * FROM EMP;
MY_CUR EMP%ROWTYPE;
BEGIN
OPEN TEST_CUR;
FETCH TEST_CUR INTO MY_CUR;
WHILE TEST_CUR%FOUND
LOOP
DBMS_OUTPUT.PUT_LINE(MY_CUR.EMPNO||','||MY_CUR.ENAME);
FETCH TEST_CUR INTO MY_CUR;
END LOOP;
CLOSE TEST_CUR;
END;
--
DECLARE
CURSOR TEST_CUR IS
SELECT * FROM EMP;
BEGIN
FOR MY_CUR IN TEST_CUR
LOOP
DBMS_OUTPUT.PUT_LINE(MY_CUR.EMPNO||','||MY_CUR.ENAME);
END LOOP;
END;
--
DECLARE
CURSOR TEST_CUR(V_SAL NUMBER) IS
SELECT *
FROM EMP
WHERE SAL > V_SAL;
V_SAL1 NUMBER ;
BEGIN
V_SAL1 := 2000;
FOR MY_CUR IN TEST_CUR(V_SAL1)
LOOP
DBMS_OUTPUT.PUT_LINE(MY_CUR.EMPNO||','||MY_CUR.ENAME);
END LOOP;
END;
5. 關於oracle8i的帶參數游標用法的問題
oracle資料庫游標使用大全
sql是用於訪問oracle資料庫的語言,pl/sql擴展和加強了sql的功能,它同時引入了更強的程序邏輯。 pl/sql支持dml命令和sql的事務控制語句。ddl在pl/sql中不被支持,這就意味作在pl/sql程序塊中不能創建表或其他任何對象。較好的pl/sql程序設計是在pl/sql塊中使用象dbms_sql這樣的內建包或執行execute immediate命令建立動態sql來執行ddl命令,pl/sql編譯器保證對象引用以及用戶的許可權。
下面我們將討論各種用於訪問oracle資料庫的ddl和tcl語句。
查詢
select語句用於從資料庫中查詢數據,當在pl/sql中使用select語句時,要與into子句一起使用,查詢的返回值被賦予into子句中的變數,變數的聲明是在delcare中。select into語法如下:
select [distict|all]{*|column[,column,...]}
into (variable[,variable,...] |record)
from {table|(sub-query)}[alias]
where............
pl/sql中select語句只返回一行數據。如果超過一行數據,那麼就要使用顯式游標(對游標的討論我們將在後面進行),into子句中要有與select子句中相同列數量的變數。into子句中也可以是記錄變數。
%type屬性
在pl/sql中可以將變數和常量聲明為內建或用戶定義的數據類型,以引用一個列名,同時繼承他的數據類型和大小。這種動態賦值方法是非常有用的,比如變數引用的列的數據類型和大小改變了,如果使用了%type,那麼用戶就不必修改代碼,否則就必須修改代碼。
例:
v_empno scott.emp.empno%type;
v_salary emp.salary%type;
不但列名可以使用%type,而且變數、游標、記錄,或聲明的常量都可以使用%type。這對於定義相同數據類型的變數非常有用。
delcare
v_a number(5):=10;
v_b v_a%type:=15;
v_c v_a%type;
begin
dbms_output.put_line
(''v_a=''||v_a||''v_b=''||v_b||''v_c=''||v_c);
end
sql>/
v_a=10 v_b=15 v_c=
pl/sql procere successfully completed.
sql>
其他dml語句
其它操作數據的dml語句是:insert、update、delete和lock table,這些語句在pl/sql中的語法與在sql中的語法相同。我們在前面已經討論過dml語句的使用這里就不再重復了。在dml語句中可以使用任何在declare部分聲明的變數,如果是嵌套塊,那麼要注意變數的作用范圍。
例:
create or replace procere fire_employee (pempno in number)
as
v_ename emp.ename%type;
begin
select ename into v_ename
from emp
where empno=p_empno;
insert into former_emp(empno,ename)
values (p_empno,v_ename);
delete from emp
where empno=p_empno;
update former_emp
set date_deleted=sysdate
where empno=p_empno;
exception
when no_data_found then
dbms_output.put_line(''employee number not found!'');
end
dml語句的結果
當執行一條dml語句後,dml語句的結果保存在四個游標屬性中,這些屬性用於控製程序流程或者了解程序的狀態。當運行dml語句時,pl/sql打開一個內建游標並處理結果,游標是維護查詢結果的內存中的一個區域,游標在運行dml語句時打開,完成後關閉。隱式游標只使用sql%found,sql%notfound,sql%rowcount三個屬性.sql%found,sql%notfound是布爾值,sql%rowcount是整數值。
sql%found和sql%notfound
在執行任何dml語句前sql%found和sql%notfound的值都是null,在執行dml語句後,sql%found的屬性值將是:
. true :insert
. true :delete和update,至少有一行被delete或update.
. true :select into至少返回一行
當sql%found為true時,sql%notfound為false。
sql%rowcount
在執行任何dml語句之前,sql%rowcount的值都是null,對於select into語句,如果執行成功,sql%rowcount的值為1,如果沒有成功,sql%rowcount的值為0,同時產生一個異常no_data_found.
sql%isopen
sql%isopen是一個布爾值,如果游標打開,則為true, 如果游標關閉,則為false.對於隱式游標而言sql%isopen總是false,這是因為隱式游標在dml語句執行時打開,結束時就立即關閉。
事務控制語句
事務是一個工作的邏輯單元可以包括一個或多個dml語句,事物控制幫助用戶保證數據的一致性。如果事務控制邏輯單元中的任何一個dml語句失敗,那麼整個事務都將回滾,在pl/sql中用戶可以明確地使用commit、rollback、savepoint以及set transaction語句。
commit語句終止事務,永久保存資料庫的變化,同時釋放所有lock,rollback終止現行事務釋放所有lock,但不保存資料庫的任何變化,savepoint用於設置中間點,當事務調用過多的資料庫操作時,中間點是非常有用的,set transaction用於設置事務屬性,比如read-write和隔離級等。
顯式游標
當查詢返回結果超過一行時,就需要一個顯式游標,此時用戶不能使用select into語句。pl/sql管理隱式游標,當查詢開始時隱式游標打開,查詢結束時隱式游標自動關閉。顯式游標在pl/sql塊的聲明部分聲明,在執行部分或異常處理部分打開,取數據,關閉。下表顯示了顯式游標和隱式游標的差別:
表1 隱式游標和顯式游標
隱式游標 顯式游標
pl/sql維護,當執行查詢時自動打開和關閉 在程序中顯式定義、打開、關閉,游標有一個名字。
游標屬性前綴是sql 游標屬性的前綴是游標名
屬性%isopen總是為false %isopen根據游標的狀態確定值
select語句帶有into子串,只有一行數據被處理 可以處理多行數據,在程序中設置循環,取出每一行數據。
使用游標
這里要做一個聲明,我們所說的游標通常是指顯式游標,因此從現在起沒有特別指明的情況,我們所說的游標都是指顯式游標。要在程序中使用游標,必須首先聲明游標。
聲明游標
語法:
cursor cursor_name is select_statement;
在pl/sql中游標名是一個未聲明變數,不能給游標名賦值或用於表達式中。
例:
delcare
cursor c_emp is select empno,ename,salary
from emp
where salary>2000
order by ename;
........
begin
在游標定義中select語句中不一定非要表可以是視圖,也可以從多個表或視圖中選擇的列,甚至可以使用*來選擇所有的列 。
打開游標
使用游標中的值之前應該首先打開游標,打開游標初始化查詢處理。打開游標的語法是:
open cursor_name
cursor_name是在聲明部分定義的游標名。
例:
open c_emp;
關閉游標
語法:
close cursor_name
例:
close c_emp;
從游標提取數據
從游標得到一行數據使用fetch命令。每一次提取數據後,游標都指向結果集的下一行。語法如下:
fetch cursor_name into variable[,variable,...]
對於select定義的游標的每一列,fetch變數列表都應該有一個變數與之相對應,變數的類型也要相同。
例:
set serveriutput on
declare
v_ename emp.ename%type;
v_salary emp.salary%type;
cursor c_emp is select ename,salary from emp;
begin
open c_emp;
fetch c_emp into v_ename,v_salary;
dbms_output.put_line(''salary of employee''|| v_ename
||''is''|| v_salary);
fetch c_emp into v_ename,v_salary;
dbms_output.put_line(''salary of employee''|| v_ename
||''is''|| v_salary);
fetch c_emp into v_ename,v_salary;
dbms_output.put_line(''salary of employee''|| v_ename
||''is''|| v_salary);
close c_emp;
end
這段代碼無疑是非常麻煩的,如果有多行返回結果,可以使用循環並用游標屬性為結束循環的條件,以這種方式提取數據,程序的可讀性和簡潔性都大為提高,下面我們使用循環重新寫上面的程序:
set serveriutput on
declare
v_ename emp.ename%type;
v_salary emp.salary%type;
cursor c_emp is select ename,salary from emp;
begin
open c_emp;
loop
fetch c_emp into v_ename,v_salary;
exit when c_emp%notfound;
dbms_output.put_line(''salary of employee''|| v_ename
||''is''|| v_salary);
end
記錄變數
定義一個記錄變數使用type命令和%rowtype,關於%rowstype的更多信息請參閱相關資料。
記錄變數用於從游標中提取數據行,當游標選擇很多列的時候,那麼使用記錄比為每列聲明一個變數要方便得多。
當在表上使用%rowtype並將從游標中取出的值放入記錄中時,如果要選擇表中所有列,那麼在select子句中使用*比將所有列名列出來要安全得多。
例:
set serveriutput on
declare
r_emp emp%rowtype;
cursor c_emp is select * from emp;
begin
open c_emp;
loop
fetch c_emp into r_emp;
exit when c_emp%notfound;
dbms_out.put.put_line(''salary of employee''||r_emp.ename||''is''|| r_emp.salary);
end loop;
close c_emp;
end;
%rowtype也可以用游標名來定義,這樣的話就必須要首先聲明游標:
set serveriutput on
declare
cursor c_emp is select ename,salary from emp;
r_emp c_emp%rowtype;
begin
open c_emp;
loop
fetch c_emp into r_emp;
exit when c_emp%notfound;
dbms_out.put.put_line(''salary of employee''||r_emp.ename||''is''|| r_emp.salary);
end loop;
close c_emp;
end;
帶參數的游標
與存儲過程和函數相似,可以將參數傳遞給游標並在查詢中使用。這對於處理在某種條件下打開游標的情況非常有用。它的語法如下:
cursor cursor_name[(parameter[,parameter],...)] is select_statement;
定義參數的語法如下:
parameter_name [in] data_type[{:=|default} value]
與存儲過程不同的是,游標只能接受傳遞的值,而不能返回值。參數只定義數據類型,沒有大小。
另外可以給參數設定一個預設值,當沒有參數值傳遞給游標時,就使用預設值。游標中定義的參數只是一個佔位符,在別處引用該參數不一定可靠。
在打開游標時給參數賦值,語法如下:
open cursor_name[value[,value]....];
參數值可以是文字或變數。
例:
decalre
cursor c_dept is select * from dept order by deptno;
cursor c_emp (p_dept varachar2) is
select ename,salary
from emp
where deptno=p_dept
order by ename
r_dept dept%rowtype;
v_ename emp.ename%type;
v_salary emp.salary%type;
v_tot_salary emp.salary%type;
begin
open c_dept;
loop
fetch c_dept into r_dept;
exit when c_dept%notfound;
dbms_output.put_line(''department:''|| r_dept.deptno||''-''||r_dept.dname);
v_tot_salary:=0;
open c_emp(r_dept.deptno);
loop
fetch c_emp into v_ename,v_salary;
exit when c_emp%notfound;
dbms_output.put_line(''name:''|| v_ename||'' salary:''||v_salary);
v_tot_salary:=v_tot_salary+v_salary;
end loop;
close c_emp;
dbms_output.put_line(''toltal salary for dept:''|| v_tot_salary);
end loop;
close c_dept;
end;
游標for循環
在大多數時候我們在設計程序的時候都遵循下面的步驟:
1、打開游標
2、開始循環
3、從游標中取值
4、檢查那一行被返回
5、處理
6、關閉循環
7、關閉游標
可以簡單的把這一類代碼稱為游標用於循環。但還有一種循環與這種類型不相同,這就是for循環,用於for循環的游標按照正常的聲明方式聲明,它的優點在於不需要顯式的打開、關閉、取數據,測試數據的存在、定義存放數據的變數等等。游標for 循環的語法如下:
for record_name in
(corsor_name[(parameter[,parameter]...)]
| (query_difinition)
loop
statements
end loop;
下面我們用for循環重寫上面的例子:
decalre
cursor c_dept is select deptno,dname from dept order by deptno;
cursor c_emp (p_dept varachar2) is
select ename,salary
from emp
where deptno=p_dept
order by ename
v_tot_salary emp.salary%type;
begin
for r_dept in c_dept loop
dbms_output.put_line(''department:''|| r_dept.deptno||''-''||r_dept.dname);
v_tot_salary:=0;
for r_emp in c_emp(r_dept.deptno) loop
dbms_output.put_line(''name:''|| v_ename||'' salary:''||v_salary);
v_tot_salary:=v_tot_salary+v_salary;
end loop;
dbms_output.put_line(''toltal salary for dept:''|| v_tot_salary);
end loop;
end;
在游標for循環中使用查詢
在游標for循環中可以定義查詢,由於沒有顯式聲明所以游標沒有名字,記錄名通過游標查詢來定義。
decalre
v_tot_salary emp.salary%type;
begin
for r_dept in (select deptno,dname from dept order by deptno) loop
dbms_output.put_line(''department:''|| r_dept.deptno||''-''||r_dept.dname);
v_tot_salary:=0;
for r_emp in (select ename,salary
from emp
where deptno=p_dept
order by ename) loop
dbms_output.put_line(''name:''|| v_ename||'' salary:''||v_salary);
v_tot_salary:=v_tot_salary+v_salary;
end loop;
dbms_output.put_line(''toltal salary for dept:''|| v_tot_salary);
end loop;
end;
游標中的子查詢
語法如下:
cursor c1 is select * from emp
where deptno not in (select deptno
from dept
where dname!=''accounting'');
可以看出與sql中的子查詢沒有什麼區別。
游標中的更新和刪除
在pl/sql中依然可以使用update和delete語句更新或刪除數據行。顯式游標只有在需要獲得多行數據的情況下使用。pl/sql提供了僅僅使用游標就可以執行刪除或更新記錄的方法。
update或delete語句中的where current of子串專門處理要執行update或delete操作的表中取出的最近的數據。要使用這個方法,在聲明游標時必須使用for update子串,當對話使用for update子串打開一個游標時,所有返回集中的數據行都將處於行級(row-level)獨占式鎖定,其他對象只能查詢這些數據行,不能進行update、delete或select...for update操作。
語法:
for update [of [schema.]table.column[,[schema.]table.column]..
[nowait]
在多表查詢中,使用of子句來鎖定特定的表,如果忽略了of子句,那麼所有表中選擇的數據行都將被鎖定。如果這些數據行已經被其他會話鎖定,那麼正常情況下oracle將等待,直到數據行解鎖。
在update和delete中使用where current of子串的語法如下:
where{current of cursor_name|search_condition}
例:
delcare
cursor c1 is select empno,salary
from emp
where comm is null
for update of comm;
v_comm number(10,2);
begin
for r1 in c1 loop
if r1.salary<500 then
v_comm:=r1.salary*0.25;
elseif r1.salary<1000 then
v_comm:=r1.salary*0.20;
elseif r1.salary<3000 then
v_comm:=r1.salary*0.15;
else
v_comm:=r1.salary*0.12;
end if;
update emp;
set comm=v_comm
where current of c1l;
end loop;
end
6. Oracle中的游標可以帶參數么
可以啊,參數在游標定義時使用,打開時傳入參數,例如:
create or replace procere a
as
cursor b(c_id int)is select * from d where id=c_id;
begin
open b(111);
end;
貌似就這樣了。呵呵
7. 游標是什麼ORACLE是怎樣使用游標的舉例說明!
一
游標是什麼
游標字面理解就是游動的游標。
用資料庫語言來描述:游標是映射在結果集中一行數據上的位置實體,有了游標,用戶就可以訪問結果集中的任意一行數據了,將游標放置到某行後,即可對該行數據進行操作,例如提取當前行的數據等。
二
游標的分類
顯式游標和隱式游標
顯式游標的使用需要4步:
1.
聲明游標
CURSOR
mycur(vartype
number)
is
select
emp_no,emp_zc
from
cus_emp_basic
where
com_no
=
vartype;
2.
打開游標
open
mycur(000627)
註:000627是參數
3.
讀取數據
fetch
mycur
into
varno,
varprice;
4.
關閉游標
close
mycur;
三
游標的屬性
oracle
游標有4個屬性:%ISOPEN,%FOUND,%NOTFOUND,%ROWCOUNT。
%ISOPEN判斷游標是否被打開,如果打開%ISOPEN等於true,否則等於false;
%FOUND
%NOTFOUND判斷游標所在的行是否有效,如果有效,則%FOUNDD等於true,否則等於false;
%ROWCOUNT返回當前位置為止游標讀取的記錄行數。
四
示例
set
serveroutput
on;
declare
varno
varchar2(20);
varprice
varchar2(20);
CURSOR
mycur(vartype
number)
is
select
emp_no,emp_zc
from
cus_emp_basic
where
com_no
=
vartype;
begin
if
mycur%isopen
=
false
then
open
mycur(000627);
end
if;
fetch
mycur
into
varno,varprice;
while
mycur%found
loop
dbms_output.put_line(varno||','||varprice);
if
mycur%rowcount=2
then
exit;
end
if;
fetch
mycur
into
varno,varprice;
end
loop;
close
mycur;
end;
PL/SQL記錄的結構和C語言中的結構體類似,是由一組數據項構成的邏輯單元。
PL/SQL記錄並不保存在資料庫中,它與變數一樣,保存在內存空間中,在使用記錄時候,要首先定義記錄結構,然後聲明記錄變數。可以把PL/SQL記錄看作是一個用戶自定義的數據類型。
set
serveroutput
on;
declare
type
person
is
record
(
empno
cus_emp_basic.emp_no%type,
empzc
cus_emp_basic.emp_zc%type);
person1
person;
cursor
mycur(vartype
number)is
select
emp_no,emp_zc
from
cus_emp_basic
where
com_no=vartype;
begin
if
mycur%isopen
=
false
then
open
mycur(000627);
end
if;
loop
fetch
mycur
into
person1;
exit
when
mycur%notfound;
dbms_output.put_line('雇員編號:'||person1.empno||',地址:'||person1.empzc);
end
loop;
close
mycur;
end;
典型游標for
循環
游標for循環示顯示游標的一種快捷使用方式,它使用for循環依次讀取結果集中的行數據,當form循環開始時,游標自動打開(不需要open),每循環一次系統自動讀取游標當前行的數據(不需要fetch),當退出for循環時,游標被自動關閉(不需要使用close)。使用游標for循環的時候不能使用open語句,fetch語句和close語句,否則會產生錯誤。
set
serveroutput
on;
declare
cursor
mycur(vartype
number)is
select
emp_no,emp_zc
from
cus_emp_basic
where
com_no=vartype;
begin
for
person
in
mycur(000627)
loop
dbms_output.put_line('雇員編號:'||person.emp_no||',地址:'||person.emp_zc);
end
loop;
end;
8. Oracle中調用輸出參數為游標存儲過程的SQL語句怎麼寫
create or replace procere test1(cursor1 out SYS_REFCURSOR)is
begin
open cursor1 for select * from 表名;
end;
然後在你調用的程序里去這個游標就可以了
9. Oracle中怎麼用游標作為輸出參數,寫點代碼舉例吧!
您好,要自己定義一個type [cur_name] is ref cursor游標,返回的時候就直接 procere AAA(變數名 out [cur_name])如此申明OUT變數
存儲過程 用系統默認的 sys_refcursor 游標類型 定義變數就OK了
1、Sql代碼
--PL/SQL Code (包中帶過程) 過程帶游標的OUT參數,返回遊標(ref cursor)
create or replace package my_pack as
type my_ref_cursor is ref cursor;
procere getMyCursor(val out my_ref_cursor);
end my_pack;
create or replace package body my_pack as
procere getMyCursor(val out my_ref_cursor)
is
begin
open val for select * from student;
end;
end my_pack;
--PL/SQL Code (包中帶過程) 過程帶游標的OUT參數,返回遊標(ref cursor)
create or replace package my_pack as
type my_ref_cursor is ref cursor;
procere getMyCursor(val out my_ref_cursor);
end my_pack;
create or replace package body my_pack as
procere getMyCursor(val out my_ref_cursor)
is
begin
open val for select * from student;
end;
end my_pack;
2、Java代碼
Class.forName("oracle.jdbc.driver.OracleDriver");
Connection conn = DriverManager.getConnection ("jdbc:oracle:thin:@XX.XX.XX.XXX:XXXX:oracle9i","XXX_temp","XXX_temp");
DriverManager.registerDriver (new oracle.jdbc.OracleDriver());
CallableStatement cs = conn.prepareCall("{ call my_pack.getMyCursor(?) }");
cs.registerOutParameter(1,OracleTypes.CURSOR);
cs.execute();
ResultSet rs = ((OracleCallableStatement)cs).getCursor(1);
while(rs.next())
{
System.out.println(rs.getString(1)+" "+rs.getString(2)+" "+rs.getString(3)+" "+ rs.getDate(4)+" "+rs.getString(5));
}
Class.forName("oracle.jdbc.driver.OracleDriver");
Connection conn = DriverManager.getConnection ("jdbc:oracle:thin:@XX.XX.XX.XXX:XXXX:oracle9i","XXX_temp","XXX_temp");
DriverManager.registerDriver (new oracle.jdbc.OracleDriver());
CallableStatement cs = conn.prepareCall("{ call my_pack.getMyCursor(?) }");
cs.registerOutParameter(1,OracleTypes.CURSOR);
cs.execute();
ResultSet rs = ((OracleCallableStatement)cs).getCursor(1);
while(rs.next())
{
System.out.println(rs.getString(1)+" "+rs.getString(2)+" "+rs.getString(3)+" "+ rs.getDate(4)+" "+rs.getString(5));
}
3、Sql代碼
--PL/SQL Code(存儲過程) 帶游標的OUT參數,返回遊標(ref cursor)
create or replace procere retCursor(ret_cursor out sys_refcursor)is
ret_cursor_value sys_refcursor;
begin
open ret_cursor_value for select * from student;
ret_cursor:=ret_cursor_value;
end retCursor;
--PL/SQL Code(存儲過程) 帶游標的OUT參數,返回遊標(ref cursor)
create or replace procere retCursor(ret_cursor out sys_refcursor)is
ret_cursor_value sys_refcursor;
begin
open ret_cursor_value for select * from student;
ret_cursor:=ret_cursor_value;
end retCursor;
4、Java代碼
Class.forName("oracle.jdbc.driver.OracleDriver");
Connection conn = Connection conn = DriverManager.getConnection ("jdbc:oracle:thin:@XX.XX.XX.XXX:XXXX:oracle9i","XXX_temp","XXX_temp");
DriverManager.registerDriver (new oracle.jdbc.OracleDriver());
CallableStatement cs = conn.prepareCall("{ call retCursor(?) }");
cs.registerOutParameter(1,OracleTypes.CURSOR);
cs.execute();
ResultSet rs = ((OracleCallableStatement)cs).getCursor(1);
while(rs.next())
{
System.out.println(rs.getString(1)+" "+rs.getString(2)+" "+rs.getString(3)+" "+ rs.getDate(4)+" "+rs.getString(5));
}
Class.forName("oracle.jdbc.driver.OracleDriver");
Connection conn = Connection conn = DriverManager.getConnection ("jdbc:oracle:thin:@XX.XX.XX.XXX:XXXX:oracle9i","XXX_temp","XXX_temp");
DriverManager.registerDriver (new oracle.jdbc.OracleDriver());
CallableStatement cs = conn.prepareCall("{ call retCursor(?) }");
cs.registerOutParameter(1,OracleTypes.CURSOR);
cs.execute();
ResultSet rs = ((OracleCallableStatement)cs).getCursor(1);
while(rs.next())
{
System.out.println(rs.getString(1)+" "+rs.getString(2)+" "+rs.getString(3)+" "+ rs.getDate(4)+" "+rs.getString(5));
}
5、下面是個每個學生求平均值的存儲過程。遇到的問題是帶參數游標中的變數名字不要和表中的一樣,否則會出問題
Sql代碼
create or replace procere AAA
as
--查詢學生表的ID
cursor s_sno is select s.sno from student s;
--通過學生ID查詢平均成績
cursor sc_avg(s_no varchar2) is select avg(sc.degree) from score sc where sc.sno=s_no;
s_sno_j student.sno%type; --變數ID
sc_avg_i score.degree%type; --變數平局成績
begin
open s_sno;--打開查詢ID的游標
loop
fetch s_sno into s_sno_j;
exit when s_sno%notfound;
open sc_avg(s_sno_j); --打開查詢平均成績的游標,參數為學生ID
loop
fetch sc_avg into sc_avg_i;
exit when sc_avg%notfound;
dbms_output.put_line(sc_avg_i);
end loop;
close sc_avg;
end loop;
close s_sno;
end AAA;