แบบสอบถาม Oracle เพื่อดึงชื่อคอลัมน์


123

ฉันมีแบบสอบถาม mySQL เพื่อรับคอลัมน์จากตารางดังนี้:

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 ได้อย่างไร ฉันต้องการรับชื่อคอลัมน์เป็นชุดผลลัพธ์สำหรับตาราง 'ผู้ใช้' โดยไม่รวมคอลัมน์บางคอลัมน์โดยระบุสคีมา ตอนนี้ฉันมีตารางทั้งหมดในพื้นที่ตารางใหม่ฉันจึงระบุชื่อพื้นที่ตารางแทนชื่อสคีมาหรือไม่

มี HQL ทั่วไปสำหรับสิ่งนี้ด้วยหรือไม่? ในฐานข้อมูล Oracle ใหม่ของฉัน (ฉันยังใหม่กับ Oracle) ฉันมีเพียงชื่อพื้นที่ตารางดังนั้นจึงเทียบเท่ากับชื่อสคีมา (ในเชิงเหตุผล?)

คำตอบ:


177

เทียบเท่า Oracle สำหรับinformation_schema.COLUMNSเป็นUSER_TAB_COLSโต๊ะที่เป็นเจ้าของโดยผู้ใช้ปัจจุบันALL_TAB_COLSหรือDBA_TAB_COLSสำหรับตารางที่เป็นเจ้าของโดยผู้ใช้ทั้งหมด

Tablespace ไม่เทียบเท่ากับสคีมาคุณไม่จำเป็นต้องระบุชื่อพื้นที่ตาราง

การระบุสคีมา / ชื่อผู้ใช้จะถูกนำไปใช้หากคุณต้องการสอบถามALL_TAB_COLSหรือDBA_TAB_COLSสำหรับคอลัมน์ของตารางที่เป็นของผู้ใช้เฉพาะ ในกรณีของคุณฉันคิดว่าข้อความค้นหาจะมีลักษณะดังนี้:

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

โปรดทราบว่าด้วยวิธีนี้คุณเสี่ยงต่อการแทรก SQL

แก้ไข:ตัวพิมพ์ใหญ่ชื่อตารางและคอลัมน์เนื่องจากโดยทั่วไปจะเป็นตัวพิมพ์ใหญ่ใน Oracle เป็นเพียงกรณีที่ต่ำกว่าหรือผสมหากสร้างขึ้นโดยมีเครื่องหมายคำพูดคู่รอบตัว


2
โดยวิธีการที่ฉันพบวิธีทั่วไปในการทำเช่นนี้โดยไม่คำนึงถึงฐานข้อมูลผ่าน jdbc .. ด้วยลิงก์ที่นี่: kodejava.org/examples/163.html
pri_dev

ฉันต้องเพิ่มand virtual_column = 'NO'ในแบบสอบถามของฉันด้วย
musicin3d

101

แบบสอบถามด้านล่างใช้ได้ผลสำหรับฉันในฐานข้อมูล Oracle

select COLUMN_NAME from ALL_TAB_COLUMNS where TABLE_NAME='MyTableName';

26
โปรดทราบว่า Oracle เป็นกรณี ๆ ไป ฉันมักจะใช้...WHERE LOWER(Table_Name) = 'mytablename';ไฟล์.

2
@ user565869 ฉันจะใช้where lower(TABLE_NAME) = lower('WHATEVER')มิฉะนั้นเมื่อชื่อตารางมีอักขระตัวพิมพ์ใหญ่มันจะไม่พบตารางเช่นกัน
AlexanderD

SELECT column_name FROM all_tab_cols WHERE UPPER(Table_Name) = UPPER('tablename');ใช้งานได้ดีเช่นกัน
user3553260

การใช้lower(TABLE_NAME)หรือupper(TABLE_NAME)ต้องใช้ oracle ในการสแกนตารางของALL_TAB_COLUMNSตารางเพื่อรับค่าทั้งหมดTABLE_NAMEก่อนที่จะสามารถเปรียบเทียบกับที่ให้UPPER('MyTableName')มา ในการทดสอบอย่างรวดเร็วสิ่งนี้ทำให้ประสิทธิภาพไม่สามารถใช้งานได้ตามวัตถุประสงค์ของฉันดังนั้นฉันจะยึดติดกับการเปรียบเทียบแบบคำนึงถึงขนาดตัวพิมพ์
Chris Magnuson

40

ใน oracle คุณสามารถใช้ได้

desc users

เพื่อแสดงคอลัมน์ทั้งหมดที่มีในตารางผู้ใช้


6
... เพราะถึงแม้จะเป็นคำตอบสำหรับ 'วิธีรับรายการคอลัมน์ทั้งหมดของตาราง' แต่ก็ไม่ตอบคำถามที่ถาม: 1) ไม่ใช่แบบสอบถาม 2) ไม่ จำกัด / กรองคอลัมน์ที่ส่งคืน 3) ส่งคืนชุดผลลัพธ์หรือไม่
Ehryk

6
ขาดการ upvotes ไม่ได้ทำให้desc usersเป็นคำตอบที่ดีที่จะคำถามบางอย่าง แต่มันไม่ได้เป็นคำตอบที่ดีคนนี้
Ehryk

และเนื่องจากไม่ใช่แบบสอบถาม sql แต่เป็นคำสั่ง sql * plus ชำระเงินนี้สำหรับข้อมูลเพิ่มเติม: stackoverflow.com/questions/37133666/…
01000001

7

คุณสามารถลองสิ่งนี้: (ใช้งานได้กับ 11g และส่งคืนชื่อคอลัมน์ทั้งหมดจากตารางในที่นี้ test_tbl คือชื่อตารางและ user_tab_columns คือคอลัมน์ของตารางที่ผู้ใช้อนุญาต)

select  COLUMN_NAME  from user_tab_columns
where table_name='test_tbl'; 


1
USER_TAB_COLUMNSเป็นคอลัมน์ของตารางที่เป็นของผู้ใช้ไม่ใช่ของตารางที่ผู้ใช้อนุญาต
David Faber

2

แบบสอบถามที่จะใช้กับ Oracle คือ:

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

ไม่เคยได้ยิน HQL สำหรับคำถามดังกล่าว ฉันคิดว่ามันไม่สมเหตุสมผลสำหรับการใช้งาน ORM ที่จะจัดการกับมัน ORM คือ Object Relational Mapping และสิ่งที่คุณกำลังมองหาคือการแม็ปข้อมูลเมตา ... คุณจะไม่ใช้ HQL แทนที่จะใช้วิธี API เพื่อจุดประสงค์นี้หรือใช้ SQL โดยตรง ตัวอย่างเช่นคุณสามารถใช้ JDBC DatabaseMetaData

ฉันคิดว่าช้อนโต๊ะไม่มีส่วนเกี่ยวข้องกับสคีมา ตาราง AFAIK ส่วนใหญ่ใช้เพื่อวัตถุประสงค์ทางเทคนิคภายในเชิงตรรกะซึ่งน่าจะรบกวน DBA สำหรับข้อมูลเพิ่มเติมเกี่ยวกับตารางดูออราเคิล doc


TABLE_NAME='"+_db+".users'จะล้มเหลว; คุณต้องแยกเจ้าของ / สคีมาและชื่อตารางในALL_TAB_COLUMNS
David Faber

2

วิธีเดียวที่ฉันจะได้ชื่อคอลัมน์คือการใช้แบบสอบถามต่อไปนี้:

select COLUMN_NAME
FROM all_tab_columns atc
WHERE table_name like 'USERS'

2

ประเด็นคือในคางคกคุณต้องเขียนชื่อตารางเช่นนี้:

select *
FROM all_tab_columns
where table_name like 'IDECLARATION';

1

ฉันพบว่าสิ่งนี้มีประโยชน์ใน 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;

คำตอบนี้อ่านยากมาก โปรดพิจารณาจัดรูปแบบใหม่
chharvey

จะเกิดอะไรขึ้นถ้ามีหลายตารางที่มีชื่อเดียวกัน แต่มีเจ้าของต่างกัน?
David Faber

1

ในหลาย ๆ ครั้งเราต้องใช้รายการคอลัมน์ทั้งหมดที่คั่นด้วยจุลภาคจากตารางในสคีมา ในกรณีเช่นนี้เราสามารถใช้ฟังก์ชันทั่วไปนี้ซึ่งดึงรายการที่คั่นด้วยจุลภาคเป็นสตริง

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

ดังนั้นการเรียกใช้ฟังก์ชันจากคิวรีจะทำให้ได้แถวที่มีคอลัมน์ทั้งหมด

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

หมายเหตุ: LISTAGGจะล้มเหลวหากความยาวรวมของคอลัมน์ทั้งหมดเกิน4000อักขระซึ่งหายาก สำหรับกรณีส่วนใหญ่จะได้ผล


0
  1. SELECT * FROM <SCHEMA_NAME.TABLE_NAME> WHERE ROWNUM = 0;-> โปรดทราบว่านี่คือผลการค้นหาซึ่งเป็น ResultSet ซึ่งสามารถส่งออกไปยังรูปแบบอื่นได้ และคุณสามารถส่งออกผลการสืบค้นเพื่อจัดTextรูปแบบได้ การส่งออกดูเหมือนด้านล่างเมื่อฉันทำ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> -> หมายเหตุ: นี่คือเอาต์พุตสคริปต์


-1

คุณสามารถใช้แบบสอบถามด้านล่างเพื่อรับรายชื่อตารางที่ใช้คอลัมน์เฉพาะใน DB2:

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

หมายเหตุ: แทนที่COLUMN_NAMEด้วยชื่อคอลัมน์ที่คุณกำลังค้นหา


บางทีคุณควรมองหาคำถาม DB2 เพื่อตอบ? ฉันสงสัยว่ามีคนค้นหา Oracle ต้องการคำตอบ DB2
RichardTheKiwi

1
คำตอบนี้ช่วยฉันได้จริง ฉันใช้ DB2 ในโหมด Oracle และไม่รองรับ all_tab_cols
wm_eddie

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.