天天看點

帶你讀《SAS資料分析開發之道 軟體品質的次元》第三章通信交流3.4使用者生成的傳回碼(一)

使用者生成的傳回碼

正如SAS系統傳回碼能顯示 SAS程式、DATA步驟、函數及程式指令的成敗,開發人員應該使用使用者生成的傳回碼來驗證自己的宏、程序及程式。在軟體設計過程    中,應該能夠識别那些導緻軟體故障的漏洞,并确認哪些檢測漏洞的程式可以推行到    異常情況處理架構中。第 6章介紹了防錯性程式設計,并列舉了一些看似簡單的SAS程式中的漏洞案例,如閱讀資料集。

一個軟體的最佳操作是要求每個建立的宏都能至少産生一個傳回碼。在宏指令的第一行将&SYSCC指派為“0”,并在宏結束時檢查&SYSCC值,這樣能夠防禦一些意想不到的故障,沒必要評估子程序中的&SYSCC   值,但要評估引用宏并依賴子程序順利進行的父程序中的值。例如,在   DATA    步驟之前,可能想确認被引用的資料集不是空白的。

宏%GETOBS能夠确定資料集中觀測值的數量。如果因某些原因出現了故障,&GETOBS_RC 傳回碼會顯示該故障。

datatemp;run;

*determinesthenumberofobservationsinadataset;

%macrogetobs(dsn=/*  datasetnameisLIB.DSNorDSNformat*/);

%letsyscc=0;

%globalobstot;

%letobstot=;

%globalgetobs_rc;

%letgetobs_rc=GENERALFAILURE;procsqlnoprint;

selectcount(*)into:obstotfrom&dsn;

quit;

%if&syscc>0%then%letgetobs_rc=somethingaintright!;

%else%letgetobs_rc=;*emptyshowssuccess;

%mend;

%getobs(dsn=temp);

%putRC:getobs_rc;

RC:somethingaintright!

即便開發人員沒有意識到 SQL程式指令在資料集沒有任何變量的情況下會發生故障(如Temp),&SYSCC也會捕獲這一潛在的、不可預見的錯誤。“運作時錯誤”依然會發生,但調用 %GETOBS的父程序将能夠動态變更線路或穩健地終止,而不是受制于連鎖故障。需要注意的是,傳回碼的命名應具有獨特性,以避免它與 其他程式的傳回碼混淆。第      11     章“重複宏變量”部分會講到這一點。使用者生成的傳回碼通常可通過兩種方法進行操作 :帶内信号及帶外信号,以下會對這兩部分進行介紹。

帶内信号

帶内信号指通過現有管道傳遞中繼資料,資料主要通過該途徑轉移。關于軟體開發,帶内傳回碼轉移的是同一宏變量内的性能資訊——中繼資料,否則資料就會被轉移。帶内傳回碼的一個優點是簡單,因為無須建立一個單獨的通用宏變量。“使用者生成的傳回碼”部分舉的例子是一個帶外傳回碼(&GETOBS_RC),該傳回碼獨立于 &OBSTOT宏變量。相反,帶内解決方案在出現異常情況或錯誤時能夠将&OBSTOT的值指定為“有些事情不對勁”,進而使得&OBSTOT在觀測數值計數不能保留的情況下包含觀測數值的數量或錯誤資訊。

帶内傳回碼最大的缺點是它們必須能夠與有效資料清清楚楚地區分開,若未區分開,有效資料可能會出現在宏變量中。例如,一個用于表示資料集中變量數量的宏變量将包含數值型資料,這使它自身能夠通過字母數字資料表達附加的傳回碼值。字母數字傳回碼不會與有效數值資料混淆。

在上述“SYSRC()”部分介紹過一個使用者生成傳回碼的例子。若%TEST宏發生故障,本地宏變量 &VARS設定為 FAILURE。%GLOBAL宏建立該傳回碼,%LET程式指令将它的值初始化。初始化能夠確定在ATTRN發生故障且 &VARS未被設定為資料集中變量數量的情況下,故障能夠顯現出來。

%macrotest;

%globalvars;

%letvars=GENERALFAILURE;

%letdsid=%sysfunc(open(perm.final,i));

%if%sysfunc(sysrc())=0%then%do;

%letvars=%sysfunc(attrn(&dsid,nvars));

%letclose=%sysfunc(close(&dsid));

%end;

%else%letvars=FAILURE;

%test;

%putVARS:&vars;

在本例中,帶内傳回碼 &VARS有3個可能的結果 :如果 &VARS是一個數字, 那麼它代表的是PERM.Final資料集中出現的變量的數量 ;如果 &VARS是FAILURE,那麼它表示的是OPEN   遇到了異常情況,如一個丢失或鎖定的資料集   ;如果 &VARS是 GENERAL   FAILURE,那麼它表示一些其他的異常情況或錯誤阻止了&VARS的指派。

帶内傳回碼遠不如帶外信号常見,因為帶内信号要求中繼資料與資料之間界限分明。是以,如果宏變量被設計成包含字母、數字、文本,則更難将有效值與性能中繼資料區分開,性能中繼資料是在無法生成有效值的情況下被傳遞到變量的資料。