天天看點

帶你讀《SAS資料分析開發之道 軟體品質的次元》第三章通信交流3.2系統數字傳回碼(一)

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根本不會顯示這一故障。