遗留SAS程序SELECT列未在SQL表中显示,增删该列均报错
遗留SAS程序INSERT INTO语句的矛盾问题
接手的一段遗留SAS程序存在如下问题:
- INSERT INTO语句的SELECT子句中,选中了
PUT(%sysfunc(catx(0,&CurrYR,&CurrQtr)),6.) AS fld列,但该列并未在目标表mytable的结构定义中出现。 - 尝试两种修正操作都会触发报错:
ERROR: Attempt to insert fewer columns than specified after the INSERT table name- 将
fld列添加到CREATE TABLE mytable的结构定义中 - 从SELECT子句中移除
fld列
- 将
完整代码
data mydata; input Industry $ Variable $ Value ReferencePeriod; datalines; Manufacturing Assets 100 20204 Retail Assets 200 20204 Finance Assets 500 20204 Travel Assets 300 20204 Biotech Assets 100 20204 ; run; %let StartYr=20201; %let EndYR=20204; PROC SQL; CREATE TABLE mytable ( ReferencePeriod char(6) , INDUSTRY char(6) , Variable num , Value num ); %MACRO GETDATA(From,To); %DO %WHILE(&From<=&To); %LET CurrYR = %substr(&From,1,4); %LET CurrQtr = %substr(&From,5,1); PROC SQL; INSERT INTO mytable SELECT DISTINCT PUT(%sysfunc(catx(0,&CurrYR,&CurrQtr)),6.) AS fld , /* ReferencePeriod, */ INDUSTRY , Variable , Value FROM work.mydata GROUP BY PUT(%sysfunc(catx(0,&CurrYR,&CurrQtr)),6.) , Industry , Variable ; QUIT; %IF &CurrQtr = 4 %THEN %LET From = %eval(&CurrYR+1)1; %ELSE %LET From = &CurrYR%eval(&CurrQtr+1); %END; %MEND; %GETDATA(&StartYR,&EndYR);
问题根源分析
目标表mytable共定义了4列:ReferencePeriod、INDUSTRY、Variable、Value。当前SELECT子句返回的也是4列:fld、INDUSTRY、Variable、Value——列数刚好匹配,所以原代码能正常执行。
报错的原因在于:
- 若给
mytable新增fld列,表结构变为5列,但SELECT仍返回4列,列数不匹配触发报错。 - 若移除SELECT中的
fld,返回列数变为3,少于目标表的4列,同样触发列数不匹配报错。
原代码中注释掉ReferencePeriod列,实际意图是用生成的fld值填充目标表的ReferencePeriod列,但别名写错成fld,导致看起来列不对应,实则列数刚好凑对。
修正方案
方案1:修正别名匹配目标表列名
将SELECT中的AS fld改为AS ReferencePeriod,直接对应目标表的第一列,代码更清晰:
PROC SQL; INSERT INTO mytable SELECT DISTINCT PUT(%sysfunc(catx(0,&CurrYR,&CurrQtr)),6.) AS ReferencePeriod , INDUSTRY , Variable , Value FROM work.mydata GROUP BY ReferencePeriod , Industry , Variable ; QUIT;
方案2:显式指定INSERT的列映射
在INSERT INTO后明确列出目标表列名,确保SELECT返回值与目标列一一对应,无需依赖别名:
PROC SQL; INSERT INTO mytable (ReferencePeriod, INDUSTRY, Variable, Value) SELECT DISTINCT PUT(%sysfunc(catx(0,&CurrYR,&CurrQtr)),6.) , INDUSTRY , Variable , Value FROM work.mydata GROUP BY PUT(%sysfunc(catx(0,&CurrYR,&CurrQtr)),6.) , Industry , Variable ; QUIT;
额外优化:原代码中DISTINCT与GROUP BY功能重复,GROUP BY已自动实现去重,可移除DISTINCT提升执行效率。
内容的提问来源于stack exchange,提问作者Ivy McKee
相关产品推荐
相关产品推荐

