我有一個腳本,它運行一個連接到 Oracle 資料庫的 SAS passhtrough 查詢。這是在 Unix 服務器上運行的 cronjob 的一部分,多年來一直沒有問題。然而,在過去的幾周里,這項作業已經開始在這一特定步驟上掛起 - 根據日志,它過去需要大約 15 秒才能運行,但現在在我們不得不終止作業之前將無限期地運行。日志中沒有相關的錯誤或警告 - 該作業將創建一個鎖定檔案并無限期地運行,直到我們不得不殺死它。
作業掛起的步驟粘貼在下面。有兩個宏變數 &start_dt 和 &end_dt,它們代表作業正在為其提取銷售資料的日期范圍。
在調查程序中,我們嘗試了幾種不同的方法,通過更改三項內容,我們能夠讓此步驟在正常時間內成功運行:
通過連接到同一服務器的企業指南客戶端運行腳本,而不是通過 CLI/shell 腳本運行腳本
將步驟寫入的庫更改為作業,而不是
將資料集寫入 salesdata 庫(如下面的代碼所示)將日期更改為硬編碼值而不是宏變數。
至于日期變數本身,它們是 date9 格式的字串,例如 &start_dt = '08-May-22', &end_dt = '14-May-22'。最初我懷疑這個問題與日期的結構方式有關,因為這是我繼承的一個較舊的專案,但我很困惑為什么直到幾周前這項作業一直沒有問題,即使這些日期格式奇怪宏變數。
我考慮的另一種可能性是 unix 服務器上的某種資源在執行此步驟時被鎖定,可能是由于某種掛起的作業或與舊檔案(如日志或以前的 sas 資料集)的其他沖突.
下面粘貼的腳本中步驟的有問題的版本:
PROC SQL;
connect to oracle(user=&uid pass=&pwd path='@dw');
create table salesdata.shipped as
Select
SKN_NBR,
COLOR_NBR,
SIZE_NBR,
SALESDIV_KEY,
ORDER_LINE_QTY as QUANTITY label="SUM(ORDER_LINE_QTY)",
EX1 as DOLLARS label="SUM(EX1)" from connection to oracle(
select
A1."SKN_NBR",
A1."COLOR_NBR",
A1."SIZE_NBR",
decode(A1."SALESDIV_KEY", 'ILB', 'IQ',
'IQ ', 'IQ',
'IQC', 'IQ',
'ISQ', 'IQ',
'IWC', 'IQ',
'QVC'),
SUM(A1."ORDER_LINE_QTY"),
SUM(A1."ORDER_LINE_QTY" * A1."ORDER_LINE_PRICE_AMT")
from DW.ORDERLINE A1, DISTINCT_SKN A2, DW.ORDERSTATUSTYPE A3
where
A2."SKN_NBR" = A1."SKN_NBR" AND
A1."CURRENT_STATUS_DATE" Between &start_dt and &end_dt AND
A1."ORDERLINESTATUS_KEY" = A3."ORDERLINESTATUS_KEY" AND
A3."ORDERSTATUS_SHIPPED" = 'Y' AND
A1."ORDER_LINE_PRICE_AMT" > 0
group by A1."SKN_NBR",
A1."COLOR_NBR",
A1."SIZE_NBR",
decode(A1."SALESDIV_KEY", 'ILB', 'IQ',
'IQ ', 'IQ',
'IQC', 'IQ',
'ISQ', 'IQ',
'IWC', 'IQ',
'QVC')
order by A1."SKN_NBR",
A1."COLOR_NBR",
A1."SIZE_NBR",
decode(A1."SALESDIV_KEY", 'ILB', 'IQ',
'IQ ', 'IQ',
'IQC', 'IQ',
'ISQ', 'IQ',
'IWC', 'IQ',
'QVC')
) as t1(SKN_NBR, COLOR_NBR, SIZE_NBR, SALESDIV_KEY, ORDER_LINE_QTY, EX1)
;
disconnect from oracle; quit;
[1]: https://i.stack.imgur.com/GGjin.jpg
uj5u.com熱心網友回復:
您需要在 Oracle 中為日期常量使用什么樣式取決于您在 Oracle 中的設定。但通常你可以使用其中之一的運算式
date '2022-05-14'
'2022-05-14'
您似乎聲稱在您的系統上您可以使用類似的值
'14-May-22'
(甲骨文怎么知道你指的是哪個世紀?)。
請注意,在 Oracle 中,在常量周圍使用單引號很重要,因為它將雙引號中的字串解釋為物件名稱。
因此,如果您在 SAS 中有一個日期值,只需確保使宏變數值看起來像 Oracle 想要的。
例如,要將 ENDDT 設定為今天的日期,您可以使用:
data _null_;
call symputx('enddt',quote(put(today(),date11.),"'"));
run;
這將與
%let enddt='17-MAY-2022';
uj5u.com熱心網友回復:
所以@Tom 的回答很有幫助——我們的 DBA 似乎在幾周前更新了一些設定,這影響了 Oracle 在接受哪些日期格式方面的嚴格程度。
對于它的價值,日期宏變數是使用讀取日期鍵資料集的笨重資料步驟動態構建的:
您會注意到為 bost 變陣列合在一起的日期字串的最后一段使用 year2。格式,所以只有年份的最后兩位數。
就@Tom而言,這顯然使甲骨文在哪個世紀感到困惑,因此這項作業被掛斷了。
data dateparm;
set salesdata.week_end_date;
start = "'" || put(day(week_end_date - 6), z2.) || '-' || put(week_end_date - 6, monname3.) || '-' ||
put(week_end_date - 6, year2.) || "'";
end = "'" || put(day(week_end_date), z2.) || '-' || put(week_end_date, monname3.) || '-' ||
put(week_end_date, year2.) || "'";
call symput('start_dt', start);
call symput('end_dt', end);
run;
一旦我將此步驟更改為使用 year4。對于最后一塊的格式,該作業能夠在 unix 和 E 指南上正常運行而不會發生任何事件。下面的例子:
data dateparm;
set npdd.week_end_date;
start = "'" || put(day(week_end_date - 6), z2.) || '-' || put(week_end_date - 6, monname3.) || '-' ||
put(week_end_date - 6, year4.) || "'";
end = "'" || put(day(week_end_date), z2.) || '-' || put(week_end_date, monname3.) || '-' ||
put(week_end_date, year4.) || "'";
call symput('start_dt', start);
call symput('end_dt', end);
run;
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/477165.html