憋了一天終於憋出來了。
1.上午先測試了游標
declare
v_sql VARCHAR2(30);
CURSOR cur_test is select * from user_tables where table_name like '%2018%';
row_test cur_test%ROWTYPE;
BEGIN
OPEN cur_test;
FETCH cur_test into row_test;
WHILE cur_test%FOUND
LOOP
v_sql :='truncate table '||row_test.table_name;
dbms_output.put_line(v_sql);
execute immediate v_sql;
FETCH cur_test into row_test;
END LOOP;
close cur_test;
end;
/
可以打印並truncate表。
2.關於取表名的步驟搞了N久。表名主要有幾種,按天、周、月三種。比如table_2020_01_01這是按天的,table_2020_1這是按周的,table_2020_01這是按月的。
3.取三天前的表名
select table_name from user_tables
where table_name like '%2020%'
and regexp_like (table_name,'^[[:alpha:]]')
and length(regexp_replace(table_name,'[^0-9]',''))=8
and regexp_replace(table_name,'[^0-9]','')<to_char(sysdate-3,'YYYYMMDD');
4.最后把查詢的sql帶入游標中,truncate三天前的表名語句如下:
declare
v_sql VARCHAR2(30);
CURSOR cur_test is select table_name from user_tables where table_name like '%2020%' and regexp_like (table_name,'^[[:alpha:]]') and length(regexp_replace(table_name,'[^0-9]',''))=8 and regexp_replace(table_name,'[^0-9]','')<to_char(sysdate-3,'YYYYMMDD');
row_test cur_test%ROWTYPE;
BEGIN
OPEN cur_test;
FETCH cur_test into row_test;
WHILE cur_test%FOUND
LOOP
v_sql :='truncate table '||row_test.table_name;
dbms_output.put_line(v_sql);
execute immediate v_sql;
FETCH cur_test into row_test;
END LOOP;
close cur_test;
end;
/
總結:
還是思路問題,開始想是用regexp_like去匹配字母開頭,然后包含數字,還有下划線的,最后在判斷長度取類似2020_06_04或2020_06這樣的長度再判斷位數,長度為10位的就是按年月日來命名的表。后來無意中發現regexp_replace把下划線替換掉和字母替換掉(非數字替換掉),簡單多了。