SAS PassThrough查询以硬编码日期运行,而不是宏变量作为日期

发布于 2025-01-29 16:06:57 字数 2901 浏览 5 评论 0原文

我有一个脚本,该脚本运行了连接到Oracle数据库的SAS Passhthrough查询。这是在Unix服务器上运行的Cronjob的一部分,多年来一直没有问题。但是,在过去的几周中,这项工作已经开始挂在这一特定的一步上 - 根据原木过去大约需要15秒钟的时间,但是现在我们必须无限期地运行才能杀死工作。日志中没有相关的错误或警告 - 作业将创建一个锁紧file,只能无限期地运行,直到我们必须杀死它为止。

挂断工作的步骤粘贴在下面。有两个宏变量& start_dt and& end_dt,这些变量表示作业正在提取销售数据的日期范围。

在进行调查时,我们尝试了几种不同的方法,能够通过更改三件事来成功运行和通常的时间运行:

  • 通过连接连接的企业指南客户端运行脚本 到同一服务器,而不是通过CLI / shell运行脚本 脚本

  • 更改库的步骤写作要工作而不是编写
    到salesdata库的数据集(如下所示)

  • 将日期更改为硬编码值而不是宏变量。

至于日期变量本身,它们是date9格式的字符串,例如 & start_dt = '08 -may-22',& end_dt = '14 -may-22'。最初,我怀疑这个问题与日期的结构方式有关,因为这是我继承的一个较旧的项目,但是对于为什么这么长时间之前没有问题就跑到几周前,即使有这些格式奇怪的日期,这项工作很久就感到困惑宏vars。

我认为的另一种可能性是,Unix服务器上的某种资源在到达此步骤时就被锁定了。

以下脚本中的步骤的有问题版本:

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.sstatic.net/GGjin.jpg

I have a script that runs a SAS passhtrough query that connects to an Oracle database. This was part of a cronjob that runs on a Unix server, and has had no issues for years. In the past few weeks however, the job has started hanging up on this one particular step - according to logs it used to take about 15 seconds to run but now just will run indefinitely before we have to kill the job. There are no associated errors or warnings in the log - the job will create a lockfile and just run indefinitely until we have to kill it.

The step where the job hangs up is pasted in below. There are two macro variables &start_dt and &end_dt, which represent the date range the job is pulling sales data for.

While investigating, we tried a few different approaches, and were able to get this step to run successfully and in its usual time by changing three things:

  • running the script through an Enterprise Guide client which connects
    to the same server as opposed to running the script via CLI / shell
    script

  • Changing the library the step writes to to work instead of writing
    the dataset to salesdata library (as seen in code below)

  • Changing the dates to hardcoded values instead of macro variables.

As for the date variables themselves, they are strings in date9 format, e.g
&start_dt = '08-May-22', &end_dt = '14-May-22'. Initially I suspected the issue was related to the way the dates are structured since this is an older project I have inherited, but am confused to why the job ran without issue for so long up until a few weeks ago, even with these oddly formatted date macro vars.

The other possibility I considered was that some sort of resource on the unix server was getting locked up when it got to this step, potentially from some sort of hanging job or some other conflict with an older file such as a log or a previous sas dataset.

Problematic version of the step in the script pasted below:

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.sstatic.net/GGjin.jpg

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

丶情人眼里出诗心の 2025-02-05 16:06:57

您需要在Oracle中使用的日期常数哪种样式取决于您在Oracle中的设置。但是通常,您可以使用像其中之一的表达式,

date '2022-05-14' 
'2022-05-14'

您似乎声称在系统上可以使用诸如

'14-May-22'

(Oracle如何知道您的含义)之类的值?)。

请注意,在Oracle中,使用围绕常数的单引号很重要,因为它将字符串用双引号将字符串作为对象名称。

因此,如果您在SAS中有一个日期值,只需确保使宏变量值看起来像Oracle想要的。

例如,将ENDDT设置为今天的日期:

data _null_;
  call symputx('enddt',quote(put(today(),date11.),"'"));
run;

它与

%let enddt='17-MAY-2022';

What style you need to use for date constants in Oracle depends on your settings in Oracle. But normally you can use expressions like one of these

date '2022-05-14' 
'2022-05-14'

You seem to claim that on your system you can use values like

'14-May-22'

(how does Oracle know what century you mean by that?).

Note that in Oracle it is important to use single quotes around constants as it interprets strings in double quotes as object names.

So if you have a date value in SAS just make sure to make the macro variable value look like what Oracle wants.

For example to set ENDDT to today's date you could use:

data _null_;
  call symputx('enddt',quote(put(today(),date11.),"'"));
run;

Which would the same as

%let enddt='17-MAY-2022';
分分钟 2025-02-05 16:06:57

因此,@TOM答案很有帮助 - 几周前我们的DBA似乎更新了一些设置,从而影响了Oracle的严格性,即接受哪种日期格式。

对于它的价值,使用笨拙的数据步骤即时构建了宏观VARS的日期,该数据步骤读取了日期密钥数据集:

您会注意到,bost变量使用Year2,您会注意到日期字符串的最后一部分。格式,因此只是一年的最后两位数。

@Tom的观点,这显然使Oracle在哪个世纪中混淆了,因此工作被挂断了。

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;

一旦我更改了使用4年的步骤。上一件格式,这项工作能够在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;

So @Tom answer was helpful - it appears that our DBAs updated some settings a few weeks back that impacted how stringent Oracle is in terms of which date formats are accepted.

For what it's worth, the date macro vars were being constructed on the fly using a clunky data step that read off of a date key dataset:

You'll notice the last piece of the date string being put together for bost variables uses year2. format, so just the last two digits of the year.

To @Tom's point, this is apparently confusing Oracle in terms of which century its in, so the job gets hung up.

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;

Once I changed this step to use year4. format for the last piece, the job was able to run fine without incident on both unix and E guide. Example below:

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;

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文