2015-01-13 43 views
0

基本上想要删除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; 

日期存在于列 “HIGH_VALUE”。 例如其中一个分区的High_value = TO_DATE(' 1950-01-01 00:00:00', 'SYYYY-MM-DD HH24:MI:SS', 'NLS_CALENDAR=GREGORIAN')

我需要将日期存储在“l_date”变量中,因此它可以用于进一步的计算。

错误:

ORA-01843:不是有效的月份

ORA-06512:在第9行

01843.00000 - “不是有效的月”

+3

你有什么问题?它是否会运行,如果是这样,那么结果与您期望的结果有什么区别? – DaaaahWhoosh

+1

您是否在转换整个输入字符串之前获得“ORA-01830:日期格式图片结束”? substr参数和格式模型对于日期分区看起来是错误的;你期望什么原始的高价值? –

回答

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(使用,例如,正则表达式)并使用它!

UPDATE这将致力于捕捉面具,假设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))); 

希望这有助于。

+0

对不起,在这个回复中,延迟了,谢谢你的建议代码,它按我想要的方式工作。 – Lastwish