Sütun adlarını almak için Oracle sorgusu


123

Bunun gibi bir tablodan sütun almak için bir mySQL sorgum var:

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')"

Oracle 11g veritabanında yukarıdaki sorguyu nasıl değiştiririm? Belirli sütunları hariç tutan, bir şema belirterek tablo 'kullanıcıları' için sonuç kümesi olarak sütun adlarını almam gerekiyor. Şu anda yeni tablo alanımda tüm tablolarım var, bu nedenle şema adı yerine tablo alanı adını mı belirtmeliyim?

Ayrıca bunun için genel bir HQL var mı? Yeni Oracle veritabanımda (Oracle'da yeniyim), yalnızca tablo alanı adına sahibim, bu nedenle şema adıyla eşdeğer (mantıksal olarak?)

Yanıtlar:


177

Oracle eşdeğer information_schema.COLUMNSolan USER_TAB_COLSşimdiki kullanıcının sahip olduğu tablolar için, ALL_TAB_COLSya DBA_TAB_COLSbütün kullanıcılara ait tablolar için.

Tablo alanı bir şemaya eşdeğer değildir, ayrıca tablo alanı adını sağlamanız da gerekmez.

Sorguya istiyorsanız şemayı sağlanması / username kullanım olacağını ALL_TAB_COLSveya DBA_TAB_COLSbelirli bir kullanıcı tarafından sahip olunan tablolar OF sütunlar için. senin durumunda, sorgunun şöyle görüneceğini düşünürdüm:

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

Bu yaklaşımla, SQL enjeksiyonu riskini aldığınızı unutmayın.

DÜZENLE: Oracle'da tipik olarak büyük harf olduğundan tablo ve sütun adları büyük harfle yazılmıştır; bunlar sadece küçük veya karışıktırlar ve etraflarında çift tırnak işareti olacak şekilde oluşturulurlar.


2
bu arada, jdbc aracılığıyla veri tabanından bağımsız olarak bunu yapmanın genel bir yolunu buldum .. buradaki bağlantıyla: kodejava.org/examples/163.html
pri_dev

Sorguma da eklemek and virtual_column = 'NO'zorunda kaldım.
musicin3d

101

Aşağıdaki sorgu Oracle veritabanında benim için çalıştı.

select COLUMN_NAME from ALL_TAB_COLUMNS where TABLE_NAME='MyTableName';

26
Oracle'ın büyük / küçük harfe duyarlı olduğunu unutmayın. Ben genellikle kullanırım ...WHERE LOWER(Table_Name) = 'mytablename';.

2
@ user565869 kullanırdım where lower(TABLE_NAME) = lower('WHATEVER'), aksi takdirde tablo adı bazı büyük harfli karakterlere sahipse, tabloyu da bulamaz
AlexanderD

SELECT column_name FROM all_tab_cols WHERE UPPER(Table_Name) = UPPER('tablename');aynı şekilde çalışır.
user3553260

Sağlanan ile karşılaştırmadan önce tüm değerleri almak için tablonun bir tablo taraması yapmak için oracle'ı kullanmak lower(TABLE_NAME)veya upper(TABLE_NAME)gerektirir . Hızlı testte bu, performansı amacım için kullanılamaz hale getirdi, bu yüzden büyük / küçük harfe duyarlı karşılaştırmalara bağlı kalacağım. ALL_TAB_COLUMNSTABLE_NAMEUPPER('MyTableName')
Chris Magnuson

40

oracle'da kullanabilirsin

desc users

kullanıcılar tablosunda bulunan tüm sütunları görüntülemek için


6
... çünkü 'bir tablonun tüm sütunlarının bir listesi nasıl alınır' cevabını temsil etse de, sorulan soruyu cevaplamıyor: 1) bu bir sorgu değil, 2) sınırlamıyor / döndürülen sütunları filtreleyin, 3) bir sonuç kümesi mi döndürüyor?
Ehryk

6
Upvotes eksikliği yapmaz desc usersbazı sorulara kötü cevap, ama iyi bir cevap değildir bu bir .
Ehryk

ve bir sql sorgusu olmadığı için sql * plus komutudur. daha fazla bilgi için bunu kontrol edin: stackoverflow.com/questions/37133666/…
01000001

7

Bunu deneyebilirsiniz: (11g üzerinde çalışır ve bir tablodan tüm sütun adını döndürür, burada test_tbl tablo adıdır ve user_tab_columns kullanıcı izinli tablonun sütunlarıdır)

select  COLUMN_NAME  from user_tab_columns
where table_name='test_tbl'; 


1
USER_TAB_COLUMNSgerçekte kullanıcının sahip olduğu tabloların sütunlarıdır, kullanıcıya izin verilen tabloların değil.
David Faber

2

Oracle ile kullanılacak sorgu şudur:

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

Bu tür sorgular için HQL'i hiç duymadım. ORM uygulamalarının bununla başa çıkmasının mantıklı olmadığını varsayıyorum. ORM bir Nesne İlişkisel Eşleştirmedir ve aradığınız şey meta veri eşlemesidir ... HQL kullanmazsınız, bunun yerine API yöntemlerini veya doğrudan SQL'i kullanırsınız. Örneğin, JDBC DatabaseMetaData kullanabilirsiniz .

Tablo alanının şema ile ilgisi olmadığını düşünüyorum. AFAIK tablo alanları temel olarak DBA'ları rahatsız etmesi gereken mantıksal dahili teknik amaçlar için kullanılır. Tablo alanları hakkında daha fazla bilgi için Oracle belgesine bakın .


TABLE_NAME='"+_db+".users'başaramayacak; sahip / şema ve tablo adını ayırmanız gerekiyorALL_TAB_COLUMNS
David Faber

2

Sütun adlarını alabilmemin tek yolu aşağıdaki sorguyu kullanmaktı:

select COLUMN_NAME
FROM all_tab_columns atc
WHERE table_name like 'USERS'

2

önemli olan, kurbağada tablo adı büyük yazmanız gerektiğidir, şöyle ki:

select *
FROM all_tab_columns
where table_name like 'IDECLARATION';

1

Bunu Oracle'da yararlı buluyorum:

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;

Bu cevabın okunması çok zor. Lütfen yeniden biçimlendirmeyi düşünün.
chharvey

Ya aynı ada ancak farklı sahiplere sahip birden çok tablo varsa?
David Faber

1

Birkaç durumda, şemadaki bir tablodaki tüm sütunların virgülle ayrılmış bir listesine ihtiyacımız olacaktır. Bu gibi durumlarda, virgülle ayrılmış listeyi bir dizge olarak getiren bu genel işlevi kullanabiliriz.

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;
/

Dolayısıyla, sorgudan işlevi çağırmak, tüm sütunların bulunduğu bir satır verir.

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

Not: LISTAGG Tüm sütunların toplam uzunluğu 4000nadir görülen karakterleri aşarsa başarısız olur . Çoğu durumda bu işe yarayacaktır.


0
  1. SELECT * FROM <SCHEMA_NAME.TABLE_NAME> WHERE ROWNUM = 0;-> Bunun Sorgu Sonucu, bir Sonuç Kümesi olduğuna dikkat edin. Bu, diğer formatlara aktarılabilir. Ve, dışa aktarabilirsiniz Sorgu Sonucu için Textformatında. Dışa aktarma yaptığım zaman aşağıdaki gibi görünüyor 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> -> Not: Bu komut çıktısıdır.


-1

DB2'deki belirli bir sütunu kullanan tablo adlarının bir listesini almak için aşağıdaki sorguyu kullanabilirsiniz:

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

Not: Burada COLUMN_NAME, aradığınız sütun adıyla değiştirin .


Belki de yanıtlamak için DB2 sorularını aramalısınız? Oracle'ı arayan birinin bir DB2 yanıtına ihtiyaç duyacağından şüpheliyim.
RichardTheKiwi

1
Bu cevap aslında bana yardımcı oldu. Oracle modunda DB2 kullanıyorum ve all_tab_cols'u desteklemiyor.
wm_eddie

-1

Bunu deneyebilirsiniz:

'Tablo Adı'nı tanımlayın

Tüm sütun adlarını ve veri türlerini döndürür

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.