Как дешево проверить существование столбца в таблице в другой схеме с Oracle? - PullRequest
1 голос
/ 30 октября 2009

Среда - 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 содержит встроенное имя_схемы / пароль, поэтому мне кажется разумным, что она сработала, поскольку она эффективно входит в другую схему, что должно сделать доступными представления.

Погуглив и вымотав мои глазные яблоки на горе доктора Оракула, Я ищу кого-то, чтобы указать мне правильное направление или, по крайней мере, указать, что мне не хватает.

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

Заранее спасибо.

Evil.

+ 1 для хороших ответов. Спасибо.

Ответы [ 4 ]

6 голосов
/ 30 октября 2009

Вы можете использовать следующий запрос:

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 для нее), то вы узнаете, существует ли столбец. Если у вас нет прав на стол, вы не сможете получить метаинформацию о нем.

2 голосов
/ 30 октября 2009

Как и в других ответах, обычно я использую ALL_TAB_COLUMNS для такого запроса. Но это будет показывать только столбцы в таблицах, где у вас есть SELECT. И он выбирает этот столбец - в маловероятном случае, если они реализовали привилегии на уровне столбца для этой таблицы, вы можете увидеть таблицу, но не увидите интересующий ее конкретный столбец. Для большинства из нас это крайне редко.

DBA_TAB_COLUMNS покажет все столбцы, но вам нужно будет выбрать его, предоставленный вашей схеме вашим DBA. (На самом деле вам понадобится грант на ALL_TAB_COLUMNS, чтобы использовать его, но это распространено в большинстве магазинов). Также можно использовать встроенный пакет DBMS_METADATA PL / SQL с аналогичными ограничениями, но я думаю, вы найдете его более сложным.

Конечно, вы также можете просто попытаться выбрать запись из barney.some_table.some_column@my_dblink (или любых других частей, которые вас интересуют). А затем обработать исключение. Ужасно, я не рекомендовал бы это в большинстве ситуаций.

1 голос
/ 30 октября 2009

Тот же экземпляр, другая схема:

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';
1 голос
/ 30 октября 2009

Для этого вы бы использовали all_tab_columns.

Но учтите, что вы увидите только то, что вам разрешено видеть.

...