我需要通过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';
答案 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';