Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get schema of the result returned by select query

Can we get schema of the result returned by SELECT Query? Below code:

string SQLQuery = "SELECT DISTINCT c.name 'Column Name',  t.Name 'Data type' FROM" +
                   " sys.columns c INNER JOIN " +
                   " sys.types t ON c.system_type_id = t.system_type_id" +
                   " LEFT OUTER JOIN " +
                   " sys.index_columns ic ON ic.object_id = c.object_id AND ic.column_id = c.column_id" +
                   " LEFT OUTER JOIN" +
                   " sys.indexes i ON ic.object_id = i.object_id AND ic.index_id = i.index_id" +
                   " WHERE" +
                   " c.object_id = OBJECT_ID('[DB].[dbo].[" + ddlTable.SelectedItem.Text + "]') AND t.name <> 'sysname'";

This code returns column names along with datatype for specified table. My requirement is to get column names along with datatype from a select query rather than directly specifying table name. like

  string SQLQuery = "SELECT DISTINCT c.name 'Column Name',  t.Name 'Data type' FROM" +
                       " sys.columns c INNER JOIN " +
                       " sys.types t ON c.system_type_id = t.system_type_id" +
                       " LEFT OUTER JOIN " +
                       " sys.index_columns ic ON ic.object_id = c.object_id AND ic.column_id = c.column_id" +
                       " LEFT OUTER JOIN" +
                       " sys.indexes i ON ic.object_id = i.object_id AND ic.index_id = i.index_id" +
                       " WHERE" +
                       " c.object_id = OBJECT_ID('SELECT col1, col2 from table(s)') AND t.name <> 'sysname'";

Though this doesn't work.

like image 334
vikbehal Avatar asked Feb 21 '14 08:02

vikbehal


People also ask

How do I find the schema of a table in SQL query?

To show the schema, we can use the DESC command. This gives the description about the table structure.

How can I see the schema of a view?

Click on a worksheet to see it in the Schema Viewer. If the schema view is not showing the schema behind the worksheet, double-click the tab on the top right of the worksheet object. The worksheet view shows the following information: All tables in the worksheet, and the relationships between these tables.


2 Answers

You can SELECT the query result INTO a temporary table, and from that table get the metadata. If you choose a solution like this you will need to make sure that the name of the temporary table is UNIQUE per call, otherwise meta-data in information_schema views will be shared across the sessions.

if OBJECT_ID('tempdb..#tmp') is not null drop table #tmp

select * 
into #tmp
from Customer where 1 = 0 
-- select with a false predicate in order to ONLY get
--     metadata of the query and no rows of data.

select * from #tmp
-- Then select metadata from information_schema view
select COLUMN_NAME, DATA_TYPE from tempdb.information_schema.columns where TABLE_NAME like '#tmp%'

Result:
CustomerId  int
CustomerType    int
Name    nvarchar
IsActive    bit

Or, if you want you can do it easier In C# which will probably less error prone. It is very easy to get the meta-data for a result set of a query:

static void Main(string[] args)
        {
            string connStr = "Data Source=localhost;Initial Catalog=AdventureWorks;Integrated Security=True";
            SqlCommand cmd = new SqlCommand("select * from Orders where 1 = 0", new SqlConnection(connStr));

            SqlDataAdapter ad = new SqlDataAdapter(cmd);

            DataSet ds = new DataSet();
            ad.FillSchema(ds, SchemaType.Mapped);
            var metaTable = ds.Tables[0];

            foreach (DataColumn col in metaTable.Columns)
            {
                Console.WriteLine("{0} : {1}", col.DataType, col.ColumnName);
            }

         }

Output:

System.Int32 : OrderId
System.Int32 : CustomerId
System.Int32 : ArticleId
System.Decimal : TotalAmount
System.DateTime : OrderDate
like image 183
Peter Henell Avatar answered Sep 25 '22 16:09

Peter Henell


I know this question targeted SQL 2008 but it's handy to know for 2012+ there's an inbuilt stored procedure called sp_describe_first_result_set that will get the desired results.

See the docs

like image 25
Jeff Avatar answered Sep 24 '22 16:09

Jeff