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数据库中更改以上查询?我需要获取列名作为表'users'的结果集(不包括某些列),并指定一个模式。现在我所有的表都在新表空间中,因此我可以指定表空间名称代替模式名称吗?

还有通用的HQL吗?在我的新Oracle数据库(我是Oracle新手)中,我只有表空间名称,所以它等效于架构名称(逻辑上吗?)

Answers:


176

Oracle的等效项information_schema.COLUMNSUSER_TAB_COLS当前用户拥有的表ALL_TAB_COLSDBA_TAB_COLS所有用户拥有的表。

表空间不等同于架构,也不必提供表空间名称。

提供了架构/如果你想查询的用户名应该使用ALL_TAB_COLSDBA_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 2012年

我还必须添加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 '16

使用lower(TABLE_NAME)upper(TABLE_NAME)要求oracle对表进行表扫描ALL_TAB_COLUMNS以获取的所有值,TABLE_NAME然后才能将其与提供的值进行比较UPPER('MyTableName')。在快速测试中,这无法实现我的目的,因此我将坚持区分大小写的比较。
克里斯·马格努森

40

在甲骨文你可以使用

desc users

显示用户表中包含的所有列


6
...因为尽管它代表了“如何获取表中所有列的列表”的答案,但它并未回答所提出的问题:1)这不是查询,2)它没有限制/筛选返回的列,3)是否返回结果集?
Ehryk 2014年

6
缺乏upvotes并不能使desc users一个不好回答一些问题,但它不是一个很好的答案这一个
Ehryk 2014年

并且因为它不是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是一个对象关系映射,而您正在寻找的是元数据映射...您不会使用HQL,而是会使用API​​方法来实现此目的,也不会直接使用SQL。例如,您可以使用JDBC DatabaseMetaData

我认为表空间与架构无关。AFAIK表空间主要用于逻辑内部技术目的,这会打扰DBA。有关表空间的更多信息,请参见Oracle doc


TABLE_NAME='"+_db+".users'将失败; 您需要在ALL_TAB_COLUMNS
David Faber

2

我能够获取列名称的唯一方法是使用以下查询:

select COLUMN_NAME
FROM all_tab_columns atc
WHERE table_name like 'USERS'


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;->注意,这是查询结果,即结果集。这可以导出为其他格式。并且,您可以将查询结果导出为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 2012年

1
这个答案实际上帮助了我。我在Oracle模式下使用DB2,它不支持all_tab_cols。
wm_eddie

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.