从字符串中提取日期的一部分

Extracting a portion of a date from a string

基本上想删除 Oracle table 中的旧分区,目前在使用 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 - "not a valid month"

如果 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) 将 return 以下内容:

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 ) ) );

希望这对您有所帮助。