Requête Oracle pour récupérer les noms de colonnes


123

J'ai une requête mySQL pour obtenir des colonnes d'une table comme celle-ci:

String sqlStr="select column_name 
from information_schema.COLUMNS 
where table_name='users' 
and table_schema='"+_db+"' 
and column_name not in ('password','version','id')"

Comment modifier la requête ci-dessus dans la base de données Oracle 11g? J'ai besoin d'obtenir les noms de colonnes comme ensemble de résultats pour les «utilisateurs» de la table à l'exclusion de certaines colonnes, en spécifiant un schéma. À l'heure actuelle, j'ai toutes les tables dans mon nouvel espace de table, alors dois-je spécifier le nom de l'espace de table à la place du nom de schéma?

Existe-t-il également un HQL générique pour cela? Dans ma nouvelle base de données Oracle (je suis nouveau sur Oracle), je n'ai que le nom de l'espace de table, donc est-ce équivalent au nom du schéma (logiquement?)

Réponses:


176

L'équivalent Oracle pour information_schema.COLUMNSest USER_TAB_COLSpour les tables appartenant à l'utilisateur actuel ALL_TAB_COLSou DBA_TAB_COLSpour les tables appartenant à tous les utilisateurs.

L'espace de table n'est pas équivalent à un schéma, vous n'avez pas non plus à fournir le nom de l'espace de table.

Fournir le schéma / nom d'utilisateur serait utile si vous souhaitez interroger ALL_TAB_COLSou DBA_TAB_COLSpour les colonnes de tables appartenant à un utilisateur spécifique. dans votre cas, j'imagine que la requête ressemblerait à quelque chose comme:

String sqlStr= "
SELECT column_name
  FROM all_tab_cols
 WHERE table_name = 'USERS'
   AND owner = '" +_db+ "'
   AND column_name NOT IN ( 'PASSWORD', 'VERSION', 'ID' )"

Notez qu'avec cette approche, vous risquez une injection SQL.

EDIT: a mis les noms de table et de colonne en majuscules car ils sont généralement en majuscules dans Oracle; ils sont seulement minuscules ou mixtes s'ils sont créés avec des guillemets doubles autour d'eux.


2
au fait, j'ai trouvé un moyen générique de faire cela indépendamment de la base de données via jdbc .. avec le lien ici: kodejava.org/examples/163.html
pri_dev

J'ai également dû ajouter and virtual_column = 'NO'à ma requête.
musicin3d

101

La requête ci-dessous a fonctionné pour moi dans la base de données Oracle.

select COLUMN_NAME from ALL_TAB_COLUMNS where TABLE_NAME='MyTableName';

26
Gardez à l'esprit qu'Oracle est sensible à la casse. J'utilise généralement ...WHERE LOWER(Table_Name) = 'mytablename';.

2
@ user565869 J'utiliserais where lower(TABLE_NAME) = lower('WHATEVER'), sinon quand le nom de la table a un caractère majuscule, il ne trouvera pas non plus la table
AlexanderD

SELECT column_name FROM all_tab_cols WHERE UPPER(Table_Name) = UPPER('tablename');fonctionne aussi bien.
user3553260

L'utilisation de lower(TABLE_NAME)ou upper(TABLE_NAME)requiert qu'oracle effectue une analyse de table de la ALL_TAB_COLUMNStable pour obtenir toutes les valeurs TABLE_NAMEavant de pouvoir la comparer à celle fournie UPPER('MyTableName'). Lors de tests rapides, cela a rendu les performances inutilisables pour mon objectif, je vais donc m'en tenir à des comparaisons sensibles à la casse.
Chris Magnuson

40

dans Oracle, vous pouvez utiliser

desc users

pour afficher toutes les colonnes contenant dans le tableau des utilisateurs


6
... car bien qu'il représente une réponse à `` comment obtenir une liste de toutes les colonnes d'une table '', il ne répond pas à la question qui a été posée: 1) ce n'est pas une requête, 2) il ne limite pas / filtrer les colonnes renvoyées, 3) renvoie-t-il un jeu de résultats?
Ehryk

6
Le manque de votes positifs ne constitue pas desc usersune mauvaise réponse à certaines questions, mais ce n'est pas une bonne réponse à celle-ci .
Ehryk

et parce que ce n'est pas une requête sql, c'est plutôt la commande sql * plus. consultez ceci pour plus d'informations: stackoverflow.com/questions/37133666/…
01000001

7

Vous pouvez essayer ceci: (Cela fonctionne sur 11g et il renvoie tous les noms de colonnes d'une table, ici test_tbl est le nom de la table et user_tab_columns sont les colonnes de la table autorisée par l'utilisateur)

select  COLUMN_NAME  from user_tab_columns
where table_name='test_tbl'; 


1
USER_TAB_COLUMNSsont en fait les colonnes des tables appartenant à l'utilisateur, et non celles des tables autorisées à l'utilisateur.
David Faber

2

La requête à utiliser avec Oracle est:

String sqlStr="select COLUMN_NAME from ALL_TAB_COLUMNS where TABLE_NAME='"+_db+".users' and COLUMN_NAME not in ('password','version','id')"

Jamais entendu parler de HQL pour de telles requêtes. Je suppose que cela n'a pas de sens pour les implémentations ORM de le gérer. ORM est un mappage relationnel d'objet, et ce que vous recherchez, c'est le mappage de métadonnées ... Vous n'utiliserez pas HQL, utilisez plutôt des méthodes API à cette fin, ou direct SQL. Par exemple, vous pouvez utiliser JDBC DatabaseMetaData .

Je pense que l'espace de table n'a rien à voir avec le schéma. Les tablespaces AFAIK sont principalement utilisés à des fins techniques internes logiques qui devraient déranger les DBA. Pour plus d'informations sur les tablespaces, consultez le doc Oracle .


TABLE_NAME='"+_db+".users'échouera; vous devez séparer le propriétaire / schéma et le nom de la table dansALL_TAB_COLUMNS
David Faber

2

La seule façon dont j'ai pu obtenir les noms de colonnes était d'utiliser la requête suivante:

select COLUMN_NAME
FROM all_tab_columns atc
WHERE table_name like 'USERS'

2

le fait est que dans toad, vous devez écrire le nom de la table en majuscule, comme ceci:

select *
FROM all_tab_columns
where table_name like 'IDECLARATION';

1

Je trouve celui-ci utile dans Oracle:

SELECT 
    obj.object_name, 
    atc.column_name, 
    atc.data_type, 
    atc.data_length 
FROM 
    all_tab_columns atc,
    (SELECT 
        * 
     FROM 
         all_objects
     WHERE 
        object_name like 'GL_JE%'
        AND owner = 'GL'
        AND object_type in ('TABLE','VIEW')   
    ) obj
WHERE 
    atc.table_name = obj.object_name
ORDER BY 
    obj.object_name, 
    atc.column_name;

Cette réponse est très difficile à lire. Veuillez envisager de reformater.
chharvey

Que faire s'il y a plusieurs tables avec le même nom, mais des propriétaires différents?
David Faber

1

À plusieurs reprises, nous aurions besoin d'une liste séparée par des virgules de toutes les colonnes d'une table dans un schéma. Dans de tels cas, nous pouvons utiliser cette fonction générique qui récupère la liste séparée par des virgules sous forme de chaîne.

CREATE OR REPLACE FUNCTION cols(
    p_schema_name IN VARCHAR2,
    p_table_name  IN VARCHAR2)
  RETURN VARCHAR2
IS
  v_string VARCHAR2(4000);
BEGIN
  SELECT LISTAGG(COLUMN_NAME , ',' ) WITHIN GROUP (
  ORDER BY ROWNUM )
  INTO v_string
  FROM ALL_TAB_COLUMNS
  WHERE OWNER    = p_schema_name
  AND table_name = p_table_name;
  RETURN v_string;
END;
/

Ainsi, le simple fait d'appeler la fonction à partir de la requête produit une ligne avec toutes les colonnes.

select cols('HR','EMPLOYEES') FROM DUAL;

EMPLOYEE_ID,FIRST_NAME,LAST_NAME,EMAIL,PHONE_NUMBER,HIRE_DATE,JOB_ID,SALARY,COMMISSION_PCT,MANAGER_ID,DEPARTMENT_ID

Remarque: LISTAGG échouera si la longueur combinée de toutes les colonnes dépasse les 4000caractères, ce qui est rare. Dans la plupart des cas, cela fonctionnera.


0
  1. SELECT * FROM <SCHEMA_NAME.TABLE_NAME> WHERE ROWNUM = 0;-> Notez qu'il s'agit du résultat de la requête, un ResultSet. Ceci est exportable vers d'autres formats. Et, vous pouvez exporter le résultat de la requête au Textformat. L'exportation ressemble à ci-dessous quand je l'ai fait SELECT * FROM SATURN.SPRIDEN WHERE ROWNUM = 0;:

    "SPRTELE_PIDM" "SPRTELE_SEQNO" "SPRTELE_TELE_CODE" "SPRTELE_ACTIVITY_DATE" "SPRTELE_PHONE_AREA" "SPRTELE_PHONE_NUMBER" "SPRTELE_PHONE_EXT" "SPRTELE_STATUS_IND" "SPRTELE_ATYP_CODE" "SPRTELE_ADDR_SEQNO" "SPRTELE_PRIMARY_IND" "SPRTELE_UNLIST_IND" "SPRTELE_COMMENT" "SPRTELE_INTL_ACCESS" "SPRTELE_DATA_ORIGIN" "SPRTELE_USER_ID" « SPRTELE_CTRY_CODE_PHONE "" SPRTELE_SURROGATE_ID "" SPRTELE_VERSION "" SPRTELE_VPDI_CODE "

  2. DESCRIBE <TABLE_NAME> -> Remarque: il s'agit d'une sortie de script.


-1

Vous pouvez utiliser la requête ci-dessous pour obtenir une liste des noms de table qui utilisent la colonne spécifique dans DB2:

SELECT TBNAME                
FROM SYSIBM.SYSCOLUMNS       
WHERE NAME LIKE '%COLUMN_NAME'; 

Remarque: remplacez ici le COLUMN_NAMEpar le nom de la colonne que vous recherchez.


Peut-être devriez-vous rechercher des questions DB2 auxquelles répondre? Je doute que quelqu'un recherchant Oracle ait besoin d'une réponse DB2.
RichardTheKiwi

1
Cette réponse m'a vraiment aidé. J'utilise DB2 en mode Oracle et il ne prend pas en charge all_tab_cols.
wm_eddie

-1

Vous pouvez essayer ceci:

décrire 'Nom de la table'

Il renverra tous les noms de colonnes et types de données

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.