深刻探訪mysql自增列招致主鍵反復成績的緣由。本站提示廣大學習愛好者:(深刻探訪mysql自增列招致主鍵反復成績的緣由)文章只能為提供參考,不一定能成為您想要的結果。以下是深刻探訪mysql自增列招致主鍵反復成績的緣由正文
1.靜態SQLSQL與靜態SQL
Oracle編譯PL/SQL法式塊分為兩個種:其一為後期聯編(early binding),即SQL語句在法式編譯時代就曾經肯定,年夜多半的編譯情形屬於這類類型;別的一種是前期聯編(late binding),即SQL語句只要在運轉階段能力樹立,例如當查詢前提為用戶輸出時,那末Oracle的SQL引擎就沒法在編譯期對該法式語句停止肯定,只能在用戶輸出必定的查詢前提後能力提交給SQL引擎停止處置。平日,靜態SQL采取前一種編譯方法,而靜態SQL采取後一種編譯方法。
本文重要就靜態SQL的開辟停止評論辯論,並在最初給出一些現實開辟的技能。
2.靜態SQL法式開辟
懂得了靜態SQL編譯的道理,也就控制了其根本的開辟思惟。靜態SQL既然是一種”不肯定”的SQL,那其履行就有其響應的特色。Oracle中供給了Execute immediate語句來履行靜態SQL,語法以下:
Excute immediate 靜態SQL語句 using 綁定參數列表 returning into 輸入參數列表;對這一語句作以下解釋:
1)靜態SQL是指DDL和不肯定的DML(即帶參數的DML)
2)綁定參數列表為輸出參數列表,即其類型為in類型,在運轉時辰與靜態SQL語句中的參數(現實上占位符,可以懂得為函數外面的情勢參數)停止綁定。
3)輸入參數列表為靜態SQL語句履行後前往的參數列表。
4)因為靜態SQL是在運轉時辰停止肯定的,所以絕對於靜態而言,其更多的會喪失一些體系機能來換取其靈巧性。
為了更好的解釋其開辟的進程,上面羅列一個實例:
設數據庫的emp表,其數據為以下:
ID
NAME
SALARY
100
Jacky
5600
101
Rose
3000
102
John
4500
請求:
1.創立該表並輸出響應的數據。
2.依據特定ID可以查詢到其姓名和薪水的信息。
3.依據年夜於特定的薪水的查詢響應的員工信息。
依據後面的請求,可以分離創立三個進程(均應用靜態SQL)來完成:
進程一:
create or replace procedure create_table as
begin
execute immediate '
create table emp(id number,
name varchar2(10),
salary number )'; --靜態SQL為DDL語句
insert into emp
values (100,'jacky',5600);
insert into emp
values (101,'rose',3000);
insert into emp
values (102,'john',4500);
end create_table;
進程二:
create or replace procedure find_info(p_id number) as
v_name varchar2(10);
v_salary number;
begin
execute immediate '
select name,salary from emp
where id=:1'
using p_id
returning into v_name,v_salary; --靜態SQL為查詢語句
dbms_output.put_line(v_name ||'的支出為:'||to_char(v_salary));
exception
when others then
dbms_output.put_line('找不到響應數據');
end find_info;
進程三:
create or replace procedure find_emp(p_salary number) as
r_emp emp%rowtype;
type c_type is ref cursor;
c1 c_type;
begin
open c1 for '
select * from emp
where salary >:1'
using p_salary;
loop
fetch c1 into r_emp;
exit when c1%notfound;
dbms_output.put_line('薪水年夜於‘||to_char(p_salary)||'的員工為:‘);
dbms_output.put_line('ID為'to_char(r_emp)||' 其姓名為:'||r_emp.name);
end loop;
close c1;
end create_table;
留意:在進程二中的靜態SQL語句應用了占位符“:1“,其實它相當於函數的情勢參數,應用”:“作為前綴,然後應用using語句將p_id在運轉時辰將:1給調換失落,這裡p_id相當於函數裡的實參。別的進程三中翻開的游標為靜態游標,它也屬於靜態SQL的領域,其全部編譯和開辟的進程與execute immediate履行的進程很相似,這裡就不在贅述了。
3. 靜態SQL語句開辟技能
後面剖析到了,靜態SQL的履行是以喪失體系機能來換取其靈巧性的,所以對它停止必定水平的優化也是需要的,筆者依據現實開辟經歷給出一些開辟的技能,須要指出的是,這裡許多經歷不只局限於靜態SQL,有些也實用於靜態SQL,在描寫中會賜與標注。
技能一:盡可能應用相似的SQL語句,如許Oracle自己經由過程SGA中的同享池來直接對該SQL語句停止緩存,那末鄙人一次履行相似語句時就直接挪用緩存中已解析過的語句,以此來進步履行效力。
技能二:當觸及到聚集單位的時刻,盡可能應用批聯編。好比須要對id為100和101的員工的薪水加薪10%,普通情形下應當為以下情勢:
declare
type num_list is varray(20) of number;
v_id num_list :=num_list(100,101);
begin
...
for i in v_id.first .. v_id.last loop
...
execute immediate 'update emp
set =salary*1.2
where id=:1 '
using v_id(i);
end loop;
end;
關於下面的處置,當數據量年夜的時刻就會顯得比擬慢,那末假如采取批聯編的話,則全部聚集起首一次性的傳入到SQL引擎中停止處置,如許比零丁處置效力要高的多,停止批聯編處置的代碼以下:
declare
type num_list is varray(20) of number;
v_id num_list :=num_list(100,101);
begin
...
forall i in v_id.first .. v_id.last loop
...
execute immediate 'update emp
set =salary*1.2
where id=:1 '
using v_id(i);
end loop;
end;
這裡是應用forall來停止批聯編,這裡將批聯編處置的情況作一個小結:
1) 假如一個輪回內履行了insert,delete,update等語句援用了聚集元素,那末可以將其挪動到一個forall語句中。
2) 假如select into,fetch into 或returning into 子句援用了一個聚集,應當應用bulk collect 子句停止歸並。
3) 若有能夠,應當應用主機數組來完成在法式和數據庫辦事器之間傳遞參數。
技能三:應用NOCOPY編譯器來進步PL/SQL機能。缺省情形下,out類型和in out類型的參數是由值傳遞的方法停止的。然則關於年夜的對象類型或許聚集類型的參數傳遞而言,其願望消耗將是很年夜的,為了削減消耗,可以采取援用傳遞的方法,即在停止參數聲明的時刻援用NOCOPY症結字來講明便可達到如許的後果。好比創立一個進程:
create or replace procedure test(p_object in nocopy square)...end;
個中square為一個年夜的對象類型。如許只是傳遞一個地址,而不是傳遞全部對象了。明顯如許的處置也是進步了效力。
4. 小結
本文對靜態SQL的編譯道理、開辟進程和開辟技能的評論辯論,經由過程本文的引見後,信任讀者對靜態SQL法式開辟有了一個整體的熟悉,為往後深刻的任務打下一個優越的基本。