Как дешево проверить существование столбца в таблице в другой схеме с Oracle?

Среда - Oracle 9 & 10. У меня нет доступа уровня DBA.

Проблема состоит в том, чтобы убедиться, что определенный столбец существует в определенной таблице, в другой схеме.

Есть два случая, чтобы иметь дело с.

  1. Другая схема в том же экземпляре
  2. Схема в другом экземпляре с использованием ссылки 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';
Другие вопросы по тегам