2012-07-10 3 views
1

Есть ли способ создать производный столбец на основе результата выражения в 10g?Oracle Derived Column На основе результата выражения

В частности, я унаследовал таблицу, которая содержит как символьные данные, так и числовые данные в поле varchar2. Очевидно, что это не вызывает головных болей при попытке выполнить объединения, так как я постоянно получаю ошибки «недопустимого числа», когда Oracle переупорядочивает мой запрос, который использует to_number() в поле. Итак, что я хотел бы сделать, это создать производный столбец, который имеет значение, если значение исходного столбца является числовым и NULL, если это не так, и использовать его в соединении, а не в поле со смешанными типами.

Обратите внимание, что я пытаюсь сделать это в запросе, а не в процедуре/функции.

Возможно ли такое?

ответ

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 в своем запросе, но это, похоже, усложнит ситуацию, а не упростит ситуацию.

1

могли бы использовать регулярные выражения:

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

Я бы также предложите поместить [регулярные выражения] (http://psoug.org/reference/regexp.html) в подзапрос, а затем просто присоединиться к ним. помните о двух вещах: (1) было бы лучше развести «один столбец, чтобы править ими всеми», и разделить эту таблицу на два столбца, чтобы избежать этих проблем (числа до чисел, текст в текст после); (2) если у вас есть столбец типа '12 abc 34 def ', вам лучше всего убедиться, что ваш regExp принимает нужные вам Alphas и нужные вам цифры, но я настоятельно рекомендую установить таблицу и перейти с # 1 – Harrison

+0

Вы не можете (легко) решить, какие предложения выполняются сначала в запросе. Если соединение выполняется перед фильтром, это приведет к ошибкам числового преобразования. –

3

В Oracle 11g можно определить virtual columns:

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

В 10г и прежде, чем я хотел бы предложить использовать вид:

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

Вы могли бы даже индексировать выражение с индексом на основе функции для выполнения (до тех пор, пока вы используете только стандартные SQL-функции и детерминированные пользовательские функции):

CREATE INDEX idx ON mytable (CASE WHEN ...); 
Смежные вопросы