#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
работает в других местах? @Sebz5. Поскольку это не задокументировано, я не знаю его ограничений.