【问题标题】:Oracle query to fetch column namesOracle 查询以获取列名
【发布时间】:2012-02-03 01:59:03
【问题描述】:

我有一个 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 新手),我只有表空间名称,所以它等同于模式名称(逻辑上?)

【问题讨论】:

    标签: sql oracle


    【解决方案1】:

    information_schema.COLUMNS 的 Oracle 等效项对于当前用户拥有的表是 USER_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 中通常是大写的;如果在它们周围使用双引号创建它们,它们只会是小写或混合大小写。

    【讨论】:

    • 顺便说一句,我发现了一种通用的方法,不管数据库如何通过 jdbc .. 链接在这里:kodejava.org/examples/163.html
    • 我还必须将and virtual_column = 'NO' 添加到我的查询中。
    【解决方案2】:

    以下查询在 Oracle 数据库中对我有用。

    select COLUMN_NAME from ALL_TAB_COLUMNS where TABLE_NAME='MyTableName';
    

    【讨论】:

    • 请记住,Oracle 区分大小写。我通常使用...WHERE LOWER(Table_Name) = 'mytablename';
    • @user565869 我会使用where lower(TABLE_NAME) = lower('WHATEVER'),否则当表名有一些大写字符时也找不到表
    • SELECT column_name FROM all_tab_cols WHERE UPPER(Table_Name) = UPPER('tablename'); 也可以。
    • 使用lower(TABLE_NAME)upper(TABLE_NAME) 需要oracle 对ALL_TAB_COLUMNS 表进行表扫描以获取TABLE_NAME 的所有值,然后才能将其与提供的UPPER('MyTableName') 进行比较。在快速测试中,这使得性能无法用于我的目的,因此我将坚持区分大小写的比较。
    • Oracle 以大写形式存储对象名称。利用这一事实。如果您需要“翻译”大小写,请翻译用户输入的大小写 - 而不是 Oracle 对象名称。 IE。 WHERE table_name = UPPER('my_table_name')。如果这是一段较大代码的一部分,您应该在将用户输入 传递给 WHERE 条件之前将其大写。
    【解决方案3】:

    在oracle中你可以使用

    desc users
    

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

    【讨论】:

    • ... 因为虽然它代表了“如何获取表中所有列的列表”的答案,但它没有回答所提出的问题:1)它不是查询, 2)它不限制/过滤返回的列,3)它是否返回结果集?
    • 缺乏支持并不会使desc users 成为对某些问题的不好回答,但对于这个来说却不是一个好回答。
    • 因为它不是 sql 查询,而是 sql* plus 命令。查看更多信息:stackoverflow.com/questions/37133666/…
    【解决方案4】:

    你可以试试这个:(它适用于 11g,它返回一个表中的所有列名,这里 test_tbl 是表名,user_tab_columns 是用户允许的表的列)

    select  COLUMN_NAME  from user_tab_columns
    where table_name='test_tbl'; 
    

    【讨论】:

    • USER_TAB_COLUMNS实际上是用户拥有的表的列,而不是用户允许的表的列。
    【解决方案5】:

    关键是在 toad 中你必须将表名写成大写,像这样:

    select *
    FROM all_tab_columns
    where table_name like 'IDECLARATION';
    

    【讨论】:

      【解决方案6】:

      与 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中分离所有者/模式和表名
      【解决方案7】:

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

      select COLUMN_NAME
      FROM all_tab_columns atc
      WHERE table_name like 'USERS'
      

      【讨论】:

        【解决方案8】:

        在某些情况下,我们需要以逗号分隔的模式中表中的所有列的列表。在这种情况下,我们可以使用这个通用函数来获取逗号分隔的列表作为字符串。

        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
        

        注意:如果所有列的总长度超过4000 字符,LISTAGG 将失败,这种情况很少见。在大多数情况下,这将起作用。

        【讨论】:

          【解决方案9】:

          我发现这个在 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;
          

          【讨论】:

          • 如果有多个同名但所有者不同的表怎么办?
          【解决方案10】:
          1. SELECT * FROM <SCHEMA_NAME.TABLE_NAME> WHERE ROWNUM = 0; --> 注意,这是Query Result,一个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> --> 注意:这是脚本输出。

          【讨论】:

            【解决方案11】:

            您可以使用以下查询来获取使用 DB2 中特定列的表名列表:

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

            注意:这里将COLUMN_NAME 替换为您要搜索的列名。

            【讨论】:

            • 也许您应该寻找 DB2 问题来回答?我怀疑搜索 Oracle 的人是否需要 DB2 的答案。
            • 这个答案实际上帮助了我。我在 Oracle 模式下使用 DB2,它不支持 all_tab_cols。
            【解决方案12】:

            你可以试试这个:

            描述“表名”

            它将返回所有列名和数据类型

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 2021-12-26
              • 2011-05-09
              • 1970-01-01
              相关资源
              最近更新 更多