數據庫程序設計2 PL/SQL

目錄

什麼是PL/SQL

PL/SQL塊的類型

PL/SQL塊結構

PL/SQL變量

變量聲明

%TYPE屬性

其他變量

輸出

 註釋

函數

語句

查詢語句

DML語句

事物控制語句

流程控制語句

IF語句

邏輯表

CASE語句

LOOP語句

WHILE循環


什麼是PL/SQL

SQL PL:Structured Query Language Procedual Language(IBM)

T-SQL:Transact-SQL(Microsoft)

PL/SQL:Procedual Language / Structured Query Language

是對SQL的擴展,改善了性能,具有可重用性,模塊化。

PL/SQL塊的類型

  • 匿名塊:不能保存在數據庫中
  • 過程函數和包:命名的PL/SQL塊,存儲在數據庫中,能多次執行
  • 觸發器:發生觸發事件會執行

PL/SQL塊結構

1.定義部分

可選部分。與其它語言-樣,PL/SQL中使用的變量、常量、遊標和異常處理的名字都必須先定義後使用。並且必須定義在以DECLARE關鍵字開頭的定義部分。

2.可執行部分

該部分是PL/SQL塊的主體,包含該塊的可執行語句。該部分定義了塊的功能,是必須的。 由關鍵字BEGIN開始,以END結束。

3.異常處理部分

該部分包含塊的異常處理程序(錯誤處理程序)。當該塊程,序體中的某個語句出現異常(檢測到一個錯誤)時,oracle將程序控制轉到異常部分的相應的異常處理程序中進行進一步的處理。該部分由關鍵字EXCEPTION開始,END關鍵字結束。

DECLEAR-可選

變量定義 數據類型

BEGIN-必須

EXCEPTION-異常處理

END-可選

PL/SQL變量

  • 標量型
  • 複合型
  • 引用型
  • LOB型(大型對象)

標量數據類型

  • CHAR
  • VARCHAR
  • DATE
  • NUMBER
  • BINARY_INTEGER
  • PLS_INTEGER
  • BOOLEAN
  • BINARY_FLOAT
  • BINAYR_DOUBLE

變量聲明

語法

identifier [CONSTANT] datatype [NOT NULL]
        [ := | DEFAULT expr];

例如

Declare
    v_hierdate    DATE
    c_tax_rate    CONSTANT NUMBER(3,2) := 0.25

注意:多個變量同一數據類型不能一起定義,一行定義一個

select語句要有into語句

%TYPE屬性

變量的聲明可以直接映射到數據庫的某一列上 或整個表上,這樣可以採用%TYPE或 %ROWTYPE將這個變量錨定到數據庫相應的列或表。

例如:

...
v_balance    NUMBER(7,2)
v_min_balance    V_balance%TYPE := 10
...

其他變量

  • boolean變量

三個類型:True,False,Null   (注意空值)

邏輯運算符:AND,OR,NOT

  • 大對象

三個類型:CLOB,BLOB,BFILE

  • 外部變量

在某一程序主環境下聲明的一種變量

在declare之前聲明的,瞭解。

複習:空值判斷要用is;空值=空值返回假;nvl(v_x,0)實現的內容是若v_x爲空則賦成0

輸出

DBMS_OUTPUT.PUT_LINE

DECLARE
    v_var    varchar2(10);
BEGIN
    SELECT ename into v_var
    FROM emp
    WHERE empno=7369;
    DBMS_OUTPUT.PUT_LINE('僱員名=' || v_var);
END;

 註釋

多行/**/

單行--

函數

過程語句中的有效函數:

  • 單行字符(CONCAT、LENGTH、LOWER、SUBSTR等)
  • 數據類型轉換(TO_ CHAR、TO_ DATE、 TO_ NUMBER等)
  • 日期(ADD_ MONTHS、SYSDATE、MONTHS_ BETWEEN等)

過程語句中的無效函數:

  • DECODE
  • 分組函數(AVG、MIN、MAX、COUNT、SUM等)
  • 分組函數僅在PL/SQL塊的SQL語句中適用

語句

可以用的

  • select語句
  • DML:insert update delete merge
  • 事物:commit rollback savepoint

PL/SQL不能用的

  • DDL: creat alter drop truncate rename
  • DCL:授權grant revoke

查詢語句

是用來給變量賦值的。只能返回一行結果,必須使用into。

例:選擇並打印emp表中的最高薪水

DECLARE
    v_sal    emp.sal%type
BEGIN
    SELECT    max(sal)
    INTO    V_sal
    FROM    emp;
    dbms_output.put_line(v_sal);
END;

DML語句

和SQL一致

例如:新增數據:新員工:工作職位‘MANAGER’,ID爲7788

BEGIN
    INSERT INTO emp
        (empno,ename,job,mgr,hiredate,sal)
    VALUES(
        1000,'TOM','MANAGER',7788,sysdate,4000);
END;

更新數據:增加analyst工資

DECLARE
    v_sal    emp.sal%type := 800;
BEGIN
    UPDATE emp
    SET sal = sal + v_sal
    WHERE job = 'ANALYST'   
END;

刪除數據:員工Smith離職

DECLARE
    v_ename    emp.ename%type := 'SMITH';
BEGIN
    DELETE FROM emp
    WHERE ename = v_ename
END;

事物控制語句

與SQL相同

BEGIN
    INSERT INTO temp(x, y)
        VALUES (1 ,'aaa') ;
    SAVEPOINT a;
    INSERT INTO temp (x,y)
        VALUES (2, 'bbb') ;
    SAVEPOINT b;
    ROLLBACK TO SAVEPOINT a;
    COMMIT;
END;

流程控制語句

IF語句

IF condition THEN
    statements;
ELSEIF condiction THEN
    statements;
ELSE
    statements;
END IF;

邏輯表

注意一些不常見的情況

CASE語句

兩種用法

CASE selector
    WHEN expression1 then result1
    WHEN expression2 then result2
    WHEN expressionN then resultN
    ELSE resultN+1
END;

例:

求僱員的平均薪水,當薪水小於1000時,提示”薪水太低”,當薪水大於等於1000小於2000時,提示”起步的薪水”, 當薪水大於等於2000時,提示”已經步入軟件行業中”,使用CASE表達式來實現.

DECLARE
    V_ _var    varchar2(20);
    V_sal    emp.sal%type; 
BEGIN
    SELECT avg(sal) INTO V_ sal FROM emp; 
    V_ _var :=
        CASE
            WHEN V_ sal <1000 THEN‘薪水 太低’
            WHEN V_ sal>=1000 AND V_ sal <2000 THEN '起步的薪水'
            ELSE '已經步 入軟件行業中’
        END;
    Dbms_ output.put _line(v_ var);
End;

 注意:要麼case後面加變量,when後面只有數字;要麼case後面沒東西,when後面加語句。二選一。

LOOP語句

三種循環:簡單循環(無條件循環)、for循環、while循環

  • 簡單循環

先進循環再判斷(和do-whille有點像)

LOOP
    statement
    ...
    EXIT [WHEN condition]
END LOOP;

例子:

DECLARE
    V_ count    number(2):= 1;
    V_ empno    emp.empno%type;
    V_ ename    emp.ename%type:=‘ SMITH;
    v_ job    emp.job%type:=‘MANAGER'; 
BEGIN
    SELECT max(empno) INTO V_ empno
    FROM emp;
    LOOP
        INSERT INTO test(empno,ename,job)
        VALUES ((v_ empno+v. count),v_ ename,v job);
        V_ count := V_ count + 1;
        EXIT WHEN v_ count >3;--注意循環邊界很重要
    end loop;
END;
  • for循環
FOR counter in [REVERSE]
    lower_ bound.. upper_ bound LOOP
    statement1;
    statement2;
    ...
END LOOP; ;

counter不需要顯示聲明;循環下界大於上界循環就不會執行;reverse可以使計數器從大到小遞減。

DECLARE
    V_ empno    emp.empno%type;
    V_ ename    emp.ename%type := 'ljs';
    V_ job    emp. job%type := 'manager'; 
BEGIN
    SELECT max(empno) INTO V_empno
    FROM emp; 
    FOR V_ count IN 1..3 LOOP
        INSERT INTO test(empno,ename,job)
            VALUES ((v_ empno+v_ count),v_ ename,v_ job); 
    END LOOP;
END;

注意:循環變量counter自動維護,只讀,自己不能修改(修改會報錯)。

WHILE循環

WHILE condition LOOP
    statement 1;
    statement2;
    ...
END LOOP;

和簡單循環類似,先判斷條件再進循環(和while語句比較像)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章