Предложение по использованию to_number в Oracle

#sql #database #oracle #oracle11g

Вопрос:

Ниже запрос выдает ошибку.

 select sob.set_of_books_id, orginfo.org_information1
from 
  gl_sets_of_books sob, 
  hr_organization_information orginfo
    where 
      sob.set_of_books_id = to_number(orginfo.org_information1);
 

введите описание изображения здесь

Причина set_of_books_id в том, что это столбец чисел и org_information1 varchar, который содержит строку, а также числовую строку. так что это несоответствие типов. мы должны выбрать только те значения, в которых есть числовая строка org_information1

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

 select sob.set_of_books_id, orginfo.org_information1
from  hr_organization_information orginfo, gl_sets_of_books sob
where sob.set_of_books_id = to_number(orginfo.org_information1)
and REGEXP_LIKE(orginfo.org_information1, '^[[:digit:]] 

Мы только что добавили эту строку  and REGEXP_LIKE(orginfo.org_information1, '^[[:digit:]] $');  в предыдущий запрос, и она работает правильно.

Мой вопрос даже в последнем запросе, мы используем предложение where и присоединяемся к тому же условию, которое не удалось выполнить в первом запросе .и  where  определенно будет выполняться раньше  AND  . так почему же он не терпит неудачу? будет ли это неудачно для некоторых записей? или запрос правильный? есть ли лучший способ использовать второй запрос?

если я не использую существующее  where  условие, то это приводит к ошибке. я не знаю, в чем проблема с нижеприведенным запросом.

введите описание изображения здесь

Мы не можем использовать  to_char  on set_of_books_id  , потому что этот столбец содержит индекс.и мы не можем изменить его для создания индекса на основе функций.Мы должны использовать индекс в нашем запросе


Комментарии:

1. не могу изменить, чтобы создать индекс на основе функций - почему вы не можете создать индекс на основе функций?

2. Привет, Крис, Потому что стол не принадлежит нам. Это приложение EBS, в котором к одной таблице обращаются многие приложения. Они отказались создавать индекс на основе функций. мы используем их таблицу для панели мониторинга.

Ответ №1:

where обязательно побегу раньше and

Нет!

Оптимизатор может свободно изменять условия в вашем запросе. Нет никакой гарантии, что он обрабатывает их сверху вниз. Это может привести к неожиданным последствиям, если план изменится (например, из-за того, что вы добавили/удалили индексы).

Предполагая, что вы используете 12.2 или выше, вместо регулярного выражения вы можете использовать on conversion error предложение для сопоставления всех нечисловых значений с null :

 with rws as (
  select level x,
         case mod ( level, 3 )
           when 0 then chr ( level 64 )
           else to_char ( level )
         end y
  from   dual
  connect by level <= 10
)
  select y from rws
  where  x = to_number ( y default null on conversion error );
  
Y    
1     
2     
4     
5     
7     
8     
10   
 

Комментарии:

1. Привет, Крис, я использую 11g. также я не могу использовать to_char(sob.set_of_books_id) для этого, потому что этот столбец содержит индекс в базовой таблице. поэтому мы хотим использовать индекс. можем ли мы каким-то образом изменить приведенный выше запрос и убедиться, что он не завершится неудачей ни при каких обстоятельствах?

Ответ №2:

Используйте TO_CHAR в столбце число, а не TO_NUMBER в столбце строка:

 select sob.set_of_books_id,
       orginfo.org_information1
from   hr_organization_information orginfo
       INNER JOIN gl_sets_of_books sob
       ON ( TO_CHAR(sob.set_of_books_id) = orginfo.org_information1 );
 

Или, начиная с Oracle 12.2, вы можете использовать TO_NUMBER(value DEFAULT NULL ON CONVERSION ERROR) :

 select sob.set_of_books_id,
       orginfo.org_information1
from   hr_organization_information orginfo
       INNER JOIN gl_sets_of_books sob
       ON ( sob.set_of_books_id
            = TO_NUMBER(orginfo.org_information1 DEFAULT NULL ON CONVERSION ERROR)
          );
 

Комментарии:

1. Мы не можем использовать to_char для set_of_books_id, потому что этот столбец содержит индекс.и мы не можем изменить его для создания индекса на основе функций

2. "Мы не можем использовать to_char для set_of_books_id, потому что этот столбец содержит индекс". Индекс не мешает вам использовать функцию. Это просто означает, что если вы используете функцию, индекс не может быть использован для разрешения запроса, что, вероятно, приведет к полному сканированию таблицы. Но это также не обязательно может быть проблемой. Вы действительно устали от этого?

3. Привет, на самом деле более раннее условие было to_char(set_of_books_id)=org_information1 . команда perf предложила нам изменить и использовать to_number, чтобы можно было использовать индекс. теперь можно использовать индекс, но мы сталкиваемся с проблемой преобразования, потому что org_information1 также содержит буквенно-цифровую строку. таким образом, преобразование их в число приведет к ошибке.

);
Мы только что добавили эту строку and REGEXP_LIKE(orginfo.org_information1, '^[[:digit:]] $'); в предыдущий запрос, и она работает правильно.

Мой вопрос даже в последнем запросе, мы используем предложение where и присоединяемся к тому же условию, которое не удалось выполнить в первом запросе .и where определенно будет выполняться раньше AND . так почему же он не терпит неудачу? будет ли это неудачно для некоторых записей? или запрос правильный? есть ли лучший способ использовать второй запрос?

если я не использую существующее where условие, то это приводит к ошибке. я не знаю, в чем проблема с нижеприведенным запросом.

введите описание изображения здесь

Мы не можем использовать to_char on set_of_books_id , потому что этот столбец содержит индекс.и мы не можем изменить его для создания индекса на основе функций.Мы должны использовать индекс в нашем запросе

Комментарии:

1. не могу изменить, чтобы создать индекс на основе функций — почему вы не можете создать индекс на основе функций?

2. Привет, Крис, Потому что стол не принадлежит нам. Это приложение EBS, в котором к одной таблице обращаются многие приложения. Они отказались создавать индекс на основе функций. мы используем их таблицу для панели мониторинга.

Ответ №1:

where обязательно побегу раньше and

Нет!

Оптимизатор может свободно изменять условия в вашем запросе. Нет никакой гарантии, что он обрабатывает их сверху вниз. Это может привести к неожиданным последствиям, если план изменится (например, из-за того, что вы добавили/удалили индексы).

Предполагая, что вы используете 12.2 или выше, вместо регулярного выражения вы можете использовать on conversion error предложение для сопоставления всех нечисловых значений с null :


Комментарии:

1. Привет, Крис, я использую 11g. также я не могу использовать to_char(sob.set_of_books_id) для этого, потому что этот столбец содержит индекс в базовой таблице. поэтому мы хотим использовать индекс. можем ли мы каким-то образом изменить приведенный выше запрос и убедиться, что он не завершится неудачей ни при каких обстоятельствах?

Ответ №2:

Используйте TO_CHAR в столбце число, а не TO_NUMBER в столбце строка:


Или, начиная с Oracle 12.2, вы можете использовать TO_NUMBER(value DEFAULT NULL ON CONVERSION ERROR) :


Комментарии:

1. Мы не можем использовать to_char для set_of_books_id, потому что этот столбец содержит индекс.и мы не можем изменить его для создания индекса на основе функций

2. «Мы не можем использовать to_char для set_of_books_id, потому что этот столбец содержит индекс». Индекс не мешает вам использовать функцию. Это просто означает, что если вы используете функцию, индекс не может быть использован для разрешения запроса, что, вероятно, приведет к полному сканированию таблицы. Но это также не обязательно может быть проблемой. Вы действительно устали от этого?

3. Привет, на самом деле более раннее условие было to_char(set_of_books_id)=org_information1 . команда perf предложила нам изменить и использовать to_number, чтобы можно было использовать индекс. теперь можно использовать индекс, но мы сталкиваемся с проблемой преобразования, потому что org_information1 также содержит буквенно-цифровую строку. таким образом, преобразование их в число приведет к ошибке.