Oracle派生列基于表达式结果

时间:2012-07-10 15:21:37

标签: oracle plsql oracle10g

有没有办法根据10g中的表达式结果创建派生列?

具体来说,我继承了一个包含varchar2字段中的字符数据和数字数据的表。显然,在尝试连接时,这不会导致头痛,因为我经常得到"无效数字" Oracle重新排序我在字段上使用to_number()的查询时出错。所以,我想要做的是创建一个派生列,如果原始列的值是数字,则该值具有值;如果不是,则为NULL,并且在连接中使用该值而不是具有混合类型的字段

请注意,我尝试在查询中执行此操作,而不是在过程/函数中执行此操作。

这样的事情可能吗?

3 个答案:

答案 0 :(得分:3)

在Oracle 11g中,您可以定义virtual columns

ALTER TABLE mytable ADD (new_column GENERATED ALWAYS AS (CASE WHEN id ...));

在10g之前我建议使用视图:

CREATE VIEW myview AS SELECT t.*, CASE WHEN ... END id_number FROM mytable;

您甚至可以使用基于函数的性能索引来索引表达式(只要您只使用SQL标准函数和确定性自定义函数):

CREATE INDEX idx ON mytable (CASE WHEN ...);

答案 1 :(得分:2)

10g中最接近的是基于函数的索引。像

这样的东西
CREATE OR REPLACE FUNCTION my_to_number( p_str IN VARCHAR2 )
  RETURN NUMBER
  DETERMINISTIC
IS
  l_num NUMBER;
BEGIN
  l_num := to_number( p_str );
  RETURN l_num;
EXCEPTION
  WHEN OTHERS THEN
    RETURN NULL;
END;

CREATE INDEX idx_derived_column
    ON table_name( my_to_number( column_name ) );

这通常要求在查询中创建和引用函数,但基于函数的索引预先计算结果,因此您不会在运行时实际调用该函数。如果你真的想要避开这个函数,你也可以在CASE语句中创建索引,然后在查询中引用相同的CASE语句,但这似乎会使情况复杂化,而不是简单。

答案 2 :(得分:1)

可以使用正则表达式:

select * from table where varchar_field not like '%[0-9]%';