SQL游標

          隱含游標:專門處理SELECT INTO、INSERT、UPDATE以及DELETE語句。

          顯示游標:用于處理多行的SELECT語句。

          當在PL/SQL塊中執行INSERT、UPDATE及DELETE語句時,為了取得DML語句作用的結果,需要使用SQL游標屬性。

          第一,游標的4種屬性

          1. SQL%ISOPEN

          該屬性永遠都是false,沒有實際意義。

          2. SQL%FOUND

          語句是否操作成功。當SQL語句有作用行時為TRUE.

          3. SQL%NOTFOUND

          LOOP

          FETCH  emp_cursor  INTO   v_name, v_deptno;

          EXIT  WHEN  emp_cursor%NOTFOUND;

          ...

          END LOOP;

           

          4. SQL%ROWCOUNT

          返回SQL語句所作用的總計行數。

          該屬性用于返回已提取的實際行數。

           

          第二,顯示游標專用于處理SELECT語句返回的多行數據。

          • 定義游標:

          CURSOR  cursor_name  IS  select_statement;

          • 打開游標:

          open  cursor_name;

          • 提到數據:

          FETCH  cursor_name  INTO  var1[, var2, ...];

          • 關閉游標:

          CLOSE  cursor_name;

          例子:

          DECLARE
             CURSOR category_cursor
             IS
                SELECT *
                  FROM tb_out_service t
                 WHERE t.servicename LIKE '長沙%';

             TYPE category_table_type IS TABLE OF tb_out_service%ROWTYPE
                INDEX BY BINARY_INTEGER;

             category_table   category_table_type;
             i                INT;
          BEGIN
             OPEN category_cursor;

             LOOP
                i := category_cursor%ROWCOUNT + 1;

                FETCH category_cursor
                 INTO category_table (i);

                EXIT WHEN category_cursor%NOTFOUND;
                DBMS_OUTPUT.put_line (   RPAD (category_table (i).serviceid, 30)
                                      || '  '
                                      || category_table (i).servicename
                                     );
             END LOOP;

             CLOSE category_cursor;
          END;

           

          第三,游標FOR循環

          語法:

          FOR  record_name  IN  cursor_name  LOOP

          statement;

          ...

          END  LOOP;

          注意:當使用游標FOR循環時,既可以在定義部分定義游標,也可以直接在FOR循環中使用SELECT語句。

           

          第四,參數游標

          CURSOR cursor_name(parameter_name datatype) is select_statement;

          OPEN cursor_name(parameter_value)

          注意:

          定義參數只能指定數據類型,不能指定長度。

          另外,應該在游標的select語句的where子句中引用游標參數,否則失去了定義參數游標的意義。

          ---------------------------------------------------------------------------------------------------------------------

          DECLARE
             CURSOR category_cursor (NAME VARCHAR2)
             IS
                SELECT *
                  FROM tb_out_service t
                 WHERE t.servicename LIKE NAME || '%';
          BEGIN
             FOR category_record IN category_cursor ('吉首')
             LOOP
                DBMS_OUTPUT.put_line (   RPAD (category_record.serviceid, 30)
                                      || '  '
                                      || category_record.servicename
                                     );
             END LOOP;
          END;

           

          第五,更新或刪除游標行

          語法

          CURSOR cursor_name IS select_statement

          FOR UPDATE [OF column_reference]  [NOWAIT];

          UPDATE table_name SET column=..  WHERE CURRENT OF cursor_name;

          DELETE FROM table_name WHERE CURRENT OF cursor_name;

           

          注意

          1. OF子句的格式:column_reference為table_name.column_name

          2. WHERE CURRENT OF cursor_name, 更新或者刪除游標所在行的數據。

          3. 在使用游標更新或刪除數據時,定義游標必須帶有FOR  UPDATE子句,并且在更新或者刪除游標時必須帶有WHERE CURRENT OF 子句。

          當查詢語句涉及到多張表時,如果不帶有OF子句,會在多張表上同時加鎖,如果只在特定的表上加鎖,需要帶有OF子句。

           

          DECLARE
             CURSOR category_cursor (NAME VARCHAR2)
             IS
                SELECT        *
                         FROM tb_out_service t
                        WHERE t.servicename LIKE NAME || '%'
                FOR UPDATE OF t.querystr;

             v_name   CONSTANT VARCHAR2 (20) := '長沙';
          BEGIN
             FOR category_record IN category_cursor (v_name)
             LOOP
                IF INSTR (category_record.servicename, v_name || '——') <> 1
                THEN
                   DBMS_OUTPUT.put_line (   'delete: '
                                         || RPAD (category_record.serviceid, 30)
                                         || '  '
                                         || category_record.servicename
                                        );

                   DELETE FROM tb_out_service
                         WHERE CURRENT OF category_cursor;
                ELSE
                   DBMS_OUTPUT.put_line (   'upate: '
                                         || RPAD (category_record.serviceid, 30)
                                         || '  '
                                         || category_record.servicename
                                        );

                   UPDATE tb_out_service t
                      SET t.querystr = v_name || '——' || t.servicename
                    WHERE CURRENT OF category_cursor;
                END IF;
             END LOOP;
          END;

           

          第六, 游標變量

          游標變量是基于REF CURSOR類型所定義的變量,它實際上是指向內存地址的指針。顯式游標只能定義靜態游標,而游標變量可以在打開時指定其所對應的SELECT語句,從而實現動態游標。

          • 定義游標:

          TYPE  ref_type_name  IS  REF  CURSOR  [RETURN  return_type];

          cursor_variable  ref_type_name;

          • 打開游標:

          OPEN  cursor_name  FOR  select_statement;

          • 提到數據:

          FETCH  cursor_variable  INTO  var1[, var2, ...];

          • 關閉游標:

          CLOSE  cursor_variable;

          注意:

          不能在遠程子程序中使用游標變量。

          當指定子查詢時,不能帶有FOR UPDATE子句。

          當指定RETURN子句時,返回類型必須使用PL/SQL記錄類型。

          例子:

          DECLARE
             TYPE category_cursor_type IS REF CURSOR
                RETURN tb_out_service%ROWTYPE;

             category_cursor   category_cursor_type;
             category_record   tb_out_service%ROWTYPE;
             v_name   CONSTANT VARCHAR2 (40)            := '長沙';
          BEGIN
             OPEN category_cursor FOR
                SELECT *
                  FROM tb_out_service t
                 WHERE t.servicename LIKE v_name || '%';

             LOOP
                FETCH category_cursor
                 INTO category_record;

                EXIT WHEN category_cursor%NOTFOUND;
                DBMS_OUTPUT.put_line (   RPAD (category_record.serviceid, 30)
                                      || '  '
                                      || category_record.servicename
                                     );
             END LOOP;
          END;

          posted on 2009-03-17 11:07 JavaBegger 閱讀(631) 評論(0)  編輯  收藏


          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          <2009年3月>
          22232425262728
          1234567
          891011121314
          15161718192021
          22232425262728
          2930311234

          導航

          統計

          常用鏈接

          留言簿(2)

          隨筆分類

          隨筆檔案

          文章分類

          文章檔案

          搜索

          最新評論

          閱讀排行榜

          評論排行榜

          主站蜘蛛池模板: 尼勒克县| 怀柔区| 阳东县| 长沙县| 丁青县| 桃园市| 磐安县| 高碑店市| 滨州市| 开封市| 蓬莱市| 东乌珠穆沁旗| 台东市| 泸定县| 辉南县| 阳朔县| 互助| 炎陵县| 城固县| 郎溪县| 南岸区| 青龙| 宁安市| 昭平县| 钦州市| 敦煌市| 巴里| 金湖县| 正阳县| 金溪县| 桃源县| 平乐县| 宁南县| 桂东县| 雷州市| 长垣县| 太湖县| 迁西县| 孟村| 华蓥市| 平阴县|