有没有办法根据 10g 中的表达式结果创建派生列?
具体来说,我继承了一个表,其中包含 varchar2 字段中的字符数据和数字数据。显然,在尝试进行连接时,这会让人头疼不已,因为当 Oracle 重新排序我在字段上使用 to_number() 的查询时,我经常遇到“无效号码”错误。所以,我想做的是创建一个派生列,如果原始列的值是数字,则该列具有一个值,如果不是,则在连接中使用它而不是混合类型的字段。
请注意,我试图在查询中执行此操作,而不是在过程/函数中。
这样的事情可能吗?
在 Oracle 11g 中,您可以定义虚拟列:
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 ...);
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
的语句,但这似乎会使情况复杂化,而不是使其更简单。
可以使用正则表达式:
select * from table where varchar_field not like '%[0-9]%';