當前位置:首頁 » 編程語言 » oraclesql常量
擴展閱讀
webinf下怎麼引入js 2023-08-31 21:54:13
堡壘機怎麼打開web 2023-08-31 21:54:11

oraclesql常量

發布時間: 2023-03-31 01:02:12

Ⅰ 關於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

Ⅱ 大蝦請進:oracle資料庫超大數據量的處理

通過使用一些輔助性工具來找到程序中的瓶頸,然後就可以對瓶頸部分的代碼進行優化。一般有兩種方案:即優化代碼或更改設計方法。我們一般會選擇後者,因為不去調用以下代碼要比調用一些優化的代碼更能提高程序的性能。而一個設計良好的程序能夠精簡代碼,從而提高性能。
下面將提供一些在JAVA程序的設計和編碼中,為了能夠提高JAVA程序的性能,而經常採用的一些方法和技巧。
1.對象的生成和大小的調整。

JAVA程序設計中一個普遍的問題就是沒有好好的利用JAVA語言本身提供的函數,從而常常會生成大量的對象(或實例)。由於系統不僅要花時間生成對象,以後可能還需花時間對這些對象進行垃圾回收和處理。因此,生成過多的對象將會給程序的性能帶來很大的影響。
例1:關於String ,StringBuffer,+和append
JAVA語言提供了對於String類型變數的操作。但如果使用不當,會給程序的性能帶來影響。如下面的語句:
String name=new String("HuangWeiFeng");
System.out.println(name+"is my name");
看似已經很精簡了,其實並非如此。為了生成二進制的代碼,要進行如下的步驟和操作:
(1) 生成新的字元串 new String(STR_1);
(2) 復制該字元串;
(3) 載入字元串常量"HuangWeiFeng"(STR_2);
(4) 調用字元串的構架器(Constructor);
(5) 保存該字元串到數組中(從位置0開始);
(6) 從java.io.PrintStream類中得到靜態的out變數;
(7) 生成新的字元串緩沖變數new StringBuffer(STR_BUF_1);
(8) 復制該字元串緩沖變數;
(9) 調用字元串緩沖的構架器(Constructor);
(10) 保存該字元串緩沖到數組中(從位置1開始);
(11) 以STR_1為參數,調用字元串緩沖(StringBuffer)類中的append方法;
(12) 載入字元串常量"is my name"(STR_3);
(13) 以STR_3為參數,調用字元串緩沖(StringBuffer)類中的append方法;
(14) 對於STR_BUF_1執行toString命令;
(15) 調用out變數中的println方法,輸出結果。
由此可以看出,這兩行簡單的代碼,就生成了STR_1,STR_2,STR_3,STR_4和困碧STR_BUF_1五個對象變數。這些生成的類的實例一般都存放在堆中。堆要對所有類的超類,類的實例進行初始化,同時還要調用類極其每個超類的構架器。而這些操作都是非常消耗系統資源的。因此,對對象的生成進行限制,是完全有必要的。
經修改,上面的代碼可以用如下的代碼來替換。
StringBuffer name=new StringBuffer("HuangWeiFeng");
System.out.println(name.append("is my name.").toString());
系統將進行如下的操作:
(1) 生成跡尺汪新的字元串緩沖變數new StringBuffer(STR_BUF_1);
(2) 復制該字元串緩沖變數;
(3) 載入字元串常量"HuangWeiFeng"(STR_1);
(4) 調用字元串緩沖的構架器(Constructor);
(5) 保存該字元串緩沖到數組中(從位置1開始);
(6) 從java.io.PrintStream類中得到靜態的out變數;
(7) 載入STR_BUF_1;
(8) 載入字元串常量"is my name"(STR_2);
(9) 以STR_2為參數,調用字元串緩沖(StringBuffer)實例中的append方法;
(10) 對於STR_BUF_1執行toString命令(STR_3);
(11)調用out變數中的println方法,輸出結果。
由此可以看出,經過改進後的代碼只生成了四個對象變數:STR_1,STR_2,STR_3和STR_BUF_1.你可能覺得少生成一個對象不會對程序的性能有很大的提高。但下面的代碼段2的執行速度將是代碼段1的2倍。因為代碼段1生成了八個對象,而代碼段2隻生成姿仔了四個對象。
代碼段1:
String name= new StringBuffer("HuangWeiFeng");
name+="is my";
name+="name";
代碼段2:
StringBuffer name=new StringBuffer("HuangWeiFeng");
name.append("is my");
name.append("name.").toString();
因此,充分的利用JAVA提供的庫函數來優化程序,對提高JAVA程序的性能時非常重要的.其注意點主要有如下幾方面;
(1) 盡可能的使用靜態變數(Static Class Variables)
如果類中的變數不會隨他的實例而變化,就可以定義為靜態變數,從而使他所有的實例都共享這個變數。
例:
public class foo
{
SomeObject so=new SomeObject();
}
就可以定義為:
public class foo
{
static SomeObject so=new SomeObject();
}
(2) 不要對已生成的對象作過多的改變。
對於一些類(如:String類)來講,寧願在重新生成一個新的對象實例,而不應該修改已經生成的對象實例。
例:
String name="Huang";
name="Wei";
name="Feng";
上述代碼生成了三個String類型的對象實例。而前兩個馬上就需要系統進行垃圾回收處理。如果要對字元串進行連接的操作,性能將得更差,因為系統將不得為此生成更多得臨時變數,如上例1所示。
(3) 生成對象時,要分配給它合理的空間和大小JAVA中的很多類都有它的默認的空間分配大小。對於StringBuffer類來講,默認的分配空間大小是16個字元。如果在程序中使用StringBuffer的空間大小不是16個字元,那麼就必須進行正確的初始化。
(4) 避免生成不太使用或生命周期短的對象或變數。對於這種情況,因該定義一個對象緩沖池。以為管理一個對象緩沖池的開銷要比頻繁的生成和回收對象的開銷小的多。
(5) 只在對象作用范圍內進行初始化。JAVA允許在代碼的任何地方定義和初始化對象。這樣,就可以只在對象作用的范圍內進行初始化。從而節約系統的開銷。
例:
SomeObject so=new SomeObject();
If(x==1) then
{
Foo=so.getXX();
}
可以修改為:
if(x==1) then
{
SomeObject so=new SomeObject();
Foo=so.getXX();
}
2.異常(Exceptions)
JAVA語言中提供了try/catch來發方便用戶捕捉異常,進行異常的處理。但是如果使用不當,也會給JAVA程序的性能帶來影響。因此,要注意以下兩點:
(1) 避免對應用程序的邏輯使用try/catch
如果可以用if,while等邏輯語句來處理,那麼就盡可能的不用try/catch語句。
(2) 重用異常
在必須要進行異常的處理時,要盡可能的重用已經存在的異常對象。以為在異常的處理中,生成一個異常對象要消耗掉大部分的時間。
3. 線程(Threading)
一個高性能的應用程序中一般都會用到線程。因為線程能充分利用系統的資源。在其他線程因為等待硬碟或網路讀寫而 時,程序能繼續處理和運行。但是對線程運用不當,也會影響程序的性能。
例2:正確使用Vector類
Vector主要用來保存各種類型的對象(包括相同類型和不同類型的對象)。但是在一些情況下使用會給程序帶來性能上的影響。這主要是由Vector類的兩個特點所決定的。第一,Vector提供了線程的安全保護功能。即使Vector類中的許多方法同步。但是如果你已經確認你的應用程序是單線程,這些方法的同步就完全不必要了。第二,在Vector查找存儲的各種對象時,常常要花很多的時間進行類型的匹配。而當這些對象都是同一類型時,這些匹配就完全不必要了。因此,有必要設計一個單線程的,保存特定類型對象的類或集合來替代Vector類.用來替換的程序如下(StringVector.java):
public class StringVector
{
private String [] data;
private int count;
public StringVector()
{
this(10); // default size is 10
}
public StringVector(int initialSize)
{
data = new String[initialSize];
}
public void add(String str)
{
// ignore null strings
if(str == null) { return; }
ensureCapacity(count + 1);
data[count++] = str;
}
private void ensureCapacity(int minCapacity)
{
int oldCapacity = data.length;
if (minCapacity > oldCapacity)
{
String oldData[] = data;
int newCapacity = oldCapacity * 2;
data = new String[newCapacity];
System.array(oldData, 0, data, 0, count);
}
}
public void remove(String str)
{
if(str == null) { return; // ignore null str }
for(int i = 0; i < count; i++)
{
// check for a match
if(data[i].equals(str))
{
System.array(data,i+1,data,i,count-1); // data
// allow previously valid array element be gc'd
data[--count] = null;
return;
}
}
}
public final String getStringAt(int index)
{
if(index < 0) { return null; }
else if(index > count) { return null; // index is > # strings }
else { return data[index]; // index is good }
}
}
因此,代碼:
Vector Strings=new Vector();
Strings.add("One");
Strings.add("Two");
String Second=(String)Strings.elementAt(1);
可以用如下的代碼替換:
StringVector Strings=new StringVector();
Strings.add("One");
Strings.add("Two");
String Second=Strings.getStringAt(1);
這樣就可以通過優化線程來提高JAVA程序的性能。用於測試的程序如下(TestCollection.java):
import java.util.Vector;
public class TestCollection
{
public static void main(String args [])
{
TestCollection collect = new TestCollection();
if(args.length == 0)
{
System.out.println("Usage: java TestCollection [ vector | stringvector ]");
System.exit(1);
}
if(args[0].equals("vector"))
{
Vector store = new Vector();
long start = System.currentTimeMillis();
for(int i = 0; i < 1000000; i++)
{
store.addElement("string");
}
long finish = System.currentTimeMillis();
System.out.println((finish-start));
start = System.currentTimeMillis();
for(int i = 0; i < 1000000; i++)
{
String result = (String)store.elementAt(i);
}
finish = System.currentTimeMillis();
System.out.println((finish-start));
}
else if(args[0].equals("stringvector"))
{
StringVector store = new StringVector();
long start = System.currentTimeMillis();
for(int i = 0; i < 1000000; i++) { store.add("string"); }
long finish = System.currentTimeMillis();
System.out.println((finish-start));
start = System.currentTimeMillis();
for(int i = 0; i < 1000000; i++) {
String result = store.getStringAt(i);
}
finish = System.currentTimeMillis();
System.out.println((finish-start));
}
}
}
關於線程的操作,要注意如下幾個方面:
(1) 防止過多的同步
如上所示,不必要的同步常常會造成程序性能的下降。因此,如果程序是單線程,則一定不要使用同步。
(2) 同步方法而不要同步整個代碼段
對某個方法或函數進行同步比對整個代碼段進行同步的性能要好。
(3) 對每個對象使用多」鎖」的機制來增大並發。
一般每個對象都只有一個」鎖」,這就表明如果兩個線程執行一個對象的兩個不同的同步方法時,會發生」死鎖」。即使這兩個方法並不共享任何資源。為了避免這個問題,可以對一個對象實行」多鎖」的機制。如下所示:
class foo
{
private static int var1;
private static Object lock1=new Object();
private static int var2;
private static Object lock2=new Object();
public static void increment1()
{
synchronized(lock1)
{
var1++;
}
}
public static void increment2()
{
synchronized(lock2)
{
var2++;
}
}
}
4.輸入和輸出(I/O)

輸入和輸出包括很多方面,但涉及最多的是對硬碟,網路或資料庫的讀寫操作。對於讀寫操作,又分為有緩存和沒有緩存的;對於資料庫的操作,又可以有多種類型的JDBC驅動器可以選擇。但無論怎樣,都會給程序的性能帶來影響。因此,需要注意如下幾點:
(1) 使用輸入輸出緩沖
盡可能的多使用緩存。但如果要經常對緩存進行刷新(flush),則建議不要使用緩存。
(2) 輸出流(Output Stream)和Unicode字元串
當時用Output Stream和Unicode字元串時,Write類的開銷比較大。因為它要實現Unicode到位元組(byte)的轉換.因此,如果可能的話,在使用Write類之前就實現轉換或用OutputStream類代替Writer類來使用。
(3) 當需序列化時使用transient
當序列化一個類或對象時,對於那些原子類型(atomic)或可以重建的原素要表識為transient類型。這樣就不用每一次都進行序列化。如果這些序列化的對象要在網路上傳輸,這一小小的改變對性能會有很大的提高。
(4) 使用高速緩存(Cache)
對於那些經常要使用而又不大變化的對象或數據,可以把它存儲在高速緩存中。這樣就可以提高訪問的速度。這一點對於從資料庫中返回的結果集尤其重要。
(5) 使用速度快的JDBC驅動器(Driver)
JAVA對訪問資料庫提供了四種方法。這其中有兩種是JDBC驅動器。一種是用JAVA外包的本地驅動器;另一種是完全的JAVA驅動器。具體要使用哪一種得根據JAVA布署的環境和應用程序本身來定。
5.一些其他的經驗和技巧

(1) 使用局部變數。
(2) 避免在同一個類中動過調用函數或方法(get或set)來設置或調用變數。
(3) 避免在循環中生成同一個變數或調用同一個函數(參數變數也一樣)。
(4) 盡可能的使用static,final,private等關鍵字。
(5) 當復制大量數據時,使用System.array()命令。

Ⅲ Oracle SQL中的!=與<>有什麼區別

第一個問題:x0dx0a這兩個都是不等於符號,沒有什麼區別,如果這個欄位有索引,物好都可以使用的。x0dx0a第二個問題:x0dx0ain 和 not in 都可以使用索引的,但是如猜老果name欄位有很多值,那麼not in的執行時間應該稍微長一點,因為它返回的值比較多。 x0dx0a補充:如果name的值比較少的話,in和not in條件嚴密性穗螞升差不多,如果name值比較多的時候,in的嚴密性更高,索引都是按照順序排好的,相等的情況只有一種,不等的情況有很多種。 x0dx0a如果你('a', 'b')這些值是放在另外一個表裡面,還有not exsits可以替換,如果是常量的話,貌似也只能這么寫了。

Ⅳ oracle中如何優化sql語句的,用什麼方法

可以使用ADDM哦,執行後可以幫助分析SQL性能以及給出修改建議

Ⅳ oracle SQL語句中怎麼樣調用存儲過程

PL/SQL是ORACLE對標准資料庫語言的擴展,ORACLE公司已經將PL/SQL整合到ORACLE 伺服器和其他工具中了,近幾年中更多的開發人員和DBA開始使用PL/SQL,本文將講述PL/SQL基礎語法,結構和組件、以及如何設計並執行一個PL/SQL程序。

PL/SQL的優點

從版本6開始PL/SQL就被可靠的整合到ORACLE中了,一旦掌握PL/SQL的優點以及其獨有的數據管理的便利性,那麼你很難想像ORACLE缺了PL/SQL的情形。PL/SQL 不是一個獨立的產品,他是一個整合到ORACLE伺服器和ORACLE工具中的技術,可以把PL/SQL看作ORACLE伺服器內的一個引擎,sql語句執行者處理單個的sql語句,PL/SQL引擎處理PL/SQL程序塊。當PL/SQL程序塊在PL/SQL引擎處理時,ORACLE伺服器中的SQL語句執行器處理pl/sql程序塊中的SQL語句。

PL/SQL的優點如下:

. PL/SQL是一種高性能的基於事務處理的語言,能運行在任何ORACLE環境中,支持所有數據處理命令。通過使用PL/SQL程序單元處理SQL的數據定義和數據控制元素。

. PL/SQL支持所有SQL數據類型和所有SQL函數,同時支持所有ORACLE對象類型

. PL/SQL塊可以被命名和存儲在ORACLE伺服器中,同時也能被其他的PL/SQL程序或SQL命令調用,任何客戶/伺服器工具都能訪問PL/SQL程序,具有很好的可重用性。

. 可以使用ORACLE數據工具管理存儲在伺服器中的PL/SQL程序的安全性。可以授權或撤銷資料庫其他用戶訪問PL/SQL程序的能力。

. PL/SQL代碼可以使用任何ASCII文本編輯器編寫,所以對任何ORACLE能夠運行的操作系統都是非常便利的

. 對於SQL,ORACLE必須在同一時間處理每一條SQL語句,在網路環境下這就意味作每一個獨立的調用都必須被oracle伺服器處理,這就佔用大量的伺服器時間,同時導致網路擁擠。而PL/SQL是以整個語句塊發給伺服器,這就降低了網路擁擠。

PL/SQL塊結構

PL/SQL是一種塊結構的語言,組成PL/SQL程序的單元是邏輯塊,一個PL/SQL 程序包含了一個或多個邏輯塊,每個塊都可以劃分為三個部分。與其他語言相同,變數在使用之前必須聲明,PL/SQL提供了獨立的專門用於處理異常的部分,下面描述了PL/SQL塊的不同部分:

聲明部分(Declaration section)

聲明部分包含了變數和常量的數據類型和初始值。這個部分是由關鍵字DECLARE開始,如果不需要聲明變數或常量,那麼可以忽略這一部分;需要說明的是游標的聲明也在這一部分。

執行部分(Executable section)

執行部分是PL/SQL塊中的指令部分,由關鍵字BEGIN開始,所有的可執行語句都放在這一部分,其他的PL/SQL塊也可以放在這一部分。

異常處理部分(Exception section)

這一部分是可選的,在這一部分中處理異常或錯誤,對異常處理的詳細討論我們在後面進行。

PL/SQL塊語法

[DECLARE]
---declaration statements
BEGIN
---executable statements
[EXCEPTION]
---exception statements
END

PL/SQL塊中的每一條語句都必須以分號結束,SQL語句可以使多行的,但分號表示該語句的結束。一行中可以有多條SQL語句,他們之間以分號分隔。每一個PL/SQL塊由BEGIN或DECLARE開始,以END結束。注釋由--標示。

PL/SQL塊的命名和匿名

PL/SQL程序塊可以是一個命名的程序塊也可以是一個匿名程序塊。匿名程序塊可以用在伺服器端也可以用在客戶端。

命名程序塊可以出現在其他PL/SQL程序塊的聲明部分,這方面比較明顯的是子程序,子程序可以在執行部分引用,也可以在異常處理部分引用。

PL/SQL程序塊可背獨立編譯並存儲在資料庫中,任何與資料庫相連接的應用程序都可以訪問這些存儲的PL/SQL程序塊。ORACLE提供了四種類型的可存儲的程序:

. 函數

. 過程

. 包

. 觸發器

函數

函數是命名了的、存儲在資料庫中的PL/SQL程序塊。函數接受零個或多個輸入參數,有一個返回值,返回值的數據類型在創建函數時定義。定義函數的語法如下:

FUNCTION name [{parameter[,parameter,...])] RETURN datatypes IS
[local declarations]
BEGIN
execute statements
[EXCEPTION
exception handlers]
END [name]

過程

存儲過程是一個PL/SQL程序塊,接受零個或多個參數作為輸入(INPUT)或輸出(OUTPUT)、或既作輸入又作輸出(INOUT),與函數不同,存儲過程沒有返回值,存儲過程不能由SQL語句直接使用,只能通過EXECUT命令或PL/SQL程序塊內部調用,定義存儲過程的語法如下:

PROCEDURE name [(parameter[,parameter,...])] IS
[local declarations]
BEGIN
execute statements
[EXCEPTION
exception handlers ]
END [name]


包(package)

包其實就是被組合在一起的相關對象的集合,當包中任何函數或存儲過程被調用,包就被載入入內存中,包中的任何函數或存儲過程的子程序訪問速度將大大加快。
包由兩個部分組成:規范和包主體(body),規范描述變數、常量、游標、和子程序,包體完全定義子程序和游標。

觸發器(trigger)

觸發器與一個表或資料庫事件聯系在一起的,當一個觸發器事件發生時,定義在表上的觸發器被觸發。

變數和常量

變數存放在內存中以獲得值,能被PL/SQL塊引用。你可以把變數想像成一個可儲藏東西的容器,容器內的東西是可以改變的。

聲明變數

變數一般都在PL/SQL塊的聲明部分聲明,PL/SQL是一種強壯的類型語言,這就是說在引用變數前必須首先聲明,要在執行或異常處理部分使用變數,那麼變數必須首先在聲明部分進行聲明。

聲明變數的語法如下:

Variable_name [CONSTANT] databyte [NOT NULL][:=|DEFAULT expression]

注意:可以在聲明變數的同時給變數強制性的加上NOT NULL約束條件,此時變數在初始化時必須賦值。

給變數賦值

給變數賦值有兩種方式:

. 直接給變數賦值

X:=200;
Y=Y+(X*20);

. 通過SQL SELECT INTO 或FETCH INTO給變數賦值

SELECT SUM(SALARY),SUM(SALARY*0.1)
INTO TOTAL_SALARY,TATAL_COMMISSION
FROM EMPLOYEE
WHERE DEPT=10;

常量

常量與變數相似,但常量的值在程序內部不能改變,常量的值在定義時賦予,,他的聲明方式與變數相似,但必須包括關鍵字CONSTANT。常量和變數都可被定義為SQL和用戶定義的數據類型。

ZERO_VALUE CONSTANT NUMBER:=0;

這個語句定了一個名叫ZERO_VALUE、數據類型是NUMBER、值為0的常量。

標量(scalar)數據類型

標量(scalar)數據類型沒有內部組件,他們大致可分為以下四類:

. number
. character
. date/time
. boolean

Ⅵ oracle資料庫declare里聲明變數constant什麼意思

常量在聲明時賦予初值,並且在運行時不允許重新賦值。使用CONSTANT關鍵字聲明常量。

Ⅶ oracle中:=與=:的區別

變數綁定 是指在sql語句的條件中使用變數而不是常量。比如shared pool里有兩條sql語句,
select * from tab1 where col1=1;
select * from tab1 where col1=2;
對oracle資料庫來說,這是兩條完全不同的SQL,對這兩條語句都需要進行hard parse。因為oracle會根據sql語句的文本去計算每個字元在內存里的hash值,因此雖然上述兩條SQL只有一個字元不一樣,oracle根據hash演算法在內存中得到的hash地址就不一樣,所以oracle就會認為這是兩條完全不同的語句。而如果將上述SQL改寫成select * from tab1 where col1=:var1;,然後通過對變數var1的賦值去查詢,那麼oracle對這條語句第一次會進行hard parse,以後就只進行soft parse。假設某條語句被重復執行了幾十萬次,那麼使用bind var帶來的好處是巨大的。一個應用程序如果bind var使用不充分,那麼幾乎一定會伴隨著嚴重的性磨旦磨能問題。

綁定變數是相對文本遲搭變數來講瞎斗的,所謂文本變數是指在SQL直接書寫查詢條件,這樣的SQL在不同條件下需要反復解析,綁定變數是指使用變數來代替直接書寫條件,查詢bind value在運行時傳遞,然後綁定執行。優點是減少硬解析,降低CPU的爭用,節省shared_pool ;缺點是不能使用histogram,sql優化比較困難

Ⅷ Oracle資料庫中的常量列

比如資料庫里有張表,表裡有個欄位是UNAME,這個欄位有個值叫TEST,現在我們要在java裡面仿燃使用sql語句查詢這個名字叫TEST的其他相關數據滲禪,當然條件是UNAME='TEST'。然後我們在java里就可以定義一個常量 string final FNAME='UNAME' 這樣我就可以使用這個常備喊虛量當做列名來用select 「+FNAME+"' as colname from docTABNAME";這樣你該懂了吧!

Ⅸ 請問如何在Oracle中通過SQL來查找包Package裡面的所有字元串常量呢,比如 。。AA := '123'; 出現的'123'

selectdistinctnamefromUSER_SOURCEwheretype='PACKAGE'anpper(text)likeupper('%你要拆源襲匹配的旅兄字元%'裂腔);

Ⅹ 為什麼oracle sql 綁定變數後更慢了

綁定變數的作用是減少SQL語句的硬解析來減少執行時間!
但是有時候 因為綁定變數需要把SQL語句的常量替換成變數,所以會對SQL語句的執行計劃產生一定的影響!