SAS警告:CREATETABLE语句递归引用目标表
SAS允许创建SAS警告:CREATETABLE语句递归引用目标表,sas,proc-sql,Sas,Proc Sql,SAS允许创建proc sqlcreate table语句,其中要创建的表在select语句中递归引用自身,例如: proc sql; create table t1 as select t1.id ,t2.val1 from t1 inner join t2 on t1.id=t2.id ; quit; 当执行这样的语句时,会向日志中写入一条警告消息 警告:此CREATETABLE语
proc sql
create table
语句,其中要创建的表在select语句中递归引用自身,例如:
proc sql;
create table t1 as
select
t1.id
,t2.val1
from
t1
inner join t2 on t1.id=t2.id
;
quit;
当执行这样的语句时,会向日志中写入一条警告消息
警告:此CREATETABLE语句递归引用目标表。这可能导致数据完整性问题。
使用undo\u policy=none
选项可以抑制此警告消息。(见附件)
问题:
- 以这种递归方式创建表可能会返回一些意外的结果吗?将同一操作分为两个步骤是否可能产生不同的结果:
proc sql; create table _data_ as select t1.id ,t2.val1 from t1 inner join t2 on t1.id=t2.id; create table t1 as select * from &syslast; quit;
- 两步法使用是否更好/更安全
data t1;
merge t1 t2;
by id;
run;
当SAS运行该类型的步骤时,它将首先使用结果创建一个新的物理文件,只有在该步骤完成后,它才会删除旧的t1.sas7bdat
,并将临时文件重命名为t1.sas7bdat
。如果使用PROC SQL语句,SAS将遵循相同的基本步骤
我认为警告是存在的,因为如果引用的表来自外部数据库系统(如Oracle),则SAS可能会将查询推入数据库,并在那里引发问题。我发现,使用与SAS proc sql输入和输出相同的表名可能会产生不正确的结果。它在大多数情况下工作正常,但绝对不是100%的时间。使用不同的输出表名称,而不是抑制警告
SAS承认了这一点:不知道您将从这个无效查询中“期望”得到什么结果,很难说它是否会返回“意外”结果。SAS proc sql不支持递归查询。@GordonLinoff-从我目前看到的情况来看,它产生的输出与两步方法相同,我不确定结果是否具有确定性。我继承了一些sas代码,我正在努力理解它。我认为这取决于使用的引擎。基本引擎(您在工作库中使用的)在后台创建一个临时数据集,然后在最后复制它。其他引擎可能不会这样做,因此发出警告。我也收到了这个警告,但我还没有看到任何异常结果。开发人员必须知道可能返回坏结果的非常具体的情况,并将免责声明放在以防万一的地方。我试着使一些最糟糕的递归sql语句成为可能,但没有得到错误的结果。就我个人而言,我会避免它。它可能在99.9999%的时间内工作,但是如果您使用的是关键数据,那么您需要绝对确保读/写操作在100%的时间内都能工作。如果您想这样做,我建议使用数据步骤。数据步骤确实支持这些递归更新操作等。如果将来确实出了问题,即使sql语句不是故障的确切原因,也要比“我忽略了这个警告,但这可能没有关系”更容易向上司解释。)谢谢你@tom的回答,这正是我所怀疑的。令我担忧的是警告消息中的一部分,该部分声明“这可能导致数据完整性问题”,并且可以使用“undo_policy=none”选项抑制警告消息。SAS文档并不十分清楚——至少从我所看到的情况来看——这种类型的语句何时可以安全使用,以及在哪些情况下会导致问题。如果它会导致数据完整性问题,那么首先为什么要允许它。