# PL/SQL Oracle > SQL在本質上缺乏對輸出結果的程序化控制。 > 它沒有陣列的處理、迴圈的結構以及其他程式語言的功能。 > > 為符合實際需要,Oracle於是提供內建的程式語言,稱為 > 結構化查詢語言的程序化語言(Procedural Language for SQL) > 於SQL*Plus 鍵入程式 > > 若執行不成功,可鍵入show errors將顯示執行期間 > 所產生之錯誤。 > > 一樣以edit命令編輯修改程式。 > > 欲取出輸出結果,Oracle提供一內建的package稱為dbms_output, 在程式中加入dbms_output。 > put_line 指令後便可出現結果。 > > 若結果沒出現,輸入set serveroutput on 來開啟螢幕輸出功能。 #### PL/SQL 結構 ```SQL= [DECLARE] -- 將變數放在這裡 BEGIN -- 將程式放在這裡 [EXCEPTION] -- 將例外處理放在這裡 END; / (備註 : -- (用於獨立的一行),或 /* */ ) ``` #### 變數類型 ``` Varchar2 Number Date Boolean ``` #### 游標 (CURSOR) [Cursor 與 Cursor Variable 的使用](https://zer931.pixnet.net/blog/post/36298232-%5Boracle%5D-cursor-%E8%88%87-cursor-variable-%E7%9A%84%E4%BD%BF%E7%94%A8) > 類似Java的ResultSet,你可以把Cursor想成是一塊暫存的資料表,裡面存放著SQL的查詢結果,所以透過Cursor我們便可以操作結果的每一列資料,但一次只能處理一列資料。 > > 是一種特殊的記憶體結構,可持有SQL敘述句,也能夠記錄程式執行結果。 > 建立在宣告區域, Oracle會再執行前先準備這道敘述句, 讓程式更有效率地使用記憶體。 >為了暫時存放從 cursor 擷取出來的資料列,必須定義一個暫存的變數,而這個變數的型態通常為一列資料(row data)。 ``` 每個 explicit cursor 都會有以下幾個屬性作為程式控制之用: %NOTFOUND 根據從資料集合中擷取的最後一筆資料,來決定回傳 TRUE(有資料) or FALSE(沒資料)。 %FOUND 與 %NOTFOUND 相反。 %ROWCOUNT 回傳資料集合中所包含的資料筆數。當 cursor 從資料集合擷取過資料後,就可以使用此屬性。 %ISOPEN 若是 cursor 狀態為 open,則回傳 TRUE;反之則回傳 FALSE。 ``` ```SQL= declare v_prod_name varchar2(80); begin select prod_name into v_prod_name from products where rownum =1; dbms_output.putline(v_prod_name); end; ``` ``` 上例為何要在程式中加入rownum = 1? 而上例使用之select陳述式(加入into)的寫法, 我們將其稱為隱式 cursor. 有了隱式cursor, Oracle幾乎可處理任何事,但這是要付出代價的: 程 式執行的速度會變慢, 以此寫法來執行 select 陳述式並非好的寫法, 唯若執行delete、update或是insert時, 你必須使用隱式cursor. ``` - 建立顯式(explicit) cursor是更好的辦法: ```SQL= declare v_prod_name varchar2(80); cursor get_data is select prod_name from products where rownum = 1; begin open get_data; fetch get_data into v_prod_name; dbms_output.putline(v_prod_name); close get_data; end; ``` - CURSOR FOR LOOP > Cursor FOR loop 是select cursor與FOR loop結合的成果。 > 如果查詢的結果有多筆記錄時,cursor FOR loop 允許你從資料庫中選取更多的記錄。 > > 它易於撰寫,並且你不用擔心開啟或關閉cursor的問題; Oracle會在迴圈中處理這個問題。 ```SQL= Declare l_emp_count number; i number; CURSOR get_employee_data is select count(*) from employee; begin OPEN get_employee_data; FETCH get_employee_data INTO l_emp_count; FOR I in l_emp_count loop dbms_output.put_line(‘Employee’|| i); End loop; CLOSE get_employee_data; end; ``` ###### tags: `SQL`
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up