【发布时间】:2022-01-23 13:11:10
【问题描述】:
我有一个已经运行多年的程序。今天,我们从 SAS 9.4M3 升级到 9.4M7。
proc setinit
Current version: 9.04.01M7P080520
从那以后,我无法获得与升级前相同的结果。
请注意,我是直接查询 Oracle 数据库。
尝试用一个最小的、可重现的 SAS 表示例来复制问题,我发现在 SAS 表而不是 Oracle 数据库上查询时问题消失了。
假设我有以下数据集:
data have;
infile datalines delimiter="|";
input name :$8. id $1. value :$8. t1 :$10.;
datalines;
Joe|A|TLO
Joe|B|IKSK
Joe|C|Yes
;
使用临时表:
proc sql;
create table want as
select name,
min(case when id = "A" then value else "" end) as A length 8
from have
group by name;
quit;
Results:
name A
Joe TLO
但是,当直接在 oracle 数据库上运行相同的查询时,我得到了一个缺失值:
proc sql;
create table want as
select name,
min(case when id = "A" then value else "" end) as A length 8
from have_oracle
group by name;
quit;
name A
Joe
根据文档,min() 函数在 SAS 表上使用时表现正常
MIN 函数返回缺失值 (.)仅当所有参数都缺失时。
我相信当 Oracle 不理解 SAS 传递它的函数时会发生这种情况 - SAS 和 Oracle 中的 min 函数非常不同,SAS 中的等效函数是 LEAST()。
所以我的猜测是升级搞砸了如何将 SAS min 函数转换为 Oracle,但它仍然是一个猜测。有没有人遇到过这种行为?
编辑:@Richard 的评论
options sastrace=',,,d' sastraceloc=saslog nostsuffix;
proc sql;
create table want as
select t1.name,
min(case when id = 'A' then value else "" end) as A length 8
from oracle_db.names t1 inner join oracle_db.ids t2 on (t1.tid = t2.tid)
group by t1.name;
ORACLE_26: Prepared: on connection 0
SELECT * FROM NAMES
ORACLE_27: Prepared: on connection 1
SELECT UI.INDEX_NAME, UIC.COLUMN_NAME FROM USER_INDEXES UI,USER_IND_COLUMNS UIC WHERE UI.TABLE_NAME='NAMES' AND
UIC.TABLE_NAME='NAMES' AND UI.INDEX_NAME=UIC.INDEX_NAME
ORACLE_28: Executed: on connection 1
SELECT statement ORACLE_27
ORACLE_29: Prepared: on connection 0
SELECT * FROM IDS
ORACLE_30: Prepared: on connection 1
SELECT UI.INDEX_NAME, UIC.COLUMN_NAME FROM USER_INDEXES UI,USER_IND_COLUMNS UIC WHERE UI.TABLE_NAME='IDS' AND
UIC.TABLE_NAME='IDS' AND UI.INDEX_NAME=UIC.INDEX_NAME
ORACLE_31: Executed: on connection 1
SELECT statement ORACLE_30
ORACLE_32: Prepared: on connection 0
select t1."NAME", MIN(case when t2."ID" = 'A' then t1."VALUE" else ' ' end) as A from
NAMES t1 inner join IDS t2 on t1."TID" = t2."TID" group by t1."NAME"
ORACLE_33: Executed: on connection 0
SELECT statement ORACLE_32
ACCESS ENGINE: SQL statement was passed to the DBMS for fetching data.
NOTE: Table WORK.SELECTED_ATTR created, with 1 row and 2 columns.
! quit;
NOTE: PROCEDURE SQL used (Total process time):
real time 0.34 seconds
cpu time 0.09 seconds
【问题讨论】:
-
您是使用 ODBC 连接还是访问 Oracle?检查这些组件是否已升级?
-
请注意,在 SAS 中键入
""或''不会创建空字符串。这与输入" "相同。如果你真的想在 SAS 中生成一个空字符串,你需要使用像trimn(' ')这样的函数调用。