有没有办法根据10g中的表达式结果创建派生列?
具体来说,我继承了一个包含varchar2字段中的字符数据和数字数据的表。显然,在尝试连接时,这不会导致头痛,因为我经常得到"无效数字" Oracle重新排序我在字段上使用to_number()的查询时出错。所以,我想要做的是创建一个派生列,如果原始列的值是数字,则该值具有值;如果不是,则为NULL,并且在连接中使用该值而不是具有混合类型的字段
请注意,我尝试在查询中执行此操作,而不是在过程/函数中执行此操作。
这样的事情可能吗?
答案 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]%';