我创建了以下过程,仅保留了最近两个月的数据,并针对oracle中的表删除了其余的数据,下面是该过程,但是我遇到了异常,请建议如何克服这一点
create or replace package TEST_TABLE AS
PROCEDURE TEST_TABLE;
END TEST_TABLE;
create or replace PACKAGE BODY TEST_TABLE AS
PROCEDURE TEST_TABLE IS
BEGIN
FOR cc IN
(
SELECT partition_name, high_value
FROM user_tab_partitions
WHERE table_name = 'TEST_TABLE'
)
LOOP
BEGIN
IF sysdate >= ADD_MONTHS(cc.high_value,2) THEN
EXECUTE IMMEDIATE
'ALTER TABLE TEST_TABLE DROP PARTITION ' || cc.partition_name;
Dbms_Output.Put_Line('Dropping partition is completed.');
END IF;
END;
END LOOP;
EXCEPTION WHEN Others THEN Dbms_Output.Put_Line( SQLERRM );
END TEST_TABLE;
END TEST_TABLE;
我得到的错误是:
错误(12,6):PL / SQL:语句已忽略
错误(12,20):PLS-00306:调用“ ADD_MONTHS”时参数的数量或类型错误
答案 0 :(得分:2)
首先,像您没有其他名称一样,用TEST_TABLE
来调用表名,包名和过程名都是很疯狂的。我已经给它们起了适当的名字。
HIGH_VALUE
不能直接用于DATE
类型的LONG
相关功能中。有一种简单的方法可以使用动态SQL(EXECUTE IMMEDIATE
)将其转换为日期
CREATE OR replace PACKAGE BODY PKG_test_table AS
PROCEDURE pr_test_table
IS
v_high_value DATE;
BEGIN
FOR cc IN (
SELECT partition_name,
high_value
FROM user_tab_partitions
WHERE table_name = 'TEST_TABLE'
) LOOP
BEGIN
EXECUTE IMMEDIATE 'BEGIN :v_high_val := '|| cc.high_value || '; END;'
USING OUT v_high_value;
IF
SYSDATE >= add_months(v_high_value,2)
THEN
EXECUTE IMMEDIATE 'ALTER TABLE TEST_TABLE DROP PARTITION '
|| cc.partition_name;
dbms_output.put_line('Dropping partition is completed.');
END IF;
END;
END LOOP;
EXCEPTION
WHEN OTHERS THEN
dbms_output.put_line(sqlerrm);
END pr_TEST_TABLE;
END PKG_test_table;
/
调用过程
BEGIN
PKG_test_table.pr_test_table;
END;
/
答案 1 :(得分:0)
您的过程不接受任何参数。您不能向其传递任何参数。
答案 2 :(得分:0)
USER_TAB_PARTITIONS中的HIGH_VALUE列是一个长数据类型,我不会从另一个网站复制代码,但是如果您使用google“ oracle将高价值转换为日期”,则应该了解如何创建一个函数来您可以用来将“长”转换为日期。
我的声誉太低,无法将其发布为评论,因此我将其添加为答案,尽管它不是一个好的答案,它应该有所帮助:(
答案 3 :(得分:0)
正如错误所述,所有ADD_MONTHS都需要一个DATE,而您是以LONG身份传递的。
尝试类似的方法,应该没问题。
示例:
DECLARE
DT LONG(1000) := 'TO_DATE('||''''||'2018-08-01 00:00:00'||''''||',' ||''''|| 'SYYYY-MM-DD HH24:MI:SS'||''''||','||''''||'NLS_CALENDAR=GREGORIAN'||''''||')';
BEGIN
DBMS_OUTPUT.PUT_LINE(DT);
EXECUTE IMMEDIATE
'BEGIN
DBMS_OUTPUT.PUT_LINE(TO_CHAR(ADD_MONTHS('||DT||',2),'||''''||'YYYY-MM-DD HH24:MI:SS'||''''||
')); END;';
END;
输出:
TO_DATE('2018-08-01 00:00:00','SYYYY-MM-DD HH24:MI:SS','NLS_CALENDAR=GREGORIAN')
2018-10-01 00:00:00
答案 4 :(得分:0)
Oracle不允许长时间使用诸如cast,substr,add_months之类的函数,但是…请阅读下文。
长型
描述user_tab_partitions;
...
SUBPARTITION_COUNT个NUMBER
HIGH_VALUE LONG
HIGH_VALUE_LENGTH NUMBER
...
将long转换为varchar2的函数
FUNCTION long_to_varchar2(p_table_owner输入VARCHAR2,p_table_name输入VARCHAR2,p_partition_name输入VARCHAR2)返回VARCHAR2 是 l_tmp长; 开始
选择高值 进入l_tmp 来自all_tab_partitions 其中table_owner = p_table_owner 和table_name = p_table_name 和partition_name = p_partition_name;
返回l_tmp; END long_to_varchar2;
3。使用新功能
select tpar."OWNER",tpar."TABLE_NAME",tpar."PART_MIN",tpar."PART_MIN_HV",tpar."PART_MAX",tpar."PART_MAX_HV",tpar."NR_PART"
,pkey.column_name as partitioned_by
,ptab.partitioning_type as partition_type
,ptab.status
from
(select p1.table_owner as owner
,p1.table_name
,pmin.partition_name as part_min
,to_date(substr(long_to_varchar2(p1.table_owner,p1.table_name,pmin.partition_name),11,10),'yyyy-mm-dd') as part_min_hv
,pmax.partition_name as part_max
,to_date(substr(long_to_varchar2(p1.table_owner,p1.table_name,pmax.partition_name),11,10),'yyyy-mm-dd') as part_max_hv
,p1.nr_part+1 as nr_part
from (select min(part.partition_position) as minp
,max(part.partition_position) as maxp
,count(*) as nr_part
,part.table_name
,part.table_owner
from all_tab_partitions part,
dba_tables tbls
where part.table_name=tbls.table_name
and part.table_owner=tbls.owner
and part.PARTITION_NAME <> 'P_CURRENT'
group by part.table_name, part.table_owner) p1
,all_tab_partitions pmin
,all_tab_partitions pmax
where p1.table_name = pmin.table_name
and p1.table_owner = pmin.table_owner
and p1.minp=pmin.partition_position
and p1.table_name = pmax.table_name
and p1.table_owner = pmax.table_owner
and p1.maxp = pmax.partition_position) tpar
,ALL_PART_KEY_COLUMNS pkey
,ALL_PART_TABLES ptab
where tpar.owner=pkey.owner
and tpar.table_name=pkey.name
and tpar.owner=ptab.owner
and tpar.table_name=ptab.table_name
and pkey.object_type='TABLE';
唯一的问题是您将执行隐式varchar2到日期的转换,否则我看不到任何方法。