如何从SELECT查询(而不是表)中显示COLUMNS?

时间:2010-09-15 09:47:44

标签: java mysql database-metadata

运行以下内容时出现语法错误:

show columns from (select * from (select * from my_table) as T)

如何显示我编写的查询中的列,而不是表格中的列?

5 个答案:

答案 0 :(得分:7)

方法1:临时表

已经发布的关于使用临时表的答案通常是最合适的解决方案。但有一点很重要,如果查询按原样运行,将处理所有连接等,在某些情况下可能需要很长时间。幸运的是,MySQL允许LIMIT 0不返回任何行,而documentation表示此"会快速返回空集"。以下存储过程将通过将SQL查询字符串作为输入,使用LIMIT 0包装它,运行动态查询以生成临时表然后显示其列来为您完成此任务:

CREATE PROCEDURE showColumns(IN sqlToShow TEXT)
BEGIN
    DROP TEMPORARY TABLE IF EXISTS tempTable;
    SET @sqlLimit0 = CONCAT('CREATE TEMPORARY TABLE tempTable AS (SELECT * FROM (',
                            sqlToShow, ') subq LIMIT 0)');
    PREPARE stmt FROM @sqlLimit0;
    EXECUTE stmt;
    DEALLOCATE PREPARE stmt;
    SHOW COLUMNS FROM tempTable;
END;

重要的一点是传入的查询最后不应该有一个分号。 (如有必要,可以修改存储过程以删除尾随的分号,但我想保持简单。)

这是一个现场演示,展示了它的实际效果:http://rextester.com/NVWY58430

方法2:INFORMATION_SCHEMA.COLUMNS

SHOW COLUMNS返回的相同信息也可以直接从INFORMATION_SCHEMA.COLUMNS表中获取:

SELECT TABLE_NAME AS `Table`,
       COLUMN_NAME AS `Field`,
       COLUMN_TYPE AS `Type`,
       IS_NULLABLE AS `Null`,
       COLUMN_KEY AS `Key`, 
       COLUMN_DEFAULT AS `Default`,
       EXTRA AS `Extra`
FROM `INFORMATION_SCHEMA`.`COLUMNS`
WHERE `TABLE_SCHEMA` = SCHEMA() -- This uses the current schema
  AND `TABLE_NAME` IN ('table1', 'table2', 'etc.');
   -- ...or could go even further and restrict to particular columns in tables if desired

上述问题的缺点是需要手动输入表(和可选的列)名称,而不是在SELECT中显示别名,但它完成了基本工作。它的优点是它不需要用户拥有创建临时表的权限,并且可以扩展返回的信息以提供进一步的列信息,例如最大字符长度,数字精度/比例,列注释等。

答案 1 :(得分:5)

  

我正在使用Java从MySql查询中检索列。

Java中获取结果集列信息的最佳方法是使用ResultSetMetaData接口:

PreparedStatement stmt = null;
ResultSet result = null;
ResultSetMetaData meta = null;

try {
    stmt = con.prepareStatement("SELECT * FROM MyTable"); 
    result = stmt.executeQuery();
} catch (SQLException e) {
    System.out.println("SQLException: "+e.getMessage());
    System.exit(1);
}
System.out.println("Successful query");

try {
    meta = result.getMetaData();
    System.out.println("Total columns: " + meta.getColumnCount());
    System.out.println("Name of column 1: " + meta.getColumnName(1));
    System.out.println("Type of column 1: " + meta.getColumnTypeName(1));

    System.out.println("Name of column 2: " + meta.getColumnName(2));
    System.out.println("Type of column 2: " + meta.getColumnTypeName(2));
} catch (SQLException e) {
    System.out.println("SQLException: "+e.getMessage());
    System.exit(1);
}
System.out.println("Successful metadata report");

我的桌子被宣布:

CREATE TABLE `MyTable` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
  `name` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
);

我的示例Java代码的输出:

Successful query
Total columns: 2
Name of column 1: id
Type of column 1: BIGINT UNSIGNED
Name of column 2: name
Type of column 2: VARCHAR
Successful metadata report

除了名称和数据类型之外,您还可以获得有关结果集列的其他信息。有关ResultSetMetaData接口的完整参考文档,请参阅http://docs.oracle.com/javase/8/docs/api/java/sql/ResultSetMetaData.html

答案 2 :(得分:4)

看起来这个语句只接受现有的表。

所以我用我的查询创建了一个新的临时表,并从那里得到了列名。

/*if the exporting table was created before, then delete it*/
DROP TABLE IF EXISTS exportTable;

/*create the temporary table (check if you have mySQL permission to do so)*/
CREATE TEMPORARY TABLE exportTable AS (your_query);

/*get result table (this is a table, the columns names are in the first column of this table ['Field'])*/
SHOW COLUMNS FROM exportTable;

临时表在会话上下文中创建,并在会话关闭时进行droped。对于SHOW COLUMNS表也是如此。您可以考虑这些表创建对服务器磁盘的影响。

  

创建表时可以使用TEMPORARY关键字。 TEMPORARY表仅对当前会话可见,并在会话关闭时自动删除。这意味着两个不同的会话可以使用相同的临时表名,而不会相互冲突或与现有会话冲突非TEMPORARY同名表。 (在删除临时表之前,将隐藏现有表。)要创建临时表,您必须具有CREATE TEMPORARY TABLES权限。

http://dev.mysql.com/doc/refman/5.7/en/create-table.html

答案 3 :(得分:0)

我使用类似这样的东西:

create procedure showFields(s text)
begin
set @showfields_var:=concat('create temporary table tmp_showfields as select * from (',s,')a where 0'); 
prepare phrase from @showfields_var;execute phrase;
show columns from tmp_showfields;
drop temporary table tmp_showfields;
end

答案 4 :(得分:-1)

试试这个 -

SHOW COLUMNS FROM (select * from my_table) T

或直接SHOW COLUMNS FROM my_table