Reputation: 755
Let's say I have a query in SQL 2014:
SELECT EmployeeName, EmployeeAddress, EmployeeAge FROM dbo.Employee
I would like to dynamically go through the query, loop and get the name of the columns like EmployeeName
, EmployeeAddress
, and EmployeeAge
.
I need this because I can have another query different than this I need to get the column names as well.
Upvotes: 4
Views: 7487
Reputation: 1739
The sp_describe_first_result_set
stored procedure will give you the column names and much more for any query. You simply need to pass the query in question to the @tsql
parameter.
Please see below example use of the stored procedure:
DECLARE @queryDescription TABLE
(
s_hidden bit NULL
,column_ordinal int NULL
,name sysname NULL
,is_nullable bit NULL
,system_type_id int NULL
,system_type_name nvarchar(256) NULL
,max_length smallint NULL
,precision tinyint NULL
,scale tinyint NULL
,collation_name sysname NULL
,user_type_id int NULL
,user_type_database sysname NULL
,user_type_schema sysname NULL
,user_type_name sysname NULL
,assembly_qualified_type_name nvarchar(4000) NULL
,xml_collection_id int NULL
,xml_collection_database sysname NULL
,xml_collection_schema sysname NULL
,xml_collection_name sysname NULL
,is_xml_document bit NULL
,is_case_sensitive bit NULL
,is_fixed_length_clr_type bit NULL
,source_server sysname NULL
,source_database sysname NULL
,source_schema sysname NULL
,source_table sysname NULL
,source_column sysname NULL
,is_identity_column bit NULL
,is_part_of_unique_key bit NULL
,is_updateable bit NULL
,is_computed_column bit NULL
,is_sparse_column_set bit NULL
,ordinal_in_order_by_list smallint NULL
,order_by_list_length smallint NULL
,order_by_is_descending smallint NULL
,tds_type_id int NULL
,tds_length int NULL
,tds_collation_id int NULL
,tds_collation_sort_id tinyint NULL
)
DECLARE @query NVARCHAR(MAX) = 'SELECT EmployeeName, EmployeeAddress, EmployeeAge FROM dbo.Employee'
INSERT INTO @queryDescription
EXEC sp_describe_first_result_set @tsql = @query
SELECT Name AS ColumnName
,system_type_name AS DataTypeName
,column_ordinal AS Ordinal
FROM @queryDescription
Upvotes: 5
Reputation: 384
This will return a comma-delimited list of the columns for the table named therein.
SELECT
(
SELECT DISTINCT STUFF( ( SELECT ',' + isc.name + ''
FROM sys.columns isc
WHERE OBJECT_NAME(isc.object_id) = 'TableName' FOR XML PATH('') ), 1,1,'')
AS SqlScript
)
Upvotes: 1
Reputation: 2909
Well, since the query can have complicated expressions that get resolved to "column" names, and they can have arbitrary names (as long as they're legal identifiers), you are looking at a string-parsing party!
Generally, a column name/alias will be either at the end of the column expression (before the comma or the start of the FROM clause), or some dbms allow you to also do "select myname=a+b, anothername=c+d, ...", and you can usually have anonymous columns as well.
Still, in the outermost select
(everything before the from
), you should be able to do a split by comma and then look for either the last string "token" that is before the comma (and preceded by "as" or just whitespace), and failing that you can look for the "colname=" part as a second pass, and then as a failsafe take the first n chars of the raw expression and use that for your "anonymous" names.
This is how the query parsers work after all, so it's not impossible, but I wouldn't want to have to code it! The complexity required to cover any legal query is going to be daunting.
For giggles, try thinking of the parsing rules for just these variants:
select col1 as NOTCOL1, col2 from table
select col1 + 1, col3=col2 from table
with x as (
select something from somewhere
)
select something as [Something with spaces for good measure] from x
select a.x, (b.col1) "look, a rainbow!"
from (
select col1 as x
from reused_table
) a
cross join reused_table b
Upvotes: 0
Reputation: 25112
You can find the column names of your talbes like so...
select t.name as TableName, c.Name as ColumnName
from sys.tables t
inner join sys.columns c on c.object_id = t.object_id
where t.name = 'yourTable'
So, you can wrap this in a cursor to do it for each table name, or just remove the WHERE
clause to get it for ALL tables
Upvotes: 0