SAS中的虛拟傳回碼
對于比較熟悉第三代語言(3GL)的軟體開發人員來說,前面對傳回碼的解釋可能會顯得不充分或不準确。實際上,在許多軟體語言中,“傳回”程式指令的目的是提示終止某個參數,即從子程序向父程序傳回某個或某些值。在SAS中,系統生成的傳回碼确實會執行這個功能,然而,%RETURN宏函數“造成目前運作宏的終止”,但實際并不會傳回任何内容。BaseSAS 中沒有固有的方法用來傳回宏的值。
考慮到這種限制,BaseSAS 中不能生成真正的傳回碼,因而需要編寫傳回碼。通過在 SAS 宏中啟用通用宏變量,資訊能夠有效地從子程序傳遞到父程序中。盡管與其他計算機語言相比,這樣做的效率較低,且安全性較差,但确實發揮了它應有的作用,同時,該限制不應該妨礙 SAS 從業人員在其軟體中執行傳回碼。
編寫傳回碼的一個缺點是違反松耦合——通用宏變量一旦建立,所有的子程序便都可調用,而并非隻是調用該宏的父程序。是以,軟體必須確定所有通用宏變量定義的獨特性,以避免它們之間互相影響或幹擾其他程式。實作這種安全性的一個方法是将宏名稱作為傳回碼變量名稱的基礎。在下面的案例中,%CHILD宏會産生&CHILDRC傳回碼 :
%macrochild();
%letsyscc=0;
%globalchildRC;
%letchildRC=GENERALFAILURE;
*dosomeprocess;
%if&syscc=0%then%letchildRC=;
%mend;
編寫傳回碼的另一個缺點是傳回碼的持續存在性,它會一直存留在以前的程式或在同一 SAS 會話運作的上一項目中。例如,如果代碼未将傳回碼初始化為預設值,那麼上一個操作的值可能會繼續存留在目前的運作環境中,進而影響該傳回碼及結 果。如前所述,在宏初始階段将傳回碼設定為一種故障狀态,或者僅在過程已經被證 實成功之後再指定一個有效的傳回碼,通過這兩種方式均可以消除上述漏洞(第 11章會具體講解)。
系統數字傳回碼
SAS系統生成的自動宏變量扮演着多個角色,它們能幫助我們了解 SAS運作環境及作業系統(OS),控制SAS的操作運作方式,記錄性能名額。自動宏變量的子集包括描述軟體性能的傳回碼,如特定SAS程式指令或功能的成功與失敗。在執行過程中出現的警告或運作錯誤通常會自動地存儲在傳回碼中。傳回碼一個主要的優點是, 它們能夠自動驅動動态處理過程,而無須手動識别錯誤,這避免了 SAS從業人員費 時費力地分析日志結果以搜尋出故障或證明軟體的成功運作。
《SAS9.4宏語言 :參考(第4版)》(SAS 9.4MacroLanguage: Reference, 4thed)中涵蓋了多數 SAS自動宏變量,其餘的 SAS自動宏變量則出現在《SAS9.4SQL程式使用者指南(第 3版)》(SAS9.4SQLProcedureUser’sGuide, 3rded)中。
數字傳回碼:
&SYSERR 系統錯誤表示最近運作過程中的錯誤代碼,在每個邊界步驟中會重置該錯誤代碼。
&SYSCC 系統目前代碼指整個SAS 工作中産生的最高錯誤代碼,該代碼在SAS 會話中不會進行重置。
&SQLRC SQL 傳回碼表示最近的SQL 程式指令—— 是指令而不是程式——是否被正确執行。
&SYSFILRC 系統檔案傳回碼指FILENAME 程式指令是否被正确執行。
&SYSLIBRC 系統資料庫傳回碼指LIBNAME 程式指令是否被準确執行。
&SYSLCKRC 系統鎖定傳回碼指LOCK 程式指令是否被準确執行。
&SYSRC 系統傳回碼記錄的是與OS 運作環境直接互動的程式指令的狀态,
如X、 SYSEXEC、SYSTASK 和WAITFOR。
SYSRC() 盡管從技術層面來講系統傳回碼是一個函數而不是一個傳回碼,但它傳回的是最近執行的輸入/ 輸出(I/O)函數的狀态。
&SYSERR
&SYSERR 宏變量是一個非常重要的傳回碼,它能顯示最近執行過程的成功與失敗。下面的輸出結果顯示的是一個成功的、建立 Final資料集的DATA步驟,由于沒有出現任何警告或錯誤,是以,&SYSERR的值設定為“0”:
datafinal;
setoriginal;*datasetexists;run;
NOTE:Therewere1observationsreadfromthedatasetWORK.ORIGINAL.NOTE: The data set WORK.FINAL has 1 observations and 0 variables.NOTE:DATAstatementused(Totalprocesstime):
realtime 0.01seconds
cputime 0.01seconds
%putSYSERR:&syserr;
SYSERR:0
若以下輸出中,Original資料集不存在,那麼&SYSERR将設定為“1012”,這表示 SAS總體的錯誤條件 :
setoriginal;
ERROR:FileWORK.ORIGINAL.DATAdoesnotexist.run;
NOTE:TheSASSystemstoppedprocessingthisstepbecauseoferrors.
WARNING:ThedatasetWORK.FINALmaybeincomplete.Whenthisstepwasstoppedtherewere0observationsand0variables.
WARNING:DatasetWORK.FINALwasnotreplacedbecausethisstepwasstopped.
NOTE:DATAstatementused(Totalprocesstime):realtime 0.01seconds
SYSERR:1012
&SYSERR 宏變量是隻讀模式,開發人員無法直接複制該變量,是以,&SYSERR通常會包含準确值,然而,通過錯誤的業務邏輯,可以手動将讀寫自動化宏變量重置為一個無效的非錯誤條件。&SYSERR 在每一個步驟邊界之後都會進行重置,包括DATA 步驟及程式。需要特别注意的是,如果兩個程式按順序執行,在程式執行之後評估 &SYSERR值時,隻能評估第二個程式的狀态。是以,如果測試和調試序列化的單片 SAS代碼,可能需要重複檢查&SYSERR的值,以確定能夠識别或分離出有故障的程式。
然而,許多特定的故障類型隻有借助具體的傳回碼才能識别。例如,FILENAME程式指令出現了錯誤,&SYSERR依然是“0”(表示操作沒有任何錯誤),這是因為 &SYSFILRC捕獲了異常情況的資訊。當 SAS 代碼用于宏架構時,尤其需要利用所有相關的傳回碼來捕獲全部的故障資訊。例如,當軟體遭遇錯誤情況“T”時,是很麻煩的事情?在下面的例子中,“5”被錯誤拼寫為“T”,盡管宏已進行編譯,但依然發生了故障 :
%macrotest;
%letsyscc=0;*requiredtoresetSYSCCanytimeitwillbeassessed;
%doi=1%toT;*softwaredefectinwhichTshouldhavebeen5;lengthchar&i$10;
%end;run;
當該代碼運作時,DATA步驟就會出現故障,日志中隻會出現提示資訊,而
此時,&SYSERR會顯示無錯誤運作。隻有 &SYSCC會準确捕獲引起故障的文法錯誤 :
%test;
NOTE: The data set WORK.FINAL has 1 observations and 0 variables.NOTE:DATAstatementused(Totalprocesstime):
realtime 26.44seconds
cputime 0.90seconds
ERROR: A character operand was found in the %EVAL function or %IFconditionwhereanumericoperandisrequired.Theconditionwas:TERROR:The%TOvalueofthe%DOTloopisinvalid.
ERROR:ThemacroTESTwillstopexecuting.
%putSYSERR:&syserr;SYSERR:0
%putSYSCC:&syscc;
SYSCC:1012
該代碼依然會建立資料集,但由于 LENGTH程式指令沒有運作,因而沒有任何變量。對于這種“悲壯”的故障,必須使用 &SYSCC來捕獲錯誤,因為 &SYSERR根本不會顯示這一故障。