Как с помощью Oracle можно дешево проверить существование столбца в таблице в другой схеме?
-
22-07-2019 - |
Вопрос
Среда — 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]:(Ошибка):ОРА-00942:таблица или представление не существует
Поразмыслив над этим некоторое время, я понял, что USER_TAB_COLS на самом деле не является таблицей.Это вид.Я все время выбирал из таблиц, а не из представления.
Я попробовал то же самое со своим db_link и был удивлен, увидев, что данные вернулись.В db_link есть встроенное имя_схемы/пароль, поэтому мне кажется разумным, что она сработала, поскольку она эффективно входит в другую схему, что должно сделать представления доступными.
Гуглившись вокруг и измотав глаза на горе Oracle Doc, я ищу кого -то, чтобы указать мне в правильном направлении или, по крайней мере, указать, что мне не хватает.
Какие методы доступны для получения метаданных, связанных с пользовательской таблицей, из схемы в одном экземпляре, чтобы проверить существование определенного столбца?
Заранее спасибо.
Зло.
+1 за хорошие ответы.Спасибо.
Решение
Как и в случае с другими ответами, обычно я использую ALL_TAB_COLUMNS для такого запроса.Но это будет отображать только столбцы в таблицах, где у вас есть SELECT.И он выбирает этот столбец — в том маловероятном случае, что они реализовали привилегии на уровне столбца для этой таблицы, вы сможете видеть таблицу, но не видеть конкретный интересующий столбец.Для большинства из нас это крайне редко.
DBA_TAB_COLUMNS отобразит все столбцы, но вам нужно будет выбрать их, предоставленные вашей схеме вашим администратором базы данных.(На самом деле, чтобы использовать его, вам понадобится разрешение на 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>
прикреплён к нему)
Если вам разрешено видеть таблицу some_table Барни (т.вам предоставлены как минимум привилегии 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';