我有一个语句,它将原始表和备份数据之间的差异计数插入到表中
EXECUTE IMMEDIATE 'INSERT INTO LOG_table (TABLE_NAME,TYPE,COUNT,QUARTER)
SELECT NAME,TYPE,COUNT,QUARTER FROM (SELECT COUNT(*) COUNT,''table_name'' NAME,''A-B'' TYPE,'''||SUPP_QUARTER||''' QUARTER FROM(
SELECT COL1 ,COL2 ... TO_CHAR(TO_DATE(SOMENUMBER,''YYYYMM''),''YYYY"-Q"Q'') AS QT FROM TABLE
MINUS
SELECT COL1 ,COL2 ... TO_CHAR(TO_DATE(SOMENUMBER,''YYYYMM''),''YYYY"-Q"Q'') AS QT FROM BACKUP_TABLE)
UNION ALL
SELECT COUNT(*),''TABLE_NAME'',''B-A'','''||SUPP_QUARTER||''' QUARTER FROM
(SELECT COL1 ,COL2 ... TO_CHAR(TO_DATE(SOMENUMBER,''YYYYMM''),''YYYY"-Q"Q'') AS QT FROM SCRATCH.W_SUPPL_SNAPSHOT_CONTROL_G_DLY_BKP_'||TO_CHAR(LATEST_DATE_VALUE,'YYMMDD') ||'
MINUS
SELECT COL1 ,COL2 ... TO_CHAR(TO_DATE(SOMENUMBER,''YYYYMM''),''YYYY"-Q"Q'') AS QT FROM FROM DW.W_SUPPL_SNAPSHOT_CONTROL_G)' INTO SUPP_QUARTER using QT
;
END;
当我运行这个程序时,我得到:* * PLS-00201:必须声明标识符"QT"**
因此,我的问题是如何将QT插入LOG_TABLE。
如果我不这样做,并从select语句本身选择季度,我会得到"not group by statement",这是正确的。
有什么办法可以做到吗?
同时表只有60条记录
1条答案
按热度按时间iugsix8n1#
即使已经定义了这些变量,也不需要
INTO SUPP_QUARTER using QT
--错误表明您至少还没有定义QT
。该语句似乎没有任何绑定变量,因此无法通过
using
提供任何内容。但您在语句中嵌入了SUPP_QUARTER
,这可能会带来SQL注入风险,因此如果需要,* 应该 * 成为绑定变量,但您似乎试图不这样做。而且它是一个插入语句,不返回任何内容。所以也不需要给into
一个变量因为它和你要嵌入的是同一个变量,看起来可能有点混乱。insert ... select ...
语法不关心在select
部分中列的名称,它将使用插入的每个列的匹配位置中的值(使用关键字或函数名(如TYPE
和COUNT
)作为列名并不理想,在某些时候可能会引起混淆......)当你被迫使用动态SQL时,首先获得一个可以工作的静态版本,然后转换它通常是很有帮助的。
作为一个静态语句,
SUPP_QUARTER
为固定值'Q1',表名的动态部分为'230222',并删除...
和一个额外的from
,它看起来如下所示:实际上并不需要这两级子查询,如果你想使用内部查询中的
QT
值,那么在选择列表中引用它而不是SUPP_QUARTER
,并在每个分支中为它添加一个group-by子句:它不再使用
SUPP_QUARTER
,但这似乎是你想要的,你没有使用COL1
或COL2
,但我把它们留在里面了--你可能在你真实的的查询中,如果它们是投影的,那么你也需要按它们分组。外部查询中不需要列别名,插入操作也不需要列别名,但您可能希望将列别名保留在那里,以便于独立运行查询。
然后可以将其转换为动态SQL,以便将变量备份表后缀添加回去;使用另一种引用语法会更容易阅读和维护:
fiddle