Truy vấn Oracle để tìm nạp tên cột


123

Tôi có một truy vấn myQuery để lấy các cột từ một bảng như thế này:

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

Làm cách nào để thay đổi truy vấn trên trong cơ sở dữ liệu Oracle 11g? Tôi cần lấy tên cột làm tập kết quả cho bảng 'người dùng' ngoại trừ các cột nhất định, chỉ định lược đồ. Ngay bây giờ tôi có tất cả các bảng trong không gian bảng mới của mình, vậy tôi có chỉ định tên vùng bảng thay cho tên lược đồ không?

Ngoài ra có một HQL chung cho việc này? Trong cơ sở dữ liệu Oracle mới của tôi (tôi mới biết về Oracle), tôi chỉ có tên vùng bảng, vì vậy nó có tương đương với tên lược đồ (về mặt logic không?)

Câu trả lời:


176

Oracle cho tương đương information_schema.COLUMNSUSER_TAB_COLScho các bảng thuộc sở hữu của người dùng hiện hành, ALL_TAB_COLShoặcDBA_TAB_COLS cho các bảng thuộc sở hữu của tất cả người dùng.

Không gian bảng không tương đương với một lược đồ, bạn cũng không phải cung cấp tên vùng bảng.

Việc cung cấp lược đồ / tên người dùng sẽ được sử dụng nếu bạn muốn truy vấn ALL_TAB_COLShoặc DBA_TAB_COLScho các cột OF bảng do một người dùng cụ thể sở hữu. trong trường hợp của bạn, tôi tưởng tượng truy vấn sẽ trông giống như:

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

Lưu ý rằng với cách tiếp cận này, bạn có nguy cơ tiêm SQL.

EDIT: Viết tắt tên bảng và cột vì chúng thường là chữ hoa trong Oracle; chúng chỉ là trường hợp thấp hơn hoặc hỗn hợp nếu được tạo với dấu ngoặc kép xung quanh chúng.


2
bằng cách này, tôi đã tìm thấy một cách chung để thực hiện việc này bất kể databbase thông qua jdbc .. với liên kết ở đây: kodejava.org/examples/163.html
Pri_dev

Tôi cũng đã phải thêm and virtual_column = 'NO'vào truy vấn của tôi.
musicin3d

101

Các truy vấn dưới đây làm việc cho tôi trong cơ sở dữ liệu Oracle.

select COLUMN_NAME from ALL_TAB_COLUMNS where TABLE_NAME='MyTableName';

26
Hãy nhớ rằng Oracle là trường hợp nhạy cảm. Tôi thường sử dụng ...WHERE LOWER(Table_Name) = 'mytablename';.

2
@ user565869 Tôi sẽ sử dụng where lower(TABLE_NAME) = lower('WHATEVER'), khác khi tên bảng có một số ký tự viết hoa, nó sẽ không tìm thấy bảng
AlexanderD

SELECT column_name FROM all_tab_cols WHERE UPPER(Table_Name) = UPPER('tablename');hoạt động tốt như vậy.
user3553260

Sử dụng lower(TABLE_NAME)hoặc upper(TABLE_NAME)yêu cầu nhà tiên tri thực hiện quét bảng của ALL_TAB_COLUMNSbảng để có được tất cả các giá trị TABLE_NAMEtrước khi có thể so sánh nó với bảng được cung cấp UPPER('MyTableName'). Trong thử nghiệm nhanh, điều này làm cho hiệu suất không thể sử dụng được cho mục đích của tôi vì vậy tôi sẽ kiên định với các so sánh phân biệt chữ hoa chữ thường.
Chris Magnuson

40

trong orory bạn có thể sử dụng

desc users

để hiển thị tất cả các cột có trong bảng người dùng


6
... bởi vì mặc dù nó đại diện cho câu trả lời cho 'cách lấy danh sách tất cả các cột của bảng', nhưng nó không trả lời câu hỏi được hỏi: 1) nó không phải là truy vấn, 2) nó không giới hạn / lọc các cột được trả về, 3) nó có trả về tập kết quả không?
Ehryk

6
Thiếu upvote không tạo ra desc usersmột câu trả lời xấu cho một số câu hỏi, nhưng nó không phải là một câu trả lời tốt cho câu hỏi này .
Ehryk

và bởi vì nó không phải là một truy vấn sql, mà đó là lệnh sql * plus. kiểm tra cái này để biết thêm thông tin: stackoverflow.com/questions/37133666/
Kẻ

7

Bạn có thể thử điều này: (Nó hoạt động vào 11g và nó trả về tất cả tên cột từ một bảng, ở đây test_tbl là tên bảng và user_tab_columns là các cột của bảng được người dùng cho phép)

select  COLUMN_NAME  from user_tab_columns
where table_name='test_tbl'; 


1
USER_TAB_COLUMNSthực sự là các cột của các bảng thuộc sở hữu của người dùng, không phải là các bảng được phép cho người dùng.
David Faber

2

Truy vấn để sử dụng với Oracle là:

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

Chưa bao giờ nghe nói về HQL cho các truy vấn như vậy. Tôi cho rằng nó không có ý nghĩa đối với việc triển khai ORM để đối phó với nó. ORM là Ánh xạ quan hệ đối tượng và thứ bạn đang tìm kiếm là ánh xạ siêu dữ liệu ... Bạn sẽ không sử dụng HQL, thay vào đó sử dụng các phương thức API cho mục đích này hoặc SQL trực tiếp. Chẳng hạn, bạn có thể sử dụng JDBC DatabaseMetaData .

Tôi nghĩ không gian bảng không liên quan gì đến lược đồ. Các không gian bảng AFAIK chủ yếu được sử dụng cho các mục đích kỹ thuật nội bộ hợp lý, điều này sẽ làm phiền các DBA. Để biết thêm thông tin về không gian bảng, xem tài liệu Oracle .


TABLE_NAME='"+_db+".users'sẽ thất bại; bạn cần tách chủ sở hữu / lược đồ và tên bảng trongALL_TAB_COLUMNS
David Faber

2

Cách duy nhất mà tôi có thể nhận được các tên cột là sử dụng truy vấn sau:

select COLUMN_NAME
FROM all_tab_columns atc
WHERE table_name like 'USERS'

2

Vấn đề là ở cóc bạn phải viết tên bảng, như thế này:

select *
FROM all_tab_columns
where table_name like 'IDECLARATION';

1

Tôi thấy cái này hữu ích trong 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;

Câu trả lời này rất khó đọc. Hãy xem xét định dạng lại.
chharvey

Nếu có nhiều bảng có cùng tên, nhưng chủ sở hữu khác nhau thì sao?
David Faber

1

Trong một số trường hợp, chúng ta sẽ cần danh sách được phân tách bằng dấu phẩy của tất cả các cột từ một bảng trong lược đồ. Trong các trường hợp như vậy, chúng ta có thể sử dụng hàm chung này để tìm nạp danh sách được phân tách bằng dấu phẩy dưới dạng chuỗi.

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

Vì vậy, chỉ cần gọi hàm từ truy vấn sẽ mang lại một hàng với tất cả các cột.

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

Lưu ý: LISTAGG sẽ thất bại nếu độ dài kết hợp của tất cả các cột vượt quá các 4000ký tự hiếm gặp. Đối với hầu hết các trường hợp, điều này sẽ làm việc.


0
  1. SELECT * FROM <SCHEMA_NAME.TABLE_NAME> WHERE ROWNUM = 0;-> Lưu ý rằng, đây là Kết quả truy vấn, Kết quả. Điều này có thể xuất sang các định dạng khác. Và, bạn có thể xuất Kết quả truy vấn sang Textđịnh dạng. Xuất khẩu như dưới đây khi tôi đã làm 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> -> Lưu ý: Đây là đầu ra tập lệnh.


-1

Bạn có thể sử dụng truy vấn dưới đây để lấy danh sách các tên bảng sử dụng cột cụ thể trong DB2:

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

Lưu ý: Ở đây thay thế COLUMN_NAMEbằng tên cột mà bạn đang tìm kiếm.


Có lẽ bạn nên tìm câu hỏi của DB2 để trả lời? Tôi nghi ngờ ai đó đang tìm kiếm Oracle sẽ cần một câu trả lời của DB2.
RichardTheKiwi

1
Câu trả lời này thực sự đã giúp tôi. Tôi đang sử dụng DB2 ở chế độ Oracle và nó không hỗ trợ all_tab_cols.
wm_eddie

-1

Bạn có thể thử điều này:

mô tả 'Tên bảng'

Nó sẽ trả về tất cả các tên cột và kiểu dữ liệu

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.