plsql(轻量版)_流程控制
生活随笔
收集整理的這篇文章主要介紹了
plsql(轻量版)_流程控制
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
記錄類型百分號type,使用它的優點,所引用的數據庫列的數據類型不必知道,要不你就得知道它的類型和他的一樣的,這里你可以實時改變,列的數據類型改變,我這里也跟著改,動態的來獲取你的類型
這里還有個百分號rowtype,返回一個記錄類型,其數據類型和數據庫表的類型一樣,一個列一樣
你這里有多少列我這里也有,列名叫什么我也跟你一樣,然后你的列的類型,也一樣,這就過了,他表示的是等于符號
這個叫一般運算符
加減乘除,這個叫賦值了,這個我們后邊講游標的時候,游標有可能有參數,參數的賦值用這個
邏輯運算符,這個我們講SQL里面都說過,你需要用到的你就來用
變量的賦值,用到連接的用到雙豎線
通過select語句來完成對數據庫的賦值,然后每次執行select語句就賦值一次,一般要求被賦值的變量,與select的列名要一一對應,select一個什么salary,工資,into于一個變量,然后賦給一個人,你要再賦予一個人,就要循環了,再賦予一個人就再賦予一次,一條一條的出來
不能講select語句賦給布爾類型的變量,這就是一個要求
然后可轉換的數據類型,在講SQL中也提過,to_number,to_char,to_date
注釋,兩個這個,表示的是單行的
然后這樣是表示多行的,這種每種語言都有,文檔注釋是JAVA特有的
第三章,PL/SQL的流程控制語句,第一個叫條件語句,我們說條件語句有兩種格式的,一種叫if then,一個叫case when then when then,先看這個,if就跟講JAVA里面一樣,JAVA里面if也說了三種結構,最簡單的是一種情況,if一個東西,他返回的也是一個布爾類型的,如果滿足真的話,就執行后面的then,分號結束,endif,因為你講PL/SQL他沒有大括號的概念,JAVA里面有大括號的概念,我一包就知道哪里是語句塊,大括號結束,大括號結束就相當于endif,他這里沒有大括號呢,只有通過單詞,叫關鍵字,關鍵字來標識,你這個語句塊結束了
兩個的話加一個else,多個的話就沒有e了,els,沒有e,然后if,這是一個詞,中間也不能加空格,這個是跟JAVA不一樣的
那我們寫一個例子,寫這個吧,查詢150號員工的工資,如果工資大于1萬,打印這個,若這個之間就打印這個,否則打印這個,declare,他的工資大于這么多,可以把工資放在這個變量里,看看這個變量是不是大于1萬,是這個意思吧,所以v_sal,employees表的salary的類型,一樣的,這樣寫,然后,begin,我就select,salary,into v_sal,from employees表,where employee_id等于150,把這個人的工資放到這兒,if,沒有寫小括號,直接寫if,如果你這個v_sal它是大于等于1萬的,then dbms_output.put_line打印這個叫salary>=10000,分號結束,這里寫了三種情況,elsif,同樣滿足我們JAVA里面講的,把更嚴格的放上邊,只需要寫上一個5000就行了,就不用and salary小于1萬了,then,再else,else就直接打印了,else這樣,最后記得寫一個endif,表明這個條件判斷語句結束了,緊接著我這個程序就結束了declarev_sal employees.salary%type;beginselect salary into v_sal from employees where employee_id = 50;if v_sal >= 10000 then dbms_output.put_line('salary>=10000');elsif v_sal > 5000 then dbms_output.put_line('5000<=salary<=10000');else dbms_output.put_line('salary<5000');endif;end;
這個人的工資大于等于1萬的,這個程序就寫完了,還有一種思路就是,什么思路,我用一個變量,來記錄你這個人妖輸出的語句,這個寫法沒問題,寫出來了,然后我再記錄一下你這個類型,v_temp,這個變量是varchar類型的,10個吧,當你工資大于等于1萬的時候,我給這個變量賦個值,冒號等于,當這個的時候,else,這個能看懂,然后結束,結束完了以后,你可以在這兒,dbms_output.put_line,v_temp,跟著你可以把他的工資給他打印一下,v_sal雙豎線,然后這樣declarev_sal employees.salary%type;v_temp varchar2(30);beginselect salary into v_sal from employees where employee_id = 150;if v_sal >= 10000 then v_temp := 'salary >= 10000';elsif v_sal >= 5000 then v_temp := '5000<=salary<10000';else v_temp := 'salary < 5000';dbms_output.put_line(v_sal || ',' || v_temp);end;
然后大于等于1萬,這種想法要注意,我們在JAVA當中也涉及到過,我可以把你要輸出的這個東西,那我就賦給一個變量,對這個變量進行一個操作,就這樣,我們體會了if else,方法二,case when then,這個例子你可以看看,這是另一種條件表達式,叫case一個東西,當這樣的時候執行這個,when then then,最后加一個else,end,然后結束
我們把剛才這個練習,給他改成case when then,我們JAVA里面講一個條件判斷的時候,一個叫if else if,還有一個叫switch case,這兩個哪個好啊,顯然if else更方便一些,沒有共鳴啊,是吧,switch case的時候,一個他就那么幾種數據類型的可以用,再一個switch一個變量,case的是你離散時的值,然后相比,如果你要比較這個數的范圍,如果很大,或者是連續的,比較這個溫度,溫度在0到15度之間,說這個溫度,那你用switch就費勁了,你這個中間的溫度那是連續的,你不可能把每一個溫度都給他寫出來,這個時候你只能用if else,有些時候一些值,如果就那么幾個,你用if else不如用switch效率高,這兒呢是同理的,這個if,else if,if then, elsif then,這個也是更具有通用性的,然后用casewhen then,那就相當于JAVA中的switch case一樣,那我們用它來寫操作一下來看看,操作的話這塊不要了,把這個工資放到這里面,下一步就是case吧,我case一下你這個工資,v_sal,當你這個工資大于等于1萬的時候,then,then這個吧,加個else,記得要加一個end,表示結束,知道為什么報錯,我們講switch的時候,switch case,case里面,不能夠放范圍的,是不是只能放變量,你不能case salary,when,salary大于1萬,case只能填變量,這個也是一樣,這里只能寫值,那你這個怎么處理,那我只能在這里處理了,這個肯定是已經獲取到他的工資了,工資除以5000,加上一個trunc,這樣不就可以得到離散的值了嗎,如果你工資小于5000的,這一串值是0,如果要5000到1萬之間的,是1,大于1萬的就是2,所以說你這個改的話,把2大的寫到else里邊,所以我們這里從小的寫,先0,再1,不是0不是1,這樣你看行不行declarev_sal employees.salary%type;v_temp varchar2(30);beginselect salary into v_sal from employees where employee_id = 150;v_temp := case trunc(v_sal/5000) when 0 then 'salary < 5000'when 1 then '5000<=salary<10000'else 'salary>10000'end;dbms_output.put_line(v_sal||','||v_temp);end;
我是讓你看到調的過程當中,哪種格式是對的,我們剛才是不是這樣寫的,不能夠寫范圍,我們沒有寫范圍,這樣處理的時候,當然這個是寫錯了,不能寫分號,然后你變量賦值不能寫這兒,每次不能寫這兒,你得給他拿出來,拿到這兒來,你就寫成這樣,變量賦值,然后當是這樣的時候,給他賦一個他,要么他要么他,打印,打印試試,因為這個人工資是大于1萬的,dbms_output.put_line,我這里簡寫,打個1,他這個也不行,他這個也特別嘔心declarev_sal employees.salary%type;v_temp varchar2(30);beginselect salary into v_sal from employees where employee_id = 150;case trunc(v_sal/5000) when 0 then dbms_output.put_line('1')when 1 then dbms_output.put_line('1')else dbms_output.put_line('1')end;dbms_output.put_line(v_sal || ',' || v_temp);end;
他這個特別的嘔心,而且還有哪里嘔心,他這里還特別有局限性,我們剛才用的trunc,如果我把這個等號刪了,實際上你這里是錯的,我把等號寫在這兒,意味著如果要等于5000的話,現在我不放在那個語句,現在我放到這種情況,那你這個時候一trunc的話,壞事了,因為如果這個工資是5000,你得的結果是1,如果是1的話輸出這個,使用case when then的時候,這個限制條件很多,一個呢他只能寫具體的值,他不能寫取值范圍,這點不如if else好,再一點,既然你這寫具體的值,既然你寫具體的值的話你就要考慮到,你這個值的范圍,因為人家這兒的話,正常的時候是比5000多,含5000的時候,都是1,當然小于1萬了,如果5000就給你放到另一個范圍里面,這樣就寫不了了,就只能夠用if else了,這就是使用它的局限性,但是他至少也算是一種表達方式吧,你就把的if else順序當成JAVA里的if else,case when then相當于JAVA里的switch case,我們再練一下他8. 使用 CASE ... WHEN ... THEN ... ELSE ... END;要求: 查詢出 122 號員工的 JOB_ID, 若其值為 'IT_PROG', 則打印 'GRADE: A'; 'AC_MGT', 打印 'GRADE B', 'AC_ACCOUNT', 打印 'GRADE C'; 否則打印 'GRADE D'declare--聲明變量v_grade char(1);v_job_id employees.job_id%type;
beginselect job_id into v_job_idfrom employeeswhere employee_id = 122;dbms_output.put_line('job_id: ' || v_job_id);--根據 v_job_id 的取值, 利用 case 字句為 v_grade 賦值v_grade := case v_job_id when 'IT_PROG' then 'A'when 'AC_MGT' then 'B'when 'AC_ACCOUNT' then 'C'else 'D'end;dbms_output.put_line('GRADE: ' || v_grade);
end; 查詢出122號員工的JOB_ID,如果他的值是這個,打印這個,這個打印這個,這個打印這個,declare,declare里面寫啥,聲明job_id,v_job_id,varchar型的,先這樣,然后打印一個東西,這個打印的東西給他當成一個變量,varchar2,這個差不多,begin,selectjob_id,into job_id,from employees where,employee_id等于122,把這個人的job_id給拿出來,v_temp等于,回來case,casev_job_id,when 'IT_PROG',then,我簡寫了,打印A,when 'AC_MGT',then,這個沒有分號,還是挺別扭的,else,然后就沒有了,打印v_job_id,然后執行,加個end,這個部門的,它是Ddeclarev_job_id varchar2(10);v_temp varchar2(10);beginselect job_id into v_job_id from employees where employee_id = 122;v_temp := case v_job_id when 'IT_PROG' then 'A'when 'AC_MGT' then 'B'when 'AC_ACCOUNT' then 'C'else 'D'end;end;
下面就循環了,循環三種結構,loop,表示循環體,分號結束
exit when,循環條件,然后end loop,表示結束,這兩個之間是可以加東西
有一個輸出1到100,用三種方式寫,先說剛才的第一種9. 使用循環語句打印 1 - 100.(三種方式)1). LOOP ... EXIT WHEN ... END LOOP
declare--初始化條件v_i number(3) := 1;
beginloop--循環體dbms_output.put_line(v_i);--循環條件exit when v_i = 100;--迭代條件v_i := v_i + 1;end loop;
end;2). WHILE ... LOOP ... END LOOP
declare--初始化條件v_i number(3) := 1;
begin--循環條件while v_i <= 100 loop--循環體dbms_output.put_line(v_i);--迭代條件v_i := v_i + 1;end loop;
end; 3).
beginfor i in 1 .. 100 loopdbms_output.put_line(i);end loop;
end;先不能loop,先declare,begin,end,我們還沒有講異常呢,我們講循環的時候,我們講JAVA的時候包括三部分,第一部分,叫初始化條件,第二部分,叫循環體也行,三循環條件,四迭代條件,這樣三部分,然后放到這兒,任何循環都是這樣一個結構,都少不了,declare的算初始化條件,聲明一個什么樣的變量,然后然他執行loop,然后就是循環體,case when算循環條件,跟endloop算迭代條件,先寫第一部分,聲明一個變量,v_i這是一個變量,這是number類型的,寫大一點也無所謂,冒號等于從1開始,這就是初始化條件,begin,loop什么執行,這個是2,dbms輸出,輸出一下v_i,輸出他以后,exit when,結束就是v_i,大于等于100的時候,exit when當結束的時候,如果沒有到這個的時候,v_i = v_i +1,然后,然后end loop,這兒是3,這兒是第四步,冒號等于declarev_i number(5) := 1;beginloopdbms_output.put_line(v_i);exit when v_i >= 100;v_i := v_i + 1;end loop;end;
從1開始,然后到100結束,先打印一下,把這個循環體放到這,這個就到99了declarev_i number(5) := 1;beginloopdbms_output.put_line(v_i);v_i := v_i + 1;exit when v_i >= 100;end loop;end;
因為你打印99,等于99加1了,把等于去了,這就到100了declarev_i number(5) := 1;beginloopdbms_output.put_line(v_i);v_i := v_i + 1;exit when v_i > 100;end loop;end;
?
你這個你可以省了,讓他在循環體里面執行也行,這是說的第一種方式,loop,exit when,end loop,這都是他的關鍵字,第二種,就是while,while loop,然后執行,end loop 用這種格式操作一下他,初始化條件,都這樣寫,where v_i小于等于100,loop執行,dbms_output.put_line,執行完了以后,v_i要讓他執行一個值,然后還有別的操作不,還有end loop,還有什么,這個跟我們講的while有點類似declarev_i number(5) := 1;beginwhile v_i<=100 loopdbms_output.put_line(v_i);v_i := v_i + 1;end loop;end; 這里是循環條件,這里是循環體,然后你得加上一個迭代部分,這個不加的話就成了死循環了,這是第二種方式,再往后,for,for循環,for循環的時候,JAVA里面的for循環重新定義了一個變量,int i = 0,這個也是一樣,循環計數器就是你定義的一個變量,只不過他的類型需要你指定了 你看看這個格式,叫in,這個你先忽略,下限,兩個點,上限,loop,要執行的語句,再end loop,所以就來,這里不要了,你可以不用,begin,for循環,定義一個變量,比如c,in,從1開始,點點到一百,loop,開始執行,打印c,打印c完了以后,我要到后面end loopbeginfor c in 1..100 loopdbms_output.put_line(c);end loop;end;?
有啥疑問嗎,這不就相當于JAVA里面的for,int i,i等于幾啊,i等于1,第二部分,分號后邊i小于等于100,這不就是到100嗎,加加,我自動的給你加加,這是循環體,就這樣,這個后邊可以加上一個reverse,從100到1,就是可以反著來beginfor c in 1..100 loopdbms_output.put_line(c);end loop;end;?
?
這個完了以后,我們寫一個稍微麻煩一點的,我們在JAVA中講過,準確來說從2開始,到100之間的質數,不只是結構,還有小算法,加不加break,效率是不一樣的,循環結構,條件判斷結構,順便考一下你的算法,題目也不大,所以是一個挺好的題目,從JAVA當中去想,你當時聲明過哪些變量,然后begin,end,我們外層for循環定義一個i,是想從2到100,在內層又定義一個for循環,然后定義一個flag,修改flag為true,這里我們也得定義一個變量,v_i,number類型的,冒號等于,從2開始,number類型的,冒號等于,也是從2開始,我再定義一個flag,早知道我們不定義布爾類型了,我還定義一個number類型的,1位就夠,這個用for循環實現和while循環實現是一樣的,我們先用while循環實現吧,while,while后邊寫的是一個條件,v_i他的小于等于100,然后loop開始執行這個循環,這個循環里邊,如果v_j<v_i,小于等于sqrt(v_i),是這個意思吧,他這個格式是這樣,從外層實現2到100,內層他每次實現到這就完了,有等號,再接著就是判斷了,如果v_i,mod一下v_j,如果等于0的時候,等號,我就讓你then,把v_flag賦值為0,賦值為0,如果你要是沒有的話,那就沒有唄,那就end if結束了,這個完了以后,內層的while循環里,你是不是執行一次查詢不滿足,不滿足就end,然后讓v_j加個1,v_j等于v_j加上一個1,再去滿足這個條件滿足,結束,這是內層循環一次,只判斷一個值是否滿足,v_i := v_i + 1;他加了1,可能在里面被改了,我們還得給他改回來,還得給他改成一個1,當里邊循環執行完了之后,沒有被改過,那個數是不是就是質數,如果v_flag他等于1,then,dbms_output.put_line,打印一下v_i,然后就是這個語句,然后end,忘了end if,這個有end if,end loop,這個呢,在這兒end if,這兒end loop,全輸出來了,那我們來看,哪出錯了,那就相當于這里沒有執行過,如果他mod他等于0,mod(v_i,v_j),這樣,mod他是一個布爾類型的,等于0,還是都有,你看在哪出錯了,他小于等于100,開始,mod他等于0,then v_flag等于0,然后end這個,當我循環執行完之后,如果v_flag等于1,第一次完了再加個1,開始一個循環,然后判斷,j從2開始,然后,v_j等于2,這個非常關鍵的declarev_i number(3) := 2;v_j number(3) := 2;v_flag number(1) := 1;beginwhile v_i <= 100 loopwhile v_j <= sqrt(v_i) loopif mod(v_i,v_j)=0 then v_flag := 0;end if;v_j := v_j + 1;end loop;if v_flag = 1 then dbms_output.put_line(v_i);end if;v_j := 2;v_i := v_i + 1;v_flag := 1;end loop;end; 這個就是那之前的一行代碼,你要是不初始化的話,每次就進不去了,每次進不去他就認為你是質數了,這個其實和我們JAVA里面,除了各式之外,就是你這個外層循環,當這個被除數,內層當除數,范圍取個根號就完了,一旦發現做除等于0的時候,你給他改個值,然后判斷這個值是否被改過,說明他就不是質數,沒改過,就是,記得每次給他改成1,這個重新給他置成一個2,然后這個加加就完了,這個是我們使用while循環來實現的,實現了質數的一個輸出,現在我們給他改成使用for,使用for循環,使用for循環的話,這兩你不用了,for v_i,in,從2開始到100,loop,for v_j,in 從2開始,sqrt(v_i),然后loop,然后還是這個判斷,如果mod(v_i,v_j),等于0,then,then v_flag置成0,end if,if完了就不用再加加了,這個完了以后,判斷一下,判斷一下v_flag,如果他是等于1的話,then,打印一下v_i,end if,注意這個,那兩行我們就不用了,v_flag等于1,end一下declarev_flag number(1) := 1;beginfor v_i in 2..100 loopfor v_j in 2 .. sqrt(v_i) loopif mod(v_i,v_j)=0 then v_flag := 0;end if;end if;if v_flag = 1 then dbms_output.put_line(v_i);end if;v_flag := 1;end loop;end; 這個我們使用for循環,顯然比剛才的while要簡潔,而for循環會自動的給你迭代,就是這兩個好處,我們講JAVA的時候,說過一個觀點,有些算法是可以改進的,在哪,比如8這個數,8這個數已經明顯等于0了,但是他沒有終止,他又繼續的比了一下4,實際上到2的時候,已經該結束了,我們開始用了一個叫continue標簽的形式,直接跳到外層,叫goto,無條件的跳到指定的標號去 跳轉我在哪跳,如果一旦你發現有一個值,我就讓你goto一個地,goto哪個地,goto到一個帶標簽的一個位置,假設這個標簽我就叫label,那你這個label是什么啊,實際上就是跳到這,一旦你這邊出現等于0的時候執行過了,進入這個語句里邊,我就來判斷一下,或者每執行一次我就給判斷一下,如果不是1了,就已經被改了,直接就跑到這里來了declarev_flag number(1) := 1;beginfor v_i in 2..100 loopfor v_j in 2 .. sqrt(v_i) loopif mod(v_i,v_j)=0 then v_flag := 0;goto label;end if;end loop;<<label>>if v_flag = 1 then dbms_output.put_line(v_i);end if;v_flag := 1;end loop;end; 10. 綜合使用 if, while 語句, 打印 1 - 100 之間的所有素數 (素數: 有且僅用兩個正約數的整數, 2, 3, 5, 7, 11, 13, ...). declarev_flag number(1):=1;v_i number(3):=2;v_j number(2):=2; beginwhile (v_i<=100) loopwhile v_j <= sqrt(v_i) loopif (mod(v_i,v_j)=0) then v_flag:= 0;end if;v_j :=v_j +1;end loop;if(v_flag=1) then dbms_output.put_line(v_i);end if;v_flag :=1;v_j := 2;v_i :=v_i +1;end loop;end;(法二)使用for循環實現1-100之間的素數的輸出 declare--標記值, 若為 1 則是素數, 否則不是v_flag number(1) := 0; beginfor i in 2 .. 100 loopv_flag := 1; for j in 2 .. sqrt(i) loopif i mod j = 0 thenv_flag := 0; end if; end loop;if v_flag = 1 thendbms_output.put_line(i);end if;end loop; end;11. 使用 goto declare--標記值, 若為 1 則是素數, 否則不是v_flag number(1) := 0; beginfor i in 2 .. 100 loopv_flag := 1; for j in 2 .. sqrt(i) loopif i mod j = 0 thenv_flag := 0;goto label; end if; end loop;<<label>>if v_flag = 1 thendbms_output.put_line(i);end if;end loop; end; 這個有分號,這個不用加尖括號,比剛剛那個效率高,就相當于我們JAVA里面講的continue,這個題就是這樣寫的,這是用兩種方式,相當于三種方式,while循環,for循環,還有使用goto這種格式的,goto就是這個意思,后邊這還有一個練習,就是這個11+.打印1——100的自然數,當打印到50時,跳出循環,輸出“打印結束” (方法一) beginfor i in 1..100 loopdbms_output.put_line(i);if(i = 50) then goto label;end if;end loop;<<label>>dbms_output.put_line('打印結束');end; (方法二) beginfor i in 1..100 loopdbms_output.put_line(i);if(i mod 50 = 0) then dbms_output.put_line('打印結束');exit;end if;end loop; end; 打印1到100的自然數,當打印到50的時候,跳出循環,輸出打印結束,看一下這個題,打印1到100的自然數,我不declare,直接就begin,直接用for,然后i in,1..100,loop,打印一個i,當打到50的時候,我就放到這,如果i當打到50的時候,i等于50的時候,then,直接dbms他,讓他goto一個label,end一個if,如果不進if語句的話就執行它,打印結束,end loop,end,每個都打了beginfor i in 1..100 loopif i = 50 then goto lable;end if;dbms_output.put_line(i);end loop;<<label>>dbms_output.put_line('打印結束');end; 從1打到99,使用goto標簽的形式,或者呢有沒有別的方式,這個我們就說完了,如果等于50,讓他exit,這個不要了,這個沒法打印結束了,那就加上一個dbms_output.put_line('打印結束'),beginfor i in 1..100 loopif i = 50 then dbms_output.put_line('打印結束');exit;end if;dbms_output.put_line(i);end loop;end;?
?
?
?
?
?
?
?
?
超強干貨來襲 云風專訪:近40年碼齡,通宵達旦的技術人生總結
以上是生活随笔為你收集整理的plsql(轻量版)_流程控制的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: plsql(轻量版)_记录类型2
- 下一篇: plsql(轻量版)_游标的使用1