2017-01-03 3 views
0

Я пытаюсь запросить строку следующим образом:Проблема Oracle с использованием concat || оператор

В настоящее время моя таблица Oracle имеет около 60 столбцов. Таким образом, чтобы запросить строку для против всех столбцов будет выглядеть следующим образом,

Работа запроса:

select * from <table_name> where (col1||col2||col3...||col60) like '%string%' 

Не работает запрос:

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

select * from <table_name> where (select LISTAGG(COLUMN_NAME, '||') WITHIN GROUP (ORDER BY COLUMN_NAME) from all_tab_columns where TABLE_NAME = '<table_name>' and OWNER = '<owner_name>' and DATA_TYPE != 'CLOB') like '%string%' 

дополнительный запрос :

Нет проблем с нижеследующим подзапросом.

select LISTAGG(COLUMN_NAME, '||') WITHIN GROUP (ORDER BY COLUMN_NAME) from all_tab_columns where TABLE_NAME = '<table_name>' and OWNER = '<owner_name>' and DATA_TYPE != 'CLOB' 

Где подзапрос возвращает результат, как в рабочем запросе.

Я думаю, что оракул, берущий "||" оператор concat только тогда, когда он жестко кодирует его.

Не могли бы вы помочь мне в этом?

+2

Это никогда не называется оператором «труба» в SQL. Это только в сценарии оболочки unix. – Hogan

+2

Вы должны использовать *** динамический SQL *** для достижения желаемого результата. Col1 || col2 в вашем первом запросе принимает значения VALUES в столбцах и объединяет их. Второй запрос объединяет имена COLUMN, а не значения, для сравнения с% string%. Таким образом, ваш второй запрос в основном возвращает строку «Col1 || Col2 || Col3 ...» и сравнивает ее с% string%. Это значительно отличается от первого запроса. Для достижения того, что, по вашему мнению, вам нужно, вам нужно сделать второй запрос строкой, конкатенирующей результаты вспомогательного запроса, а затем «выполнить (str)»; – xQbert

+1

Обратите внимание, что ваш «рабочий» запрос, вероятно, получает несоответствие, если 'Col2' заканчивается' st' и 'Col3' запускает' ring'. Вам придется решить, является ли это проблемой или нет. –

ответ

0

Вот как я решил бы решить вашу проблему таким образом, чтобы масштабировать.

CREATE OR REPLACE VIEW COLUMN_SEARCH AS 

SELECT ID, COL1 AS COL 
FROM TABLENAME 

UNION ALL 

SELECT ID, COL2 AS COL 
FROM TABLENAME 

UNION ALL 

SELECT ID, COL3 AS COL 
FROM TABLENAME 

UNION ALL 

SELECT ID, COL4 AS COL 
FROM TABLENAME 

UNION ALL 

--- 

SELECT ID, COLN AS COL 
FROM TABLENAME 

Теперь с этой точки зрения ваш запрос просто

SELECT TABLENAME.* 
FROM TABLENAME 
JOIN COLUMN_SEARCH ON TABLENAME.ID = COLUMN_SEARCH.ID 
WHERE COLUMN_SEARCH.COL = 'string' 

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

Если он работает медленно, просто сделайте указатель на ID, COL в представлении.


Обновление на основе комментариев

Я хочу добавить некоторые комментарии об использовании динамического SQL, чтобы решить эту проблему. Вы можете использовать динамический SQL для решения этой проблемы, но это будет плохая идея. (Для тех, кто не знает - создание запроса динамически из мета-данных о столбцах каждый раз при выполнении запроса будет использовать динамический SQL)

Вот почему я не рекомендую:

  1. Динамический SQL действительно сложно поддерживать - он по определению более сложный, чем не динамический SQL, и он никогда не выглядит очень похожим на запрос, который вы действительно пытаетесь запустить. Хотя кажется, что это облегчит техническое обслуживание «Каждый раз, когда я добавляю столбец, он просто автоматически добавляет в бит-бам-бум!» Фактически, я обнаружил, что каждый раз, когда вы добавляете столбец, лучше сделать выбор «Хочу ли я добавить это». Иногда это помогает автоматически добавлять его, но во много раз он нарушает работу системы.

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

  3. Dynamic SQL не может быть легко переделан, и настроен - Много чего у администратора баз данных будут выглядеть, как модели данных используются, а затем добавить индексы, перегородки, материализованные запросы и другие настройки, чтобы сделать система работает быстро. Гораздо сложнее выполнить такую ​​настройку динамического SQL (но не невозможно).

  4. Dynamic SQL является плохой код запах - это более тонкая и могут не относиться к этому конкретному вопросу, но нужно сказать - если вы используете динамический SQL это, вероятно, указывает вы сделали что-то не так с вашей моделью данных или вы используете неправильный инструмент. Существует ряд систем «nosql», которые могут быть лучше подходят для решения конкретной проблемы с данными.

+0

Да, я согласен. Но когда я применяю это к запросу «Где», он дает пустой набор результатов. – Raja

+0

, потому что строка 'col1 || col2 || col3' не совпадает с литералами 'col1 || col2 || Col3', в которых значения col1, col2 и col3 будут объединены, чтобы сформировать значение 1. который затем сравнивается с% string%. – xQbert

+0

@Yadheendran позвольте мне переписать, чтобы реально решить вашу проблему. – Hogan

Смежные вопросы