将 Varchar2 转换为间隔

Posted

技术标签:

【中文标题】将 Varchar2 转换为间隔【英文标题】:Casting Varchar2 to interval 【发布时间】: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 是无效标识符

【问题讨论】:

【参考方案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 行错误,您似乎一直在使用名称。 好的,我想我找到了,我在间隔之后添加了“日到秒”,现在它可以工作了

以上是关于将 Varchar2 转换为间隔的主要内容,如果未能解决你的问题,请参考以下文章

如何在 SQL 中将 varchar2 转换为数字

如何将存储为 VARCHAR2 的日期转换为 'MM/DD/YYYY HH24:MI:SS'?

oracle数据库之如何将blob类型转换为varchar2

Oracle VIEW - 将 VARCHAR2 转换为 DATE 并找到 DATE 的 MIN/MAX

Oracle怎样把varchar2型转成number型

在Oracle资料中,怎么将VARCHAR2转化为NUMBER?