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;