如何 select 仅 pl/sql 中应截断的分区
How to select only the partitions that should be truncated in pl/sql
给定 2 个具有值的变量:
v_days1 = 30
v_days2 = 367
以及来自 ALL_TAB_PARTITIONS
的以下分区:
TABLE_NAME PARTITION_NAME HIGH_VALUE (LONG datatype)
TABLENAME partitionname1_P30 30
TABLENAME partitionname2_P60 60
TABLENAME partitionname3_P90 90
TABLENAME partitionname4_P120 120
TABLENAME partitionname5_P150 150
TABLENAME partitionname6_P180 180
TABLENAME partitionname7_210 210
TABLENAME partitionname8_P240 240
TABLENAME partitionname9_P270 270
TABLENAME partitionname10_P300 300
TABLENAME partitionname11_P330 330
TABLENAME partitionname12_P360 367
如何将all_tab_partitions
中不等于v_days1
和v_days2
的selectHIGH_VALUE
截断对应的分区?
对于此示例,将分区 partitionname2_P60
截断为 partitionname11_P330
。
FOR rec IN (SELECT TABLE_NAME, PARTITION_NAME, HIGH_VALUE
FROM ALL_TAB_PARTITIONS
WHERE TABLE_NAME='TABLENAME'
AND HIGH_VALUE NOT IN (v_days1, v_days2) LOOP
<TRUNCATE PARTITIONS WITH HIGH_VALUE 60 TO 333
/TRUNCATE PARTITIONS WITH HIGH_VALUE NOT EQUAL TO 30 AND 367>
因为 high_value
数据类型是 Long
你不能直接在 where
子句中使用它。需要先隐蔽成lob
才能使用。然而,在这种情况下,它变得难以使用,因为您必须在一个数字范围之间查找。因此,您可以稍微修改解决方案并实现您的要求,如下所示;
DECLARE
v_days1 varchar2(10) := '20';
v_days2 varchar2(10) := '367';
l_var VARCHAR2(32767);
v_sql VARCHAR2(100);
BEGIN
FOR rec IN
(SELECT table_name,
partition_name,
high_value
FROM all_tab_partitions
WHERE TABLE_NAME='TABLENAME'
--WHERE high_value NOT IN ( v_days1)
)
LOOP
l_var:=rec.high_value;
--dbms_output.put_line('partition Name'||rec.partition_name);
--IF l_var between '20' and '367' THEN
IF (l_var NOT IN (v_days1 ,v_days2)) THEN
dbms_output.put_line('partition Name'||rec.partition_name);
v_sql:= 'ALTER TABLE '||rec.table_name||' TRUNCATE PARTITION '||rec.partition_name ;
EXECUTE immediate v_sql ;
END IF;
END LOOP;
END;
给定 2 个具有值的变量:
v_days1 = 30
v_days2 = 367
以及来自 ALL_TAB_PARTITIONS
的以下分区:
TABLE_NAME PARTITION_NAME HIGH_VALUE (LONG datatype)
TABLENAME partitionname1_P30 30
TABLENAME partitionname2_P60 60
TABLENAME partitionname3_P90 90
TABLENAME partitionname4_P120 120
TABLENAME partitionname5_P150 150
TABLENAME partitionname6_P180 180
TABLENAME partitionname7_210 210
TABLENAME partitionname8_P240 240
TABLENAME partitionname9_P270 270
TABLENAME partitionname10_P300 300
TABLENAME partitionname11_P330 330
TABLENAME partitionname12_P360 367
如何将all_tab_partitions
中不等于v_days1
和v_days2
的selectHIGH_VALUE
截断对应的分区?
对于此示例,将分区 partitionname2_P60
截断为 partitionname11_P330
。
FOR rec IN (SELECT TABLE_NAME, PARTITION_NAME, HIGH_VALUE
FROM ALL_TAB_PARTITIONS
WHERE TABLE_NAME='TABLENAME'
AND HIGH_VALUE NOT IN (v_days1, v_days2) LOOP
<TRUNCATE PARTITIONS WITH HIGH_VALUE 60 TO 333
/TRUNCATE PARTITIONS WITH HIGH_VALUE NOT EQUAL TO 30 AND 367>
因为 high_value
数据类型是 Long
你不能直接在 where
子句中使用它。需要先隐蔽成lob
才能使用。然而,在这种情况下,它变得难以使用,因为您必须在一个数字范围之间查找。因此,您可以稍微修改解决方案并实现您的要求,如下所示;
DECLARE
v_days1 varchar2(10) := '20';
v_days2 varchar2(10) := '367';
l_var VARCHAR2(32767);
v_sql VARCHAR2(100);
BEGIN
FOR rec IN
(SELECT table_name,
partition_name,
high_value
FROM all_tab_partitions
WHERE TABLE_NAME='TABLENAME'
--WHERE high_value NOT IN ( v_days1)
)
LOOP
l_var:=rec.high_value;
--dbms_output.put_line('partition Name'||rec.partition_name);
--IF l_var between '20' and '367' THEN
IF (l_var NOT IN (v_days1 ,v_days2)) THEN
dbms_output.put_line('partition Name'||rec.partition_name);
v_sql:= 'ALTER TABLE '||rec.table_name||' TRUNCATE PARTITION '||rec.partition_name ;
EXECUTE immediate v_sql ;
END IF;
END LOOP;
END;