PLSQL基礎(一)

1.hello,world起步

點擊file,創建一個sql window

DECLARE
  v_message VARCHAR2(12):='Hello,world';
BEGIN
  dbms_output.put_line(v_message);
END;

(F8)運行結果:
這裏寫圖片描述

1)PLSQL的每一段程序都是一個塊(block)。DECLARE 是聲明部分,可以聲明變量、常量;BEGIN 顧名思義就是“開始”執行命令了。

2)定義一個叫做“v_message”的變量,變量類型爲可變長字符串;“:=”在PLSQL中是用來賦值的,字符串用單引號括起來。

v_message VARCHAR2(12):='Hello,world';

3)輸出變量,相當於C#中的console.writeLine()

dbms_output.put_line(v_message);

2.PLSQL變量

(1)變量的聲明

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

identifier 是變量名,建議用v開頭,datatype是類型,中括號的是可選參數。

(2)舉個栗子

DECLARE
    v_name VARCHAR2(10):='melon';
    v_salary NUMBER(5,2):=800.89;
    v_sname v_name%TYPE:='小明';
    v_date  DATE:=SYSDATE;
BEGIN
  dbms_output.put_line('系統時間:'||v_date);
  dbms_output.put_line(v_name||'的薪水是'||v_salary);
  dbms_output.put_line(v_sname||'是學生');
END;

運行結果:

這裏寫圖片描述

1)變量類型後面的括號是變量的長度,number(5,2)是說變量長度爲5,小數點後面有兩位。

2)PLSQL特有的%TYPE屬性,來聲明和XX類型一致的變量類型。v_sname的類型和 v_name的類型一致

v_sname v_name%TYPE:='小明';

3)SYSDATE可以獲取當前的系統時間;’||’是連接操作符,相當於我們通常用的’+’,用於連接字符串。

DECLARE
   v_salary NUMBER(6):=&p_salary;
   v_totalSalary v_salary%TYPE;
BEGIN
  v_totalSalary:=v_salary*12;
  dbms_output.put_line('年收入是'||v_totalSalary);

END;

這裏寫圖片描述

運行結果:

這裏寫圖片描述

&parameter在PLSQL的SQL windows的執行環境中,用於提示用戶輸入一個具體的值

(3)PLSQL嵌套塊

<<OUT>>
DECLARE
    /*
       PLSQL塊嵌套
      ********
      ********
      ********
    */

    --聲明一個外部變量
    v_firstName VARCHAR2(20);
BEGIN
  DECLARE
     --內部變量
     v_lastName varchar2(20);
     v_name VARCHAR2(20);
  BEGIN
     v_lastName:='不感冒';
     out.v_firstName:='假裝';
     v_name:=out.v_firstName;
     dbms_output.put_line('your full name is '||'【'||v_name||v_lastName||'】');
  END;
END;

運行效果:

這裏寫圖片描述

1)PLSQL塊之間可以嵌套的,在內塊可以通過下面的方式來訪問外塊變量,out是給外塊取的名字

out.v_firstName:='假裝';

2)【/**/】可用於多行註釋,【–】用於單行註釋

3.PLSQL控制語句

(1)PLSQL判斷語句(IF,CASE)

DECLARE
  v_score   NUMBER(2) := &p_score;
  v_message VARCHAR2(100);
BEGIN
  IF v_score < 60 THEN
    v_message := 'bad';
  ELSIF v_score < 80 THEN
    v_message := 'not very bad';
  ELSIF v_score < 90 THEN
    v_message := 'good';
  ELSE
    v_message := 'quite good';
  END IF;
  dbms_output.put_line('your score is '||v_score||'. level:'||v_message);

END;

運行效果:

這裏寫圖片描述

注意這裏的if 條件是不用括號括起來的;其他條件是【ELSIF】不是【ELSEIF】

DECLARE
  v_day   char(1) := &p_day;
  v_message VARCHAR2(100);
BEGIN
  CASE v_day
    WHEN 6 THEN v_message:='睡覺';
    WHEN 7 THEN v_message:='爬山';
    ELSE v_message:='工作';
 END CASE;
  dbms_output.put_line('星期'||v_day||'要去'||v_message);
END;

(2)PLSQL循環(LOOP,WHILE,FOR)

【LOOP】

DECLARE
   v_salary NUMBER(5):=&p_salary;
   v_original v_salary%TYPE;
   v_count  NUMBER(2):=0;
BEGIN
   v_original:=v_salary;
  LOOP
     v_salary:=v_salary*(1+0.21);
     v_count:=v_count+1;
     EXIT WHEN v_salary>3000;
  END LOOP;
  dbms_output.put_line('原始工資'||v_original||',漲後工資'||v_salary||',執行次數:'||v_count);
END;

運行結果:

這裏寫圖片描述

【WHILE】

DECLARE
  v_salary   NUMBER(5) := &p_salary;
  v_original v_salary%TYPE;
  v_count    NUMBER(2) := 0;
BEGIN
  v_original := v_salary;
  WHILE v_salary < 3000 LOOP
    v_salary := v_salary * (1 + 0.21);
    v_count  := v_count + 1;
  END LOOP;
  dbms_output.put_line('原始工資' || v_original || ',漲後工資' || v_salary || ',執行次數:' || v_count);
END;

【FOR】

DECLARE
  v_salary   NUMBER(5) := &p_salary;
  v_original v_salary%TYPE;
  v_count    NUMBER(2) := 0;
BEGIN
  v_original := v_salary;
  FOR i IN 1 .. 7 LOOP
    v_salary := v_salary * (1 + 0.21);
    v_count  := v_count + 1;
  END LOOP;
  dbms_output.put_line('原始工資' || v_original || ',漲後工資' || v_salary || ',執行次數:' || v_count);
END;

三者都可以用來循環,當知道執行次數的情況下用for比較合適

4.自定義數據類型

自定義數據類型包括記錄類型、PLSQL內存表類型(類似於數組)

(1)記錄類型

【語法】

TYPE type_name IS RECORD
     (field_declaration[,field_declaration]...);
     IDENTIFIER type_name

【栗子】

DECLARE
    TYPE student_record IS RECORD
    (
        v_name VARCHAR2(20),
        v_age  NUMBER(2),
        v_sex  VARCHAR2(4)
    );
   stu  student_record;
BEGIN
   stu.v_name:='小明同學';
   stu.v_age:=10;
   stu.v_sex:='男';
  dbms_output.put_line(stu.v_name||','||stu.v_sex||','||stu.v_age||'歲了');
END;

這裏寫圖片描述

【%ROWTYPE】

顧名思義,可理解爲行記錄類型,表示某張表的記錄類型或者用戶指定的記錄類型

先簡單地創建一個【student】表,只是爲了測試(這不規範)

CREATE TABLE student(
       stu_no VARCHAR(5),
       stu_name VARCHAR(20),
       stu_sex  VARCHAR2(5)
)

往裏面插入一條數據

INSERT INTO student VALUES(12004,'德瑪西亞','男');

找到學號爲’12004’學生的個人信息

DECLARE
   student_rec student%ROWTYPE;
BEGIN
  SELECT * INTO student_rec
         FROM student
         WHERE stu_no=&p_stu_no;
  dbms_output.put_line(student_rec.stu_name||'的學號是'||student_rec.stu_no);
END;

輸出結果:

這裏寫圖片描述

student_rec 是和student表記錄類型一樣的行記錄類型,簡言之,student表下的字段屬性和類型,student_rec也擁有。值得注意的是,它只能存放一條記錄,可記爲【一行多列】

(2)內存表類型

這種結構類似於數組,使用主鍵提供類似於數組那樣的元素訪問。這種類型必須包括兩部分:使用BINARY_INTEGER類型構成的索引主鍵;一個簡單類型或自定義類型的字段作爲具體的數組元素

【語法】


TYPE type_name IS TABLE OF
     column_type|VARIABLE%TYPE
     |table.column%TYPE}[NOT NULL]
     |TABLE.%ROWTYPE
     [INDEX BY BINARY_INTEGER];
 IDENTIFIER type_name

【栗子】

DECLARE
    TYPE stu_name_type IS TABLE OF
         student.stu_name%TYPE
         INDEX BY BINARY_INTEGER;
         name_array stu_name_type;
BEGIN
          name_array(1):='六郎';
          name_array(2):='三毛';
           dbms_output.put_line(name_array(1)||name_array(2));
END;

5.遊標

遊標是一個私有的SQL工作區域,ORCALE有兩種遊標,分別爲隱式和顯式遊標。隱式遊標是Oracle服務器使用的解析和執行我們提交的SQL語句;顯式遊標是程序猿在程序中顯式聲明的。

(1)遊標的屬性

  • SQL%ROWCOUNT ——》表示SQL語句受影響的行數
  • SQL%FOUND ——》 表示SQL語句是否影響了一行以上
  • SQL%NOTFOUND ——》 表示SQL語句沒有影響數據
  • SQL%ISOPEN ——》表示是否打開

(2)顯式遊標

1)通常所說的遊標就是顯式遊標。對於返回多行結果的SQL語句的多行結果,可用顯式遊標獨立處理每一行數據。

2)遊標的相關函數可以做到:

  • 一行一行的處理返回的數據
  • 保持當前處理行的一個跟蹤,像指針一樣指示當前處理的記錄
  • 允許程序猿在PLSQL塊中人爲的控制遊標的開啓、關閉、上下移動

3)遊標控制過程

【聲明遊標】=》【打開遊標】=》【提取當前行到變量】=》【測試行的存在】=》【關閉遊標】

(3)操作遊標


DECLARE
     v_name student.stu_name%TYPE;
     v_no   student.stu_no%TYPE;
     CURSOR stu_cursor IS
            SELECT stu_name,stu_no FROM student;
BEGIN
      --打開遊標
      OPEN stu_cursor;
      --循環遊標的數據
      LOOP
        --提取一行數據
        FETCH stu_cursor INTO v_name,v_no;
        EXIT WHEN stu_cursor%ROWCOUNT>3 OR stu_cursor%NOTFOUND;
        dbms_output.put_line(v_no||v_name);
      END LOOP;
      --關閉遊標
      CLOSE stu_cursor;
END;

運行結果:

這裏寫圖片描述

如果覺的上面對遊標的遍歷繁瑣的話,可以使用for循環,省去了對遊標的聲明、打開、提取、測試、關閉等語句

【語法】

FOR record_name IN cursor_name LOOP
  statement1;
  statement2;
  ...
  END LOOP;

【栗子】


DECLARE
     v_name student.stu_name%TYPE;
     v_no   student.stu_no%TYPE;
BEGIN
    FOR stu_cursor IN (
                       SELECT stu_name,stu_no
                                   FROM student)
         LOOP
           v_name:=stu_cursor.stu_name;
           v_no:=stu_cursor.stu_no;
           dbms_output.put_line('【學號】:'||v_no||'【姓名】:'||v_name);
         END LOOP;

END;

運行結果:

這裏寫圖片描述

(4)FOR UPDATE NOWAIT語句

有的時候我們打開一個遊標是爲了更新或刪除一些記錄,這種情況下我們希望在打開遊標的時候鎖定相關的記錄,應該使用這條語句,如果鎖定失敗就停止不再繼續,以免出現長時間等待資源的死鎖情況。

【語法】

SELECT  ....
FROM        ....
FOR UPDATE [OF column_reference][NOWAIT]
發佈了40 篇原創文章 · 獲贊 87 · 訪問量 13萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章