PLSQL基礎 - 20190808

plsql塊

plsql的塊總共有兩種類型:匿名塊(沒有名字的塊)和命名塊,匿名塊具有有限的作用域(功能較少),命名塊更容易擴展,而且可重用資源。

匿名塊功能可使用在:腳本或其他的程序單元中,也就是說匿名塊的作用域僅限於包含匿名塊的程序單元或腳本。

命名塊程序作爲函數或者過程直接保存在模式中,命名快的作用最爲靈活。其次可以將命名塊程序保存在包裏面,一種方法通過發佈包函數或者過程。一種方法是獨佔的將函數或者過程保存在包主體內,這種方法限制此程序只能在包內部使用。

 
匿名塊

匿名塊原型:

    DECLARE (可選)
    Variables(變量), cursors(遊標), user-defined exceptions(異常)
    BEGIN (程序執行部分,也就是業務開始)
    SQL 語句
    PL/SQL 語句
    EXCEPTION (可選)
    處理異常
    END; (程序塊結束)

最佳操作:

在實現任何的局部命名塊之前,記住爲其定義前向引用規範,確保局部命名塊能夠相互調用

有兩個小小的細節,第一個是作爲一個強邏輯塊的語言,它要求在每一個塊中至少包括一條語句。第二個細節是

sql*plus格式化環境變量serveroutput來管理plsql程序的輸出。

對於第一個細節plsql提供null語句,在塊中使用null語句,可以在編寫詳細的塊邏輯之前確保基本塊邏輯控制正確。

    BEGIN
      NULL;--沒有任何語句的時候記得賦值null可以爲自己解決很多的麻煩
    END;

對於第一個細節如果使用命令行方式編程則需要配置環境變量,下面是命令行方式圖

 set serveroutput on--輸出

命令行方式寫匿名塊:

注意:q'()'可以替代引號在程序中使用,但是個人覺得還是用引號比較方便

 
替代變量

使用替代變量,可以將輸入的參數分配給匿名塊程序。使用&符號作爲前綴,替代變量可以是可變長得字符串或者是數字,不能再聲明塊中分配動態值。

    DECLARE
    v_num1 VARCHAR2(30);--變量
    v_num2 VARCHAR2(30);--變量
    BEGIN
     v_num1 :='&a';--從鍵盤輸入,但是我不太明白爲什麼用引號
    /* 測試結果輸入你好,輸出你好,解釋了爲什麼帶引號*/
       
       v_num2:=&a;
    /*   測試結果輸入你好,出錯必須帶字符串*/
      dbms_output.put_line(v_num1);
       
      dbms_output.put_line(v_num2);
     
      END;

建議:始終在執行塊中進行賦值或初始化,除非局部變量是常量或被視爲常量,這樣可以消除許多運行時賦值錯誤。

    DECLARE
      v_num CONSTANT VARCHAR2(25) := '掙大錢'; --定義一個常量
     
    BEGIN
     
      --打印輸出常量,常量在業務中是不變的,不能再業務中再改變它的值
      dbms_output.put_line(v_num);
     
    END;

可綁定變量

這困擾了我一下,課件上面的代碼運行不了,很懵逼。

處理交互式會話級變量的另一種方法是使用一種特殊的變量,oracle稱爲綁定(bind)變量,綁定變量使用冒號:作爲前綴。

注意:不應該在聲明塊中對綁定變量賦值。

plsql命令行下運行

 

    --會話級綁定變量,會話中變量的定義不適用冒號作爲前綴,plsql塊中使用冒號作爲前綴
    VARIABLE b VARCHAR2(20);--可綁定變量b
     
    BEGIN
      :b:='掙大錢';
      END;
     
     

使用綁定變量(關閉一個窗口也就是一個會話肯定是不能獲取到值了,因爲你本次的會話已經關閉了,沒有可綁定的變量)

    DECLARE
     
    v_num VARCHAR2(20);
     
    BEGIN
      v_num :=:b;--使用綁定變量
      dbms_output.put_line(v_num);
      END;

運行腳本

當時我建表的時候也出現問題,因爲日期插入有錯,明明表是老師給的爲什麼運行不了呢?於是百度了一下可以使用腳本的方式運行,

方法是:

也就是在sw下編寫代碼,保存然後使用cw來運行(@D:\自己打的代碼的腳本文件\調用可綁定變量.sql)

 

命名塊

我們知道可以運行匿名塊如何完成我們想要的功能,但是命名塊的功能更強大,存儲程序提供了和匿名塊相同的功能,但是可以將其部署到數據庫中,並從數據庫重用這些存儲程序。(推薦使用存儲程序)
過程塊

過程在另一個程序的作用域內運行,並執行某項任務。一般,開發人員調用過程,在某個現有事務作用域內執行任務如插入或更新表。

    --注意的in可以省略不寫,過程是沒有返回值的,可以使用
    --dbms_output.put_line()輸出
    CREATE OR REPLACE PROCEDURE h1(p_num IN VARCHAR2
                                  ) IS
    BEGIN
    dbms_output.put_line('掙大錢');
     
    END h1;

運行(調用過程):

    BEGIN
    h1('你要');
    END;

 
函數塊

函數總而言之有返回值,必須含有return語句

    CREATE OR REPLACE FUNCTION t1(p_num  varchar2--輸入的參數
                                     ) RETURN VARCHAR2 IS
      v_num1 VARCHAR2(35);--輸出的變量
    BEGIN
    v_num1 :=p_num||'掙大錢';--使用到字符拼接
      RETURN(v_num1);--函數必須有返回值
    END t1;

調用函數

    BEGIN
    dbms_output.put_line(t1('我要'));
    END;

嵌套塊

命名塊還可以嵌套在其他命名塊或匿名塊中,那麼問題來了,嵌套命名塊並不是已經發布的,這意味着在調用一個命名塊時,被調用的命名塊可能還沒有定義。這種類型的設計也稱爲‘作用域錯誤’,被調用的程序在調用發生之前是未知的。導致編譯錯誤。

解決方法一:被調用的命名塊放在前面。

    DECLARE
    --被調用的要放在前面
    FUNCTION b RETURN VARCHAR2 IS
      BEGIN
      RETURN 'hello';
      END b;
    --調用者放在後面
    procedure a IS
    BEGIN
     dbms_output.put_line(b||'掙大錢');
    END a;
     
    BEGIN
      a;--調用程序a
     
    END;

解決方法二:爲過程和函數提供佔位程序

    DECLARE
    --定義
    PROCEDURE a;--存儲過程
    FUNCTION b RETURN VARCHAR2;--函數
    PROCEDURE a IS
      BEGIN
    dbms_output.put_line(b||'掙大錢');--調用b程序過程
     
      END a;
     
    FUNCTION b RETURN VARCHAR2 IS
      BEGIN
    RETURN '我要';
      END b;
     
    BEGIN
    a;--調用a的程序過程
      
      END;

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