0

我需要通过选择查询获取多个值并放入单个变量中,然后将该变量的值与另一个只有单个值的变量进行比较。

我是 PL/SQL 编程的新手。我已经搜索了这个论坛并获得了使用 TYPE/ 集合的结果,但不确定如何在我的代码中使用它。

下面是我的代码片段:

CREATE OR REPLACE PROCEDURE MNTH_SNAPSHOT AS
  arg1 varchar2(10) ;
  TYPE snap IS TABLE OF GDWARC_JPN.DIM_ORG_UNIT_HIST.snapshot_period%TYPE;
BEGIN 
  SELECT (to_char(trunc(sysdate, 'MM'), 'MON-yyyy')) INTO arg1 FROM dual; 
  SELECT (to_char(snapshot_period,'MON-yyyy')) BULK collect into snap FROM GDWARC_JPN.DIM_ORG_UNIT_HIST; -- multiple values like DEC-2016, JAN-2016 etc . snapshot_period is date column 

  if arg1 in (snap ) then
    execute immediate 'alter table GDWARC_JPN.DIM_ORG_UNIT_HIST truncate partition arg1';
4

3 回答 3

0

我无法发表评论,所以我会写新的回复

感谢 Prabhat,您的代码编译得很好,但是当我尝试运行 proc 时,它抛出错误:错误报告 - ORA-01858:在预期数字的地方找到了非数字字符 ORA-06512:在“GDWARC_JPN.MNTH_SNAPSHOT”,第 9 行 ORA-06512:在第 1 行 01858. 00000 -“在需要数字的地方发现了一个非数字字符”你能帮忙吗?

您的问题是您使用不同的数据类型。

SELECT (to_char(snapshot_period,'MON-yyyy')) BULK collect into snap_tab/*changed*/ FROM GDWARC_JPN.DIM_ORG_UNIT_HIST;

首先,您使用日期,将其转换为字符,然后再次将其保存为日期。不知道你怎么能编译这个

SELECT (to_char(trunc(sysdate, 'MM'), 'MON-yyyy')) INTO arg1 FROM dual; 

当您将 sysdate 转换为所需的格式并将其保存到 varchar 变量时,它不再是日期。然后你将它与日期进行比较,因为你在日期上有你的格式,所以它不能被识别。因此,要么在所有变量中使用日期,要么使用 TRUNC 选项从中提取月份和年份(尽管我不确定你是否可以将表的成员转换为成员,也许你需要在这种情况下使用 for)或打开 snap表到 varchar 类型

例子

CREATE OR REPLACE PROCEDURE MNTH_SNAPSHOT AS
  arg1 varchar2(10) ;
  TYPE snap IS TABLE OF varchar2(10);
  snap_tab snap := snap() ; --declare a new collection variable and use this 
BEGIN 
  SELECT (to_char(trunc(sysdate, 'MM'), 'MON-yyyy')) INTO arg1 FROM dual; 
  SELECT (to_char(snapshot_period,'MON-yyyy')) BULK collect into snap_tab/*changed*/ FROM GDWARC_JPN.DIM_ORG_UNIT_HIST; -- multiple values like DEC-2016, JAN-2016 etc . snapshot_period is date column 

  if arg1 member of snap_tab /*changed*/ then
    execute immediate 'alter table GDWARC_JPN.DIM_ORG_UNIT_HIST truncate partition arg1';
于 2016-12-10T00:16:55.193 回答
0

您可以使用 Member of 子句来测试元素是否是集合的一部分

    if some_value member of arg1 then 
`      dbms_output.put_line('Member') ;
    end if ;

您发布的代码在声明和使用集合变量方面存在一些问题,以下是更正确的版本。

CREATE OR REPLACE PROCEDURE MNTH_SNAPSHOT AS
  arg1 varchar2(10) ;
  TYPE snap IS TABLE OF GDWARC_JPN.DIM_ORG_UNIT_HIST.snapshot_period%TYPE;
  snap_tab snap := snap() ; --declare a new collection variable and use this 
BEGIN 
  SELECT (to_char(trunc(sysdate, 'MM'), 'MON-yyyy')) INTO arg1 FROM dual; 
  SELECT (to_char(snapshot_period,'MON-yyyy')) BULK collect into snap_tab/*changed*/ FROM GDWARC_JPN.DIM_ORG_UNIT_HIST; -- multiple values like DEC-2016, JAN-2016 etc . snapshot_period is date column 

  if arg1 member of snap_tab /*changed*/ then
    execute immediate 'alter table GDWARC_JPN.DIM_ORG_UNIT_HIST truncate partition arg1';
于 2016-12-09T07:28:36.143 回答
0

您可以简单地使用循环来检查从查询返回的所有值:

CREATE OR REPLACE PROCEDURE MNTH_SNAPSHOT AS
  arg1 varchar2(10) ;
BEGIN 
  arg1 := to_char(sysdate,'MON-yyyy'); /* you do not need to trunc and/or a query here */
  --
  /* you can use a loop to scan all your values */
  for i in (
              SELECT (to_char(snapshot_period,'MON-yyyy')) val
              FROM GDWARC_JPN.DIM_ORG_UNIT_HIST
           )
  loop
      if i.val = arg1 then
        /* arg1 must be out of the fixed string */
        execute immediate 'alter table GDWARC_JPN.DIM_ORG_UNIT_HIST truncate partition ' || arg1;
      end if;
  end loop;
end;  

但是,您的代码似乎遍历了一个表,但您只截断了与 sysdate 对应的分区;因此,您的代码可以简化:

CREATE OR REPLACE PROCEDURE MNTH_SNAPSHOT AS
  arg1 varchar2(10) ;
  vCheck number;
BEGIN 
  arg1 := to_char(sysdate,'MON-yyyy'); /* you do not need to trunc and/or a query here */
  /* you only need to check whether a value for sysdate exists or not */
  select count(1)
  into vCheck
  from GDWARC_JPN.DIM_ORG_UNIT_HIST
    where to_char(snapshot_period,'MON-yyyy') = arg1;
  --
  if vCheck > 0 then
          /* arg1 must be out of the fixed string */
          execute immediate 'alter table GDWARC_JPN.DIM_ORG_UNIT_HIST truncate partition ' || arg1;
  end if;
end;  

另外,请注意,您不需要varchar2检查日期,但您可以简单地trunc将它们都设置为月份并检查结果,trunc并且动态字符串中有错误,因为它arg1应该是一个变量值,而不是硬编码到字符串中.

于 2016-12-09T08:39:49.617 回答