Как дешево проверить существование столбца в таблице в другой схеме с Oracle?
Среда - Oracle 9 & 10. У меня нет доступа уровня DBA.
Проблема состоит в том, чтобы убедиться, что определенный столбец существует в определенной таблице, в другой схеме.
Есть два случая, чтобы иметь дело с.
- Другая схема в том же экземпляре
- Схема в другом экземпляре с использованием ссылки db_link
Учитывая мою схему FRED и другую схему BARNEY, я попробовал что-то вроде этого
SELECT 1
FROM BARNEY.USER_TAB_COLS
WHERE TABLE_NAME = 'SOME_TABLE'
AND COLUMN_NAME = 'SOME_SPECIFIC_COLUMN'
Который дал [1]: (Ошибка): ORA-00942: таблица или представление не существует
После этого я понял, что USER_TAB_COLS на самом деле не таблица. Это мнение. Я все время выбирал из таблиц, но не из представления.
Я попытался сделать то же самое с моей db_link, и был удивлен, когда данные вернулись. Ссылка db_link содержит встроенное имя_схемы / пароль, поэтому мне кажется разумным, что она сработала, поскольку она эффективно выполняет вход в другую схему, что должно сделать представления доступными.
Погуглив вокруг и вымотав глаза на гору Oracle doc, я ищу человека, который укажет мне правильное направление или, по крайней мере, укажет, что мне не хватает.
Какие методы доступны для получения метаданных, связанных с пользовательской таблицей, из схемы в одном и том же экземпляре, чтобы проверить, существует ли конкретный столбец?
Заранее спасибо.
Злой.
+1 за хорошие ответы. Спасибо.
4 ответа
Как и в других ответах, обычно я использую ALL_TAB_COLUMNS для такого запроса. Но это будет показывать только столбцы в таблицах, где у вас есть SELECT. И он выбирает этот столбец - в маловероятном случае, если они реализовали привилегии на уровне столбца для этой таблицы, вы можете увидеть таблицу, но не увидите интересующий вас столбец. Для большинства из нас это крайне редко.
DBA_TAB_COLUMNS покажет все столбцы, но вам нужно будет выбрать его, предоставленный вашей схеме вашим DBA. (На самом деле вам понадобится грант на ALL_TAB_COLUMNS, чтобы использовать его, но это распространено в большинстве магазинов). Также можно использовать встроенный пакет DBMS_METADATA PL/SQL с аналогичными ограничениями, но я думаю, вы найдете его более сложным.
Конечно, вы также можете просто попытаться выбрать запись из barney.some_table.some_column@my_dblink (или любых других частей, которые вас интересуют). А затем обработать исключение. Ужасно, я не рекомендовал бы это в большинстве ситуаций.
Вы можете использовать следующий запрос:
SELECT 1
FROM ALL_TAB_COLS
WHERE TABLE_NAME = 'SOME_TABLE'
AND COLUMN_NAME = 'SOME_SPECIFIC_COLUMN'
AND OWNER = 'BARNEY';
(User_Tables и User_Tab_Cols - это просто представления all_tables и all_tab_coumns с where owner = <Current User>
прилагается к нему)
Если вам разрешено видеть некоторую_таблицу Барни (то есть вам были предоставлены как минимум привилегии SELECT для нее), то вы узнаете, существует ли столбец. Если у вас нет прав на стол, вы не сможете получить метаинформацию о нем.
Вы бы использовали all_tab_columns для этого.
Но будьте осторожны, вы увидите только то, что вам разрешено видеть.
Тот же экземпляр, другая схема:
Select Count(*)
From all_tab_cols
Where owner = 'BARNEY' and
table_name = 'SOME_TABLE' and
column_name = 'SOME_SPECIFIC_COLUMN';
Преимущество count(*) - всегда возвращать одну строку со значением 1 или 0, поэтому вам не нужно иметь дело с NO_DATA_FOUND
ошибки в PL/SQL.
Через ссылку на БД используется та же схема, что и у подключенной:
Select Count(*)
From user_tab_cols@MY_DB_LINK
Where table_name = 'SOME_TABLE' and
column_name = 'SOME_SPECIFIC_COLUMN';
Через ссылку на БД, схема отличается от той, которую вы подключаете, как:
Select Count(*)
From all_tab_cols@MY_DB_LINK
Where owner = 'BARNEY' and
table_name = 'SOME_TABLE' and
column_name = 'SOME_SPECIFIC_COLUMN';