基本上想要删除Oracle表中的旧分区,目前在使用SUBSTR函数时遇到问题。
代码:
DECLARE
l_sql_stmt VARCHAR2(1000);
l_date DATE;
BEGIN
FOR x IN (SELECT *
FROM user_tab_partitions
WHERE table_name = 'TABLE_NAME')
LOOP
l_date := to_date( substr( x.high_value, 11, 19 ), 'YYYYMMDD' );
IF( l_date < add_months( trunc(sysdate), -15 ) )
THEN
l_sql_stmt := 'ALTER TABLE TABLE_NAME' || ' DROP PARTITION ' || x.partition_name;
dbms_output.put_line( l_sql_stmt );
EXECUTE IMMEDIATE l_sql_stmt;
END IF;
END LOOP;
END;
日期出现在&#34; HIGH_VALUE&#34;列中。
例如,分区的一个High_value = TO_DATE(' 1950-01-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')
我需要将日期存储在&#34; l_date&#34;变量,因此它可以用于进一步的计算。
错误:
ORA-01843:不是有效月份
ORA-06512:第9行
01843.00000 - &#34;不是有效月份&#34;
答案 0 :(得分:0)
如果high_value
等于以下(我认为您正在说的话):TO_DATE(' 1950-01-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')
,那么以下代码行是错误的:
l_date := to_date( substr( x.high_value, 11, 19 ), 'YYYYMMDD' );
错误的原因是掩码YYYYMMDD
错误。 SUBSTR( x.high_value, 11, 19)
将返回以下内容:
1950-01-01 00:00:00
所以你想用YYYY-MM-DD HH24:MI:SS
作为面具:
l_date := to_date( substr( x.high_value, 11, 19 ), 'YYYY-MM-DD HH24:MI:SS' );
或者SYYYY-MM-DD
(如high_value
本身所述),假设年份必须签名:
l_date := to_date( substr( x.high_value, 11, 19 ), 'SYYYY-MM-DD HH24:MI:SS' );
尝试从high_value
(例如,使用正则表达式)中提取掩码并使用它可能是值得的!
更新这将捕获掩码,假设high_value
具有相同的通用格式:
-- Try to capture the mask
WITH x AS (
SELECT 'TO_DATE('' 1950-01-01 00:00:00'', ''SYYYY-MM-DD HH24:MI:SS'', ''NLS_CALENDAR=GREGORIAN'')' AS high_value
FROM dual
)
SELECT REGEXP_SUBSTR(x.high_value, '[^'']+', INSTR(x.high_value, '''', 1, 3))
FROM x
因此,您可以在代码中使用以下内容:
l_date := TO_DATE( SUBSTR( x.high_value, 11, 19 ), REGEXP_SUBSTR( x.high_value, '[^'']+', INSTR( x.high_value, '''', 1, 3 ) ) );
希望这有帮助。