oracle 将Execute沿着与变量一起使用

rbl8hiat  于 2023-03-01  发布在  Oracle
关注(0)|答案(1)|浏览(142)

我有一个语句,它将原始表和备份数据之间的差异计数插入到表中

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条记录

iugsix8n

iugsix8n1#

即使已经定义了这些变量,也不需要INTO SUPP_QUARTER using QT--错误表明您至少还没有定义QT
该语句似乎没有任何绑定变量,因此无法通过using提供任何内容。但您在语句中嵌入了SUPP_QUARTER,这可能会带来SQL注入风险,因此如果需要,* 应该 * 成为绑定变量,但您似乎试图不这样做。而且它是一个插入语句,不返回任何内容。所以也不需要给into一个变量因为它和你要嵌入的是同一个变量,看起来可能有点混乱。
insert ... select ...语法不关心在select部分中列的名称,它将使用插入的每个列的匹配位置中的值(使用关键字或函数名(如TYPECOUNT)作为列名并不理想,在某些时候可能会引起混淆......)
当你被迫使用动态SQL时,首先获得一个可以工作的静态版本,然后转换它通常是很有帮助的。
作为一个静态语句,SUPP_QUARTER为固定值'Q1',表名的动态部分为'230222',并删除...和一个额外的from,它看起来如下所示:

INSERT INTO LOG_table (TABLE_NAME, TYPE, COUNT, QUARTER) 
SELECT NAME,TYPE,COUNT,QUARTER
FROM (
  SELECT COUNT(*) COUNT, 'table_name' NAME, 'A-B' TYPE, 'Q1' QUARTER
  FROM (
    SELECT COL1, COL2, TO_CHAR(TO_DATE(SOMENUMBER, 'YYYYMM'), 'YYYY"-Q"Q') AS QT
    FROM DW.W_SUPPL_SNAPSHOT_CONTROL_G
    MINUS
    SELECT COL1, COL2, TO_CHAR(TO_DATE(SOMENUMBER, 'YYYYMM'), 'YYYY"-Q"Q') AS QT
    FROM SCRATCH.W_SUPPL_SNAPSHOT_CONTROL_G_DLY_BKP_230222
  )
  UNION ALL
  SELECT COUNT(*), 'TABLE_NAME', 'B-A', 'Q1' 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_230222
    MINUS
    SELECT COL1, COL2, TO_CHAR(TO_DATE(SOMENUMBER, 'YYYYMM'), 'YYYY"-Q"Q') AS QT 
    FROM DW.W_SUPPL_SNAPSHOT_CONTROL_G
  )
)

实际上并不需要这两级子查询,如果你想使用内部查询中的QT值,那么在选择列表中引用它而不是SUPP_QUARTER,并在每个分支中为它添加一个group-by子句:

INSERT INTO LOG_table (COUNT, TABLE_NAME, TYPE, QUARTER)
SELECT COUNT(*) COUNT, 'table_name' NAME, 'A-B' TYPE, QT QUARTER
FROM (
  SELECT COL1, COL2, TO_CHAR(TO_DATE(SOMENUMBER, 'YYYYMM'), 'YYYY"-Q"Q') AS QT
  FROM DW.W_SUPPL_SNAPSHOT_CONTROL_G
  MINUS
  SELECT COL1, COL2, TO_CHAR(TO_DATE(SOMENUMBER, 'YYYYMM'), 'YYYY"-Q"Q') AS QT
  FROM SCRATCH.W_SUPPL_SNAPSHOT_CONTROL_G_DLY_BKP_230222
)
GROUP BY QT
UNION ALL
SELECT COUNT(*), 'TABLE_NAME', 'B-A', QT
FROM (
  SELECT COL1, COL2, TO_CHAR(TO_DATE(SOMENUMBER, 'YYYYMM'), 'YYYY"-Q"Q') AS QT
  FROM SCRATCH.W_SUPPL_SNAPSHOT_CONTROL_G_DLY_BKP_230222
  MINUS
  SELECT COL1, COL2, TO_CHAR(TO_DATE(SOMENUMBER, 'YYYYMM'), 'YYYY"-Q"Q') AS QT 
  FROM DW.W_SUPPL_SNAPSHOT_CONTROL_G
)
GROUP BY QT

它不再使用SUPP_QUARTER,但这似乎是你想要的,你没有使用COL1COL2,但我把它们留在里面了--你可能在你真实的的查询中,如果它们是投影的,那么你也需要按它们分组。
外部查询中不需要列别名,插入操作也不需要列别名,但您可能希望将列别名保留在那里,以便于独立运行查询。
然后可以将其转换为动态SQL,以便将变量备份表后缀添加回去;使用另一种引用语法会更容易阅读和维护:

execute immediate q'^INSERT INTO LOG_table (COUNT, TABLE_NAME, TYPE, QUARTER)
SELECT COUNT(*) COUNT, 'table_name' NAME, 'A-B' TYPE, QT QUARTER
FROM (
  SELECT COL1, COL2, TO_CHAR(TO_DATE(SOMENUMBER, 'YYYYMM'), 'YYYY"-Q"Q') AS QT
  FROM DW.W_SUPPL_SNAPSHOT_CONTROL_G
  MINUS
  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') || q'^
)
GROUP BY QT
UNION ALL
SELECT COUNT(*), 'TABLE_NAME', 'B-A', QT
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') || q'^
  MINUS
  SELECT COL1, COL2, TO_CHAR(TO_DATE(SOMENUMBER, 'YYYYMM'), 'YYYY"-Q"Q') AS QT 
  FROM DW.W_SUPPL_SNAPSHOT_CONTROL_G
)
GROUP BY QT^';

fiddle

相关问题