在单个变量中获取多个值,并使用它与另一个变量

时间:2016-12-09 05:35:29

标签: oracle stored-procedures plsql select-into

我需要通过select查询和单个变量获取多个值,然后将该变量的值与另一个只具有单个值的变量进行比较。

我是PL / SQL编程的新手。我搜索了这个论坛,得到了使用TYPE / collections的结果,但不知道如何在我的代码中使用相同的。

以下是我的代码片段:

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';

3 个答案:

答案 0 :(得分: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';

答案 1 :(得分: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应该是变量值,而不是硬编码到字符串中。

答案 2 :(得分:0)

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

  

谢谢Prabhat,你的代码编译得很好但是当我尝试运行时   proc,它抛出错误为:错误报告 - ORA-01858:非数字   字符被发现数字是预期的ORA-06512:at   " 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;

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

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

当您将sysdate转换为所需格式并将其保存到varchar变量时,它不再是日期。然后,您将其与日期进行比较,因为您在日期上有格式,所以无法识别。 因此,要么在所有变量中使用日期,要么使用TRUNC选项从中提取月份和年份(虽然我不确定你是否可以在成员中加入表格的成员,也许你在这种情况下需要使用)或将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';