Como é que uma barata validar a existência de uma coluna em uma tabela em outro esquema com o Oracle?

StackOverflow https://stackoverflow.com/questions/1646953

Pergunta

O ambiente é o Oracle 9 e 10. Eu não tenho acesso ao nível DBA.

O problema é verificar se uma coluna específica existe em uma tabela específica, em outro esquema.

Existem dois casos para lidar com eles.

  1. Outro esquema na mesma instância
  2. Um esquema em uma instância diferente, usando uma db_link

Dado o meu esquema de Fred e outro esquema BARNEY, eu tentei algo assim

SELECT 1
FROM BARNEY.USER_TAB_COLS
WHERE TABLE_NAME = 'SOME_TABLE' 
  AND COLUMN_NAME = 'SOME_SPECIFIC_COLUMN'

o que rendeu [1]: (Erro): ORA-00942: tabela ou vista não existe

Depois de vegging sobre isso por algum tempo, percebi que USER_TAB_COLS, não é realmente uma mesa. É uma visão. Fui selecionando a partir de tabelas tempo todo, mas não a partir de um ponto de vista.

Eu tentei a mesma coisa com o meu db_link, e ficou surpreso ao ver os dados voltar. A db_link tem uma schema_name incorporado / senha nele, por isso parece-me razoável que ele trabalhou, como ele efetivamente faz logon para o outro esquema, o que deve tornar os pontos de vista acessível.

Depois de ter Googled ao redor, e desgastado meus globos oculares em na montanha da Oracle doc, Eu estou procurando alguém para me apontar na direção correta, ou pelo menos apontar o que estou em falta.

Que técnicas estão disponíveis para obter tabela de usuário metadados relacionados a partir de um esquema na mesma instância para validar que existe uma coluna específica?

Agradecemos antecipadamente.

Evil.

+1 para boas respostas. Obrigado.

Foi útil?

Solução

Tal como acontece com as outras respostas, normalmente eu uso ALL_TAB_COLUMNS para uma consulta como esta. Mas isso só irá mostrar colunas em tabelas onde você tem SELECT. E é selecionar nessa coluna - no caso improvável de que eles implementaram privilégios de nível de coluna para a tabela, você pode ser capaz de ver a mesa, mas não vir a coluna específica de interesse. Para a maioria de nós, isso é extremamente raro.

DBA_TAB_COLUMNS irá mostrar todas as colunas, mas você vai precisar selecionar nele concedido ao seu esquema pelo seu DBA. (Na verdade, você vai precisar de uma subvenção em ALL_TAB_COLUMNS para usá-la, mas isso é comum na maioria das lojas). O DBMS_METADATA PL / SQL embutido pacote também pode ser usado, com limitações semelhantes, mas eu acho que você vai encontrá-lo mais complicado.

É claro, você também pode simplesmente tentar selecionar um registro de barney.some_table.some_column@my_dblink (ou o que quer que peças de que você está em interessado). E, em seguida, tratar a exceção. Feio, eu não recomendo na maioria das situações.

Outras dicas

Você pode usar a seguinte consulta:

SELECT 1
FROM ALL_TAB_COLS
WHERE TABLE_NAME = 'SOME_TABLE' 
  AND COLUMN_NAME = 'SOME_SPECIFIC_COLUMN'
  AND OWNER = 'BARNEY';

(USER_TABLES e User_Tab_Cols são apenas pontos de vista sobre ALL_TABLES e all_tab_coumns com um where owner = <Current User> ligado a ele)

Se você está autorizado a ver some_table do Barney (ou seja, você tem sido concedida pelo menos privilégios SELECT sobre ele), então você vai saber se a coluna está lá. Se você não tem direitos sobre a mesa, você não será capaz de obter informações meta sobre ele.

Você usaria all_tab_columns para isso.

Mas cuidado que você só vai ver o que você está autorizado a ver.

O mesmo exemplo, esquema diferente:

Select Count(*)
From   all_tab_cols
Where  owner       = 'BARNEY'               and
       table_name  = 'SOME_TABLE'           and
       column_name = 'SOME_SPECIFIC_COLUMN';

A contagem (*) tem a vantagem de sempre retornando uma única linha com um valor de 1 ou 0, para que você não tem que lidar com erros NO_DATA_FOUND em PL / SQL.

Através de um DB link, mesmo esquema que o que você conectar como:

Select Count(*)
From   user_tab_cols@MY_DB_LINK
Where  table_name  = 'SOME_TABLE'           and
       column_name = 'SOME_SPECIFIC_COLUMN';

Através de um DB link, esquema diferente do que aquele que você se conectar como:

Select Count(*)
From   all_tab_cols@MY_DB_LINK
Where  owner       = 'BARNEY'               and
       table_name  = 'SOME_TABLE'           and
       column_name = 'SOME_SPECIFIC_COLUMN';
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top