2016-09-23 4 views
1

Lasst uns sagen, dass ich eine Abfrage in SQL 2014 haben:Get Spaltennamen einer Abfrage in SQL Server

SELECT EmployeeName, EmployeeAddress, EmployeeAge FROM dbo.Employee 

I dynamisch die Abfrage, Schleife zu durchlaufen und erhalten den Namen der Spalten wie EmployeeName haben möchten, EmployeeAddress und EmployeeAge.

Ich brauche das, weil ich eine andere Abfrage als diese haben kann Ich brauche auch die Spaltennamen.

+0

siehe sys.tables und sys.columns. – scsimon

+0

Im Satz "Ich möchte dynamisch ..." können Sie bitte "Ich" definieren? Ich nehme an, Sie meinen Sie nicht, eine Person (da Sie die Spaltennamen mit Ihren Augen leicht scannen können). Sprechen Sie über ein Stück Code? In welcher Sprache ist es geschrieben und wie hat es die Ergebnismenge erhalten? –

+0

Möchten Sie die Spaltennamen des zugrunde liegenden Datenbankobjekts (d. H. Der Tabelle usw.) oder möchten Sie die Spaltennamen der Ergebnismenge der Abfrage (die willkürliche Legal-Identifier-Namen enthalten kann)? – SlimsGhost

Antwort

0

Sie können die Spaltennamen Ihrer talbes wie so finden ...

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 können Sie dies in einem Cursor wickeln Sie es für jeden Tabellennamen zu tun, oder entfernen Sie einfach das WHERE Klausel zu erhalten es für ALLE Tabellen

0

Nun, da die Abfrage komplizierte Ausdrücke haben kann, die zu "Spalten" -Namen aufgelöst werden, und sie können beliebige Namen haben (solange sie legale Bezeichner sind), schauen Sie sich einen String an. Parsing-Party!

Im Allgemeinen befindet sich ein Spaltenname/Alias ​​entweder am Ende des Spaltenausdrucks (vor dem Komma oder dem Beginn der FROM-Klausel), oder einige dbms erlauben auch "select myname = a + b, anothername = c + d, ... ", und Sie können normalerweise auch anonyme Spalten haben.

Noch in der äußersten select (alles vor der from), sollten Sie in der Lage sein, eine Teilung durch Komma und dann entweder nach der letzten Zeichenfolge "Token", die vor dem Komma (und mit "as" vorangestellt ist) oder einfach whitespace), und andernfalls können Sie nach dem Teil "colname =" als zweiten Durchgang suchen und dann als Failsafe die ersten n Zeichen des rohen Ausdrucks verwenden und diesen für Ihre "anonymen" Namen verwenden.

So funktioniert die Abfrage Parser schließlich, so ist es nicht unmöglich, aber ich würde nicht wollen, um es zu codieren! Die Komplexität, die benötigt wird, um jede rechtliche Anfrage abzudecken, wird entmutigend sein.

Für kichert, versuchen Sie nur diese Varianten der Parsing-Regeln denken:

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 
+2

Anstatt Strings für Wochen am Ende zu analysieren, könnten Sie einfach die Abfrage in eine temporäre Tabelle einfügen und dann die Spaltennamen aus tempdb.sys.columns lesen. :) –

+0

Ha! Ich spreche immer andere Dinge wie die Ausdrücke selbst, aber natürlich hast du recht, wenn du nur die Namen willst! Danke, dass du mich zurück in die Realität gebracht hast. – SlimsGhost

0

Dies wird eine durch Kommata getrennte Liste der Spalten für die Tabelle darin genannten zurückzukehren.

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 
) 
2

Die sp_describe_first_result_set gespeicherte Prozedur werden Sie die Spaltennamen geben und viel mehr für jede Abfrage. Sie müssen die fragliche Abfrage einfach an den Parameter @tsql übergeben. Bitte beachten Sie die folgende Verwendung der gespeicherten Prozedur:

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 
+0

Dies ist die einzige Antwort, die funktioniert und die Frage tatsächlich beantwortet – Laurence