oracle 2

4. PL/SQL 塊

4.1 PL/SQL 塊

SQL> declare
  2  x varchar2(10);
  3  begin
  4  x:='This is..';
  5  dbms_output.put_line('x的值爲:'||x);
  6  end;
  7  /

PL/SQL 過程已成功完成。

SQL> set serveroutput on size 10000
SQL> l
  1  declare
  2  x varchar2(10);
  3  begin
  4  x:='This is..';
  5  dbms_output.put_line('x的值爲:'||x);
  6* end;
SQL> /
x的值爲:This is..

PL/SQL 過程已成功完成。


SQL> l
  1  declare
  2  x varchar2(10):='ABCDE';
  3  y string(10):='123';
  4  begin
  5  --x:='This is..';
  6  dbms_output.put_line('x的值爲:'||x||'y的值爲:'||y);
  7  /*
  8  dbms_output.put_line('x的值爲:'||x);
  9  dbms_output.put('x的值爲:'||x);
 10  */
 11* end;
SQL> @plsql_01
x的值爲:ABCDEy的值爲:123

PL/SQL 過程已成功完成。


4.2分支語句

SQL> l
  1  declare
  2  a number;
  3  b varchar2(10);
  4  begin
  5  a:=2;
  6  if a=1 then
  7  b:='A';
  8  elsif a=2 then
  9  b:='B';
 10  else
 11  b:='C';
 12  end if;
 13  dbms_output.put_line('b的值是:'||b);
 14* end;
SQL> /
b的值是:B

PL/SQL 過程已成功完成。

SQL> l
  1  declare
  2  a number;
  3  b varchar2(10);
  4  begin
  5  a:=53;
  6  if a=1 then
  7  b:='A';
  8  elsif a=2 then
  9  b:='B';
 10  else
 11  b:='C';
 12  end if;
 13  dbms_output.put_line('b的值是:'||b);
 14* end;
SQL> /
b的值是:C

PL/SQL 過程已成功完成。

4.3循環語句

SQL> l
  1  declare
  2  x number;
  3  begin
  4  x:=0;
  5  loop
  6  x:=x+1;
  7  if x>=3 then
  8  exit;
  9  end if;
 10  dbms_output.put_line('內:x='||x);
 11  end loop;
 12  dbms_output.put_line('外:x='||x);
 13* end;
SQL> /
內:x=1
內:x=2
外:x=3

PL/SQL 過程已成功完成。

SQL> l
  1  declare
  2  x number;
  3  begin
  4  x:=0;
  5  loop
  6  x:=x+1;
  7  exit when x>=3;
  8  dbms_output.put_line('內:x='||x);
  9  end loop;
 10  dbms_output.put_line('外:x='||x);
 11* end;
SQL> /
內:x=1
內:x=2
外:x=3

PL/SQL 過程已成功完成。

SQL> l
  1  declare
  2  x number;
  3  begin
  4  x:=0;
  5  while x<=3 loop
  6  x:=x+1;
  7  dbms_output.put_line('內:x='||x);
  8  end loop;
  9  dbms_output.put_line('外:x='||x);
 10* end;
SQL> /
內:x=1
內:x=2
內:x=3
內:x=4
外:x=4

PL/SQL 過程已成功完成。


SQL> l
  1  begin
  2  for i in 1..5 loop
  3  dbms_output.put_line('i='||i);
  4  end loop;
  5  dbms_output.put_line('end of for loop');
  6* end;
SQL> /
i=1
i=2
i=3
i=4
i=5
end of for loop

PL/SQL 過程已成功完成。


SQL> l
  1  begin
  2  for i in reverse 1..5 loop
  3  dbms_output.put_line('i='||i);
  4  end loop;
  5  dbms_output.put_line('end of for loop');
  6* end;
SQL> /
i=5
i=4
i=3
i=2
i=1
end of for loop

PL/SQL 過程已成功完成。


SQL> l
  1  declare
  2  x number;
  3  begin
  4  x:=0;
  5  <<repeat_loop>>
  6  x:=x+1;
  7  dbms_output.put_line('x='||x);
  8  if x<3 then
  9  goto repeat_loop;
 10  end if;
 11* end;
SQL> /
x=1
x=2
x=3

PL/SQL 過程已成功完成。


4.4異常處理

SQL> l
  1  declare
  2  b varchar2(10);
  3  begin
  4  select ename into b from emp where empno = '1';
  5  dbms_output.put_line(b);
  6* end;
SQL> /
declare
*
第 1 行出現錯誤:
ORA-01403: 未找到數據
ORA-06512: 在 line 4


SQL> l
  1  declare
  2  b varchar2(10);
  3  begin
  4  select ename into b from emp where empno = '1';
  5  dbms_output.put_line(b);
  6* end;

SQL> l
  1  declare
  2  b varchar2(10);
  3  begin
  4  select ename into b from emp where empno = '1';
  5  dbms_output.put_line(b);
  6  exception
  7  when no_data_found then
  8  dbms_output.put_line('沒有找到數據!');
  9* end;
SQL> /
沒有找到數據!

PL/SQL 過程已成功完成。


SQL> l
  1  declare
  2  b varchar2(10);
  3  e exception;
  4  begin
  5  select ename into b from emp where empno = '7369';
  6  if b<>'張三' then
  7  raise e;
  8  end if;
  9  dbms_output.put_line(b);
 10  exception
 11  when e then
 12  dbms_output.put_line('錯誤,不是 張三 !');
 13* end;
SQL> /
錯誤,不是 張三 !

PL/SQL 過程已成功完成。

4.5記錄 - 複合變量

SQL> l
  1  declare
  2  type myrecord is record(
  3  id number,
  4  name varchar2(10));
  5  real_record myrecord;
  6  begin
  7  select empno,ename into real_record from emp where empno='7566';
  8  dbms_output.put_line(real_record.id||','||real_record.name);
  9* end;
SQL> /
7566,JONES

PL/SQL 過程已成功完成。


SQL> l
  1  declare
  2  type myrecord is record(
  3  id emp.empno%type,
  4  name varchar2(10));
  5  real_record myrecord;
  6  begin
  7  select empno,ename into real_record from emp where empno='7566';
  8  dbms_output.put_line(real_record.id||','||real_record.name);
  9* end;
SQL> /
7566,JONES

PL/SQL 過程已成功完成。

SQL> l
  1  declare
  2  myrec emp%rowtype;
  3  begin
  4  select * into myrec from emp where empno='7566';
  5  dbms_output.put_line(myrec.empno||','||myrec.ename||','||myrec.job);
  6* end;
SQL> /
7566,JONES,MANAGER

PL/SQL 過程已成功完成。

5.PL/SQL高級應用

5.1 遊標

使用遊標可以充分操縱表的每一行

SQL> l
  1  declare
  2  cursor mycur is
  3  select * from books;
  4  myrecord books%rowtype;
  5  begin
  6  open mycur;
  7  fetch mycur into myrecord;
  8  while mycur%found loop
  9  dbms_output.put_line(myrecord.books_id||','||myrecord.books_name);
 10  fetch mycur into myrecord;
 11  end loop;
 12  close mycur;
 13* end;
SQL> /
1,中國文學
2,外國文學
3,英語閱讀
4,建築藝術
5,計算機入門
6,數據結構
7,語文

PL/SQL 過程已成功完成。


上面是顯式遊標

SQL> l
  1  declare
  2  cursor cur_para(id number) is
  3  select books_name from books where books_id=id;
  4  t_name books.books_name%type;
  5  begin
  6  open cur_para(1);
  7  loop
  8  fetch cur_para into t_name;
  9  exit when cur_para%notfound;
 10  dbms_output.put_line(t_name);
 11  end loop;
 12  close cur_para;
 13* end;
SQL> /
中國文學

PL/SQL 過程已成功完成。

SQL> l
  1  declare
  2  cursor cur_para(id number) is
  3  select books_name from books where books_id=id;
  4  begin
  5  dbms_output.put_line('*******結果集爲********');
  6  for cur in cur_para(1) loop
  7  dbms_output.put_line(cur.books_name);
  8  end loop;
  9* end;
SQL> /
*******結果集爲********
中國文學

PL/SQL 過程已成功完成。

SQL> l
  1  declare
  2  t_name books.books_name%type;
  3  cursor cur(id number) is
  4  select books_name from books where books_id=id;
  5  begin
  6  if cur%isopen then
  7  dbms_output.put_line('遊標已經被打開!');
  8  else
  9  open cur(3);
 10  end if;
 11  fetch cur into t_name;
 12  close cur;
 13  dbms_output.put_line(t_name);
 14* end;
SQL> /
英語閱讀

PL/SQL 過程已成功完成。

 

SQL> l
  1  declare
  2  t_name varchar2(10);
  3  cursor mycur is
  4  select ename from emp;
  5  begin
  6  open mycur;
  7  loop
  8  exit when mycur%notfound or mycur%notfound is null;
  9  dbms_output.put_line('遊標mycur的rowcount是:'||mycur%rowcount);
 10  end loop;
 11  close mycur;
 12* end;
SQL> /

PL/SQL 過程已成功完成。

SQL> l
  1  declare
  2  t_name varchar2(10);
  3  cursor mycur is
  4  select ename from emp;
  5  begin
  6  open mycur;
  7  loop
  8  fetch mycur into t_name;
  9  exit when mycur%notfound or mycur%notfound is null;
 10  dbms_output.put_line('遊標mycur的rowcount是:'||mycur%rowcount);
 11  end loop;
 12  close mycur;
 13* end;
SQL> /
遊標mycur的rowcount是:1
遊標mycur的rowcount是:2
遊標mycur的rowcount是:3
遊標mycur的rowcount是:4
遊標mycur的rowcount是:5
遊標mycur的rowcount是:6
遊標mycur的rowcount是:7
遊標mycur的rowcount是:8
遊標mycur的rowcount是:9
遊標mycur的rowcount是:10
遊標mycur的rowcount是:11
遊標mycur的rowcount是:12
遊標mycur的rowcount是:13
遊標mycur的rowcount是:14

PL/SQL 過程已成功完成。


SQL> l
  1  declare
  2  cursor cur is
  3  select name from d for update;
  4  text varchar2(10);
  5  begin
  6  open cur;
  7  fetch cur into text;
  8  while cur%found loop
  9  update d set name=name||'_t' where current of cur;
 10  fetch cur into text;
 11  end loop;
 12  close cur;
 13* end;
SQL> /

PL/SQL 過程已成功完成。

SQL> commit;

提交完成。

5.2 隱式遊標
SQL> l
  1  begin
  2  for cur in(select name from d) loop
  3  dbms_output.put_line(cur.name);
  4  end loop;
  5* end;
SQL> /
A部門_t
B部門_t
C部門_t
D部門_t
E部門_t
F部門_t
G部門_t

PL/SQL 過程已成功完成。


5.3 存儲過程

聲明 執行 異常處理
輸入參數(in) 輸出參數(out)


創建一個存儲過程:
SQL> @procedure_01

警告: 創建的過程帶有編譯錯誤。

SQL> show errors
PROCEDURE MYPROC 出現錯誤:

LINE/COL ERROR
-------- -----------------------------------------------------------------
5/1      PL/SQL: SQL Statement ignored
5/45     PL/SQL: ORA-00904: "BOOK_ID": 標識符無效
SQL> l
  1  create or replace procedure myproc(id in varchar2)
  2  is
  3  name varchar2(10);
  4  begin
  5  select book_name into name from books where book_id=id;
  6  dbms_output.put_line(name);
  7* end myproc;
SQL> @procedure_01

過程已創建。

SQL> l
  1  create or replace procedure myproc(id in varchar2)
  2  is
  3  name varchar2(10);
  4  begin
  5  select books_name into name from books where books_id=id;
  6  dbms_output.put_line(name);
  7* end myproc;
SQL> /

過程已創建。

使用存儲過程:

SQL> l
  1  declare
  2  tid varchar2(10);
  3  begin
  4  tid:='0001';
  5  myproc(tid);
  6* end;
SQL> /
中國文學

PL/SQL 過程已成功完成。

SQL> l
  1  begin
  2  myproc('0001');
  3* end;
SQL> /
中國文學

PL/SQL 過程已成功完成。

SQL> execute myproc('0001');
中國文學

PL/SQL 過程已成功完成。


存儲過程存在輸入參數和輸出參數

SQL> l
  1  create or replace procedure myproc2(id varchar2,name out varchar2)
  2  is
  3  select books_name into name from books where books_id=id;
  4* end;
SQL> show errors
PROCEDURE MYPROC2 出現錯誤:

LINE/COL ERROR
-------- -----------------------------------------------------------------
3/1      PLS-00103: 出現符號 "SELECT"在需要下列之一時:
         begin function package
         pragma procedure subtype type use <an identifier>
         <a double-quoted delimited-identifier> form current cursor
         external language

SQL> @procedure_04

過程已創建。

SQL> l
  1  create or replace procedure myproc2(id varchar2,name out varchar2)
  2  is
  3  begin
  4  select books_name into name from books where books_id=id;
  5* end;

 

SQL> l
  1  declare
  2  tid varchar2(10);
  3  tname varchar2(10);
  4  begin
  5  tid:='0001';
  6  myproc2(tid,tname);
  7  dbms_output.put_line(tname);
  8* end;
SQL> /
中國文學

PL/SQL 過程已成功完成。

 

5.4 視圖

SQL> @view_01

視圖已創建。

SQL> l
  1  create or replace view myview
  2  as
  3* select * from books
SQL> insert into myview(books_id) values ('0008');

已創建 1 行。

SQL> select * from myview;

  BOOKS_ID BOOKS_NAME                          PRICE        QTY
---------- ------------------------------ ---------- ----------
PUB
--------------------------------------------------
         8


         1 中國文學                               39         12
人民大學

         2 外國文學                             12.5         22
人民大學


  BOOKS_ID BOOKS_NAME                          PRICE        QTY
---------- ------------------------------ ---------- ----------
PUB
--------------------------------------------------
         3 英語閱讀                               33         21
清華大學

         4 建築藝術                                6         33
清華大學

         5 計算機入門                           44.8         24
電子工業


  BOOKS_ID BOOKS_NAME                          PRICE        QTY
---------- ------------------------------ ---------- ----------
PUB
--------------------------------------------------
         6 數據結構                             54.7         65
電子工業

         7 語文                                   43          5
電子工業


已選擇8行。

SQL> commit;

提交完成。

 

SQL> @view_02

視圖已創建。

SQL> l
  1  create or replace view myview
  2  as
  3* select * from books where price>30
SQL> /

視圖已創建。

SQL> select * from myview
  2  ;

BOOKS_ID BOOKS_NAME                PRICE  QTY PUB
-------- -------------------- ---------- ---- ---------------
       1 中國文學                     39   12 人民大學
       3 英語閱讀                     33   21 清華大學
       5 計算機入門                 44.8   24 電子工業
       6 數據結構                   54.7   65 電子工業
       7 語文                         43    5 電子工業


SQL> @view_02

視圖已創建。

SQL> l
  1  create or replace view myview
  2  as
  3  select * from books where price>30
  4* with check option
SQL> insert into myview values ('0009','aa',20,4,'bb');
insert into myview values ('0009','aa',20,4,'bb')
            *
第 1 行出現錯誤:
ORA-01402: 視圖 WITH CHECK OPTIDN where 子句違規

 

SQL> select empno,ename,job,d.id,d.name from emp e,d where e.empno=d.id;

     EMPNO ENAME      JOB               ID NAME
---------- ---------- --------- ---------- ----------
      7782 CLARK      MANAGER         7782 組織
      7876 ADAMS      CLERK           7876 神仙部


SQL> create or replace view v_emp_d
  2  as
  3  select empno,ename,job,d.id,d.name from emp e,d where e.empno=d.id;

視圖已創建。

SQL> save view_03
已創建 file view_03.sql
SQL> l
  1  create or replace view v_emp_d
  2  as
  3* select empno,ename,job,d.id,d.name from emp e,d where e.empno=d.id
SQL> select * from v_emp_d;

     EMPNO ENAME      JOB               ID NAME
---------- ---------- --------- ---------- ----------
      7782 CLARK      MANAGER         7782 組織
      7876 ADAMS      CLERK           7876 神仙部


SQL> desc user_views
 名稱                                                  是否爲空? 類型
 ----------------------------------------------------- -------- ---------------------------------

 VIEW_NAME                                             NOT NULL VARCHAR2(30)
 TEXT_LENGTH                                                    NUMBER
 TEXT                                                           LONG
 TYPE_TEXT_LENGTH                                               NUMBER
 TYPE_TEXT                                                      VARCHAR2(4000)
 OID_TEXT_LENGTH                                                NUMBER
 OID_TEXT                                                       VARCHAR2(4000)
 VIEW_TYPE_OWNER                                                VARCHAR2(30)
 VIEW_TYPE                                                      VARCHAR2(30)
 SUPERVIEW_NAME                                                 VARCHAR2(30)

SQL> select text from user_views where view_name = 'v_read';

未選定行

5.5 同義詞

SQL> connect sys/ora as sysdba
已連接。
SQL> select user from dual;

USER
------------------------------
SYS

SQL> select * from dept;
select * from dept
              *
第 1 行出現錯誤:
ORA-00942: 表或視圖不存在


SQL> select * from scott.dept;

    DEPTNO DNAME          LOC
---------- -------------- -------------
        10 ACCOUNTING     NEW YORK
        20 RESEARCH       DALLAS
        30 SALES          CHICAGO
        40 OPERATIONS     BOSTON

公共同義詞 私有同義詞

默認創建私有同義詞

SQL> create synonym dept for scott.dept;

同義詞已創建。

SQL> select * from dept;

    DEPTNO DNAME          LOC
---------- -------------- -------------
        10 ACCOUNTING     NEW YORK
        20 RESEARCH       DALLAS
        30 SALES          CHICAGO
        40 OPERATIONS     BOSTON
SQL> connect decoration/decoration
已連接。
SQL> select * from dept;
select * from dept
              *
第 1 行出現錯誤:
ORA-00942: 表或視圖不存在

刪除同義詞:
SQL> connect sys/ora as sysdba
已連接。
SQL> drop synonym dept;

同義詞已刪除。


創建公共同義詞:
SQL> create public synonym dept for scott.dept;

同義詞已創建。

SQL> select * from dept;

    DEPTNO DNAME          LOC
---------- -------------- -------------
        10 ACCOUNTING     NEW YORK
        20 RESEARCH       DALLAS
        30 SALES          CHICAGO
        40 OPERATIONS     BOSTON

SQL> connect decoration/decoration;
已連接。

SQL> select * from dept;

    DEPTNO DNAME          LOC
---------- -------------- -------------
        10 ACCOUNTING     NEW YORK
        20 RESEARCH       DALLAS
        30 SALES          CHICAGO
        40 OPERATIONS     BOSTON
注意:前提是decoration用戶要有select any table 的權限。

SQL> connect system/ora
已連接。
SQL> desc dba_synonyms;
 名稱                                      是否爲空? 類型
 ----------------------------------------- -------- ----------------------------
 OWNER                                     NOT NULL VARCHAR2(30)
 SYNONYM_NAME                              NOT NULL VARCHAR2(30)
 TABLE_OWNER                                        VARCHAR2(30)
 TABLE_NAME                                NOT NULL VARCHAR2(30)
 DB_LINK                                            VARCHAR2(128)

SQL> show user;
USER 爲 "DECORATION"
SQL> create synonym dep for scott.dept;

同義詞已創建。

SQL> select * from dep;

    DEPTNO DNAME          LOC
---------- -------------- -------------
        10 ACCOUNTING     NEW YORK
        20 RESEARCH       DALLAS
        30 SALES          CHICAGO
        40 OPERATIONS     BOSTON
SQL> desc user_synonyms;
 名稱                                      是否爲空? 類型
 ----------------------------------------- -------- ----------------------------
 SYNONYM_NAME                              NOT NULL VARCHAR2(30)
 TABLE_OWNER                                        VARCHAR2(30)
 TABLE_NAME                                NOT NULL VARCHAR2(30)
 DB_LINK                                            VARCHAR2(128)

SQL> select synonym_name from user_synonyms;

SYNONYM_NAME
------------------------------
DEP

SQL> select * from user_synonyms;

SYNONYM_NA TABLE_OWNER     TABLE_NAME      DB_LINK
---------- --------------- --------------- ---------------
DEP        SCOTT           DEPT


5.6 序列

SQL> @sequence_01

序列已創建。

SQL> l
  1  create sequence myseq
  2  start with 1
  3  increment by 1
  4  order
  5* nocycle
 
SQL> select myseq.nextval from dual;

   NEXTVAL
----------
         1

SQL> select myseq.nextval from dual;

   NEXTVAL
----------
         2

SQL> select myseq.nextval from dual;

   NEXTVAL
----------
         3
SQL> select myseq.nextval from dual;

   NEXTVAL
----------
         4

SQL> select myseq.currval from dual;

   CURRVAL
----------
         4


SQL> show user;
USER 爲 "SCOTT"
SQL> create table auto(a number,b varchar2(10));

表已創建。


SQL>  insert into auto(a,b) values (myseq.nextval,'abc');

已創建 1 行。

SQL>  insert into auto(a,b) values (myseq.nextval,'abc');

已創建 1 行。

SQL>  insert into auto(a,b) values (myseq.nextval,'abc');

已創建 1 行。

SQL> select * from auto;

         A B
---------- ----------
        22 abc
        23 abc
        24 abc

SQL> commit;

提交完成。


SQL> connect system/ora
已連接。
SQL> desc dba_sequences;
 名稱                                      是否爲空? 類型
 ----------------------------------------- -------- ----------------------------
 SEQUENCE_OWNER                            NOT NULL VARCHAR2(30)
 SEQUENCE_NAME                             NOT NULL VARCHAR2(30)
 MIN_VALUE                                          NUMBER
 MAX_VALUE                                          NUMBER
 INCREMENT_BY                              NOT NULL NUMBER
 CYCLE_FLAG                                         VARCHAR2(1)
 ORDER_FLAG                                         VARCHAR2(1)
 CACHE_SIZE                                NOT NULL NUMBER
 LAST_NUMBER                               NOT NULL NUMBER

SQL> desc all_sequences;
 名稱                                      是否爲空? 類型
 ----------------------------------------- -------- ----------------------------
 SEQUENCE_OWNER                            NOT NULL VARCHAR2(30)
 SEQUENCE_NAME                             NOT NULL VARCHAR2(30)
 MIN_VALUE                                          NUMBER
 MAX_VALUE                                          NUMBER
 INCREMENT_BY                              NOT NULL NUMBER
 CYCLE_FLAG                                         VARCHAR2(1)
 ORDER_FLAG                                         VARCHAR2(1)
 CACHE_SIZE                                NOT NULL NUMBER
 LAST_NUMBER                               NOT NULL NUMBER

SQL> desc user_sequences;
 名稱                                      是否爲空? 類型
 ----------------------------------------- -------- ----------------------------
 SEQUENCE_NAME                             NOT NULL VARCHAR2(30)
 MIN_VALUE                                          NUMBER
 MAX_VALUE                                          NUMBER
 INCREMENT_BY                              NOT NULL NUMBER
 CYCLE_FLAG                                         VARCHAR2(1)
 ORDER_FLAG                                         VARCHAR2(1)
 CACHE_SIZE                                NOT NULL NUMBER
 LAST_NUMBER                               NOT NULL NUMBER

SQL> show user;
USER 爲 "SYSTEM"

SQL> select sequence_name,sequence_owner from dba_sequences
  2  where sequence_owner = 'SCOTT';

SEQUENCE_NAME                  SEQUENCE_OWNER
------------------------------ ------------------------------
MYSEQ                          SCOTT


SQL> connect scott/tiger
已連接。
SQL> alter sequence myseq
  2  increment by 3;

序列已更改。

SQL> select myseq.nextval from dual;

   NEXTVAL
----------
        27

SQL> select myseq.nextval from dual;

   NEXTVAL
----------
        30
       
序列可以修改增量,不能修改當前值。

發佈了51 篇原創文章 · 獲贊 0 · 訪問量 3萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章