Concat внезапно выдает ошибку

#sql #oracle

#sql #Oracle

Вопрос:

После выполнения этого запроса (который отлично работал до того, как мы обновили нашу версию Oracle до g11) :

 SELECT to_char(wm_concat(PRODUCT_CATEGORY_CODE) )  AS COMB , 
       case when   instr( to_char(wm_concat(PRODUCT_CATEGORY_CODE) ), 'T_V') > 0  then 1 else 0  end  
       case when   instr( to_char(wm_concat(PRODUCT_CATEGORY_CODE) ), 'INT') > 0  then 1 else 0  end  
       case when   instr( to_char(wm_concat(PRODUCT_CATEGORY_CODE) ), 'TEL') > 0  then 1 else 0  end category_count 
       ....
FROM ....     
  

Фактический запрос огромен и запутан, мне удалось определить причины, вызывающие эту ошибку ( COMB,CATEGORY_COUNT из приведенного выше запроса).

PRODUCT_CATEGORY_CODE это тип VARCHAR2(3) .

Я получаю сообщение об ошибке :

ORA-22922: несуществующее значение LOB

Что вызывает эту ошибку и почему внезапное изменение после обновления?

Спасибо.

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

1. Можете ли вы сузить его до строки / набора значений, которые вызывают проблему? Я подозреваю, что причиной проблемы может быть определенное значение в PRODUCT_CATEGORY_CODE .

2. Боюсь, что это не так, в этом столбце существуют только три значения T_V,INT,TEL . @MattGibson

Ответ №1:

Ниже приведена моя попытка ответить, почему это произошло. В этом ответе есть несколько уровней, и по мере углубления они становятся более спекулятивными.

Почему мой запрос перестал работать?

Запрос выполнен с ошибкой, поскольку WM_CONCAT это недокументированная функция, недоступная в вашей новой базе данных.

Почему он больше не доступен?

WM_CONCAT использовался внутренне как часть Oracle Workspace Manager (OWM). OWM является необязательным компонентом в 10g и 11g. Возможно, некоторые базы данных были установлены без нее, или администратор базы данных мог удалить ее позже. Опция не существует для Express Edition. И функция вообще не существует в Oracle 12c.

Давным-давно кто-то в Интернете нашел эту функцию, подумал, что она полезна, рассказал людям, и идея распространилась. Но Oracle никогда не говорил людям использовать его и никогда не гарантировал, что он когда-нибудь не исчезнет. Этот день настал.

Но… почему это произошло с такой популярной функцией ?!

Это проблема отношения с корпорацией Oracle.

Oracle не оценивает функции, которые явно полезны, если они также теоретически не нужны. Они ждали двадцать лет, чтобы создать удобную официальную функцию для выполнения чего-то, что каждый разработчик баз данных в мире делает постоянно.

Вам никогда не нужно было использовать WM_CONCAT . Вы могли бы использовать хаки с XMLAGG, Oracle Data Cartridge, MODEL , CAST(COLLECT... , и т.д. Все это были ужасные решения, но они действительно работали, так почему бы вам, ленивым разработчикам, просто не создавать свое уникальное решение каждый раз, когда вам нужно решить общую проблему?

Такое отношение сводит меня с ума, и я вижу то же самое с простыми задачами, такими как разделение строк и логические типы.

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

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

1. Спасибо за этот подробный ответ. Я одобрю это, поскольку не похоже, что кто-то собирается предоставить мне какую-либо документацию об этом поведении.

Ответ №2:

Мне удалось решить эту проблему, используя LISTAGG() вместо WM_CONCAT() :

 SELECT to_char(LISTAGG(PRODUCT_CATEGORY_CODE,',') WITHIN GROUP(ORDER BY PRODUCT_CATEGORY_CODE))  AS COMB,
       case when   instr( to_char(LISTAGG(PRODUCT_CATEGORY_CODE,',') WITHIN GROUP(ORDER BY PRODUCT_CATEGORY_CODE)), 'T_V') > 0  then 1 else 0  end  
       case when   instr( to_char(LISTAGG(PRODUCT_CATEGORY_CODE,',') WITHIN GROUP(ORDER BY PRODUCT_CATEGORY_CODE)), 'INT') > 0  then 1 else 0  end  
       case when   instr( to_char(LISTAGG(PRODUCT_CATEGORY_CODE,',') WITHIN GROUP(ORDER BY PRODUCT_CATEGORY_CODE)), 'TEL') > 0  then 1 else 0  end   category_count
FROM ...
  

Но я до сих пор не понял, ПОЧЕМУ — вопрос остается.

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

1. Я был в середине ввода этого. WM_CONCAT() не поддерживается.

2. Что означает «не поддерживается»? Почему после обновления старые скрипты перестают работать? WM_CONCAT() все еще работает. Этого не должно происходить.

3. Обратите внимание, что WM_CONCAT не документирован и не поддерживается Oracle, что означает, что его не следует использовать в производственных системах. Функция LISTAGG, которая может выдавать тот же результат, что и WM_CONCAT, документирована и поддерживается Oracle.

4. Но почему он выдает ошибку, если он имеет ту же функциональность, LISTAGG что и ? Почему WM_CONCAT работает в других местах? @Sebz

5. Поскольку это не задокументировано, я не знаю его ограничений.