【问题标题】:Casting Varchar2 to interval将 Varchar2 转换为间隔
【发布时间】:2014-04-04 16:57:58
【问题描述】:

我有一个配置表,如果 record_tm 超过某个可配置时间 (config_recordtrim_hrs),我想删除一行。换句话说,变量 recordtrim_config 来自另一个表,其中有人写入了一个值(例如 24 表示 24 小时),之后将删除一条记录。

DECLARE
recordtrim_flag configs_table.value%type;
recordtrim_config configs_table.value%type;
recordtrim_interval interval;
BEGIN
SELECT configs_table.value INTO recordtrim_flag FROM configs_table WHERE configs_table.name = 'enable_recordtrim';
SELECT configs_table.value INTO recordtrim_config FROM configs_table WHERE configs_table.name = 'config_recordtrim_hrs';
SELECT CAST (recordtrim_config AS interval) INTO recordtrim_interval;

IF (recordtrim_flag = 'T') THEN
DELETE FROM main_records WHERE record_tm + recordtrim_interval < current_timestamp;
END IF;
END;

此代码在我尝试将 recordtrim_config 强制转换为间隔的行处引发错误。我该如何解决这个问题?

编辑:我的错误:

错误报告:ORA-06550:第 8 行,第 40 列:PL/SQL:ORA-30089:缺失 或无效的 ORA-06550:第 8 行,第 1 列:PL/SQL:SQL 语句被忽略

编辑 2:新代码:

DECLARE
recordtrim_flag configs_table.value%type;
recordtrim_config configs_table.value%type;
recordtrim_interval interval;
BEGIN
SELECT configs_table.value INTO recordtrim_flag FROM configs_table WHERE configs_table.name = 'enable_recordtrim';
SELECT configs_table.value INTO recordtrim_config FROM configs_table WHERE configs_table.name = 'config_recordtrim_hrs';
recordtrim_interval := NUMTODSINTERVAL (recordtrim_config, 'HOUR');

IF (recordtrim_flag = 'T') THEN
DELETE FROM main_records WHERE record_tm + recordtrim_interval < current_timestamp;
END IF;
END;

第 11 行出现新错误,recordtrim_interval 是无效标识符

【问题讨论】:

    标签: oracle plsql


    【解决方案1】:

    错误的直接原因是您只有interval 而不是类型,即interval day to second。您还必须从某处select - 在这里可以是from dual,尽管直接分配更干净。

    如果是单个数字,则不能直接投射。相反,您可以使用numtodsinterval function:

    recordtrim_interval := NUMTODSINTERVAL (recordtrim_config, 'HOUR');
    

    例如

    set serveroutput on
    declare
      recordtrim_config varchar2(4) := '24';
      recordtrim_interval interval day to second;
    begin
      recordtrim_interval := NUMTODSINTERVAL (recordtrim_config, 'HOUR');
      dbms_output.put_line(recordtrim_interval);
    end;
    /
    
    anonymous block completed
    +01 00:00:00.000000
    

    或者直接从表中选择变量。

    如果您需要更复杂的值,而不是表示小时数的简单值 - 如果是这种情况,您会将其存储为我假设的数字 - 那么如果您以合适的格式存储它,您可以投射它,或者改用to_dsinterval function;其中任何一个都会给出相同的结果:

    declare
      recordtrim_config varchar2(10) := '0 2:30:00';
      recordtrim_interval interval day to second;
    begin
      recordtrim_interval := TO_DSINTERVAL (recordtrim_config);
      dbms_output.put_line(recordtrim_interval);
      SELECT CAST (recordtrim_config AS interval day to second)
      INTO recordtrim_interval from dual;
      dbms_output.put_line(recordtrim_interval);
      recordtrim_interval := CAST (recordtrim_config AS interval day to second);
      dbms_output.put_line(recordtrim_interval);
    end;
    /
    
    anonymous block completed
    +00 02:30:00.000000
    +00 02:30:00.000000
    +00 02:30:00.000000
    

    在您编辑的问题中,ORA-00904: "RECORDTRIM_INTERVAL": invalid identifier 只是列表中的最后一个错误。回头看一下,你会发现:

    ORA-06550: line 4, column 21:
    PLS-00201: identifier 'INTERVAL' must be declared
    

    ... 在您尝试使用该变量时出现其他一些错误。您对变量的声明必须是:

    recordtrim_interval interval day to second;
    

    没有'interval'数据类型; they are interval year to month and interval day to second.

    【讨论】:

    • 我用错误更新了原始帖子。即使 recordtrim_config 在技术上是 varchar2 而不是数字,这种方法是否有效?
    • 另外,当我输入时,我的错误现在在第 11 行,说 recordtrim_interval 是无效标识符
    • 我现在的问题是如何在第 11 行使用 recordtrim_interval。我想在记录中的时间戳加上 recordtrim_interval 小于 current_timestamp 时删除记录
    • @KyleGrage - 如果它是一个包含单个数字(例如 24)的 varchar2 ,它会起作用,因为它会隐含地显示正确的类型 - 这就是我的示例正在做的事情。我还添加了更灵活的castto_dsinterval 选项,但它们要求您的配置值采用严格的格式。不过不明白您的第 11 行错误,您似乎一直在使用名称。
    • 好的,我想我找到了,我在间隔之后添加了“日到秒”,现在它可以工作了
    猜你喜欢
    • 1970-01-01
    • 2021-10-03
    • 2011-02-11
    • 1970-01-01
    • 2021-06-16
    • 2013-10-29
    • 1970-01-01
    • 1970-01-01
    • 2020-12-20
    相关资源
    最近更新 更多