Jeg ved ikke, om dette er hurtigere, men du kan bruge et trick:FOR XML AUTO
vil udelade kolonner uden indhold:
DECLARE @tbl TABLE(col1 INT,col2 INT,col3 INT);
INSERT INTO @tbl VALUES (1,2,NULL),(1,NULL,NULL),(NULL,NULL,NULL);
SELECT *
FROM @tbl AS tbl
FOR XML AUTO
Dette er resultatet:col3
mangler...
<tbl col1="1" col2="2" />
<tbl col1="1" />
<tbl />
Når du ved dette, kan du finde listen over kolonner, som ikke er NULL i alle rækker, sådan her:
DECLARE @ColList VARCHAR(MAX)=
STUFF
(
(
SELECT DISTINCT ',' + Attr.value('local-name(.)','nvarchar(max)')
FROM
(
SELECT
(
SELECT *
FROM @tbl AS tbl
FOR XML AUTO,TYPE
) AS TheXML
) AS t
CROSS APPLY t.TheXML.nodes('/tbl/@*') AS A(Attr)
FOR XML PATH('')
),1,1,''
);
SELECT @ColList
Indholdet af @ColList
er nu col1,col2
. Denne streng kan du placere i en dynamisk oprettet SELECT
.
OPDATERING:Tip
Det ville være meget smart at erstatte SELECT *
med en kolonneliste oprettet fra INFORMATION_SCHEMA.COLUMNS
ekskluderer alle ikke-nullable . Og - hvis nødvendigt og muligt - typer, som indeholder meget store data (BLOB'er).
OPDATERING 2:Ydeevne
Ved ikke, hvad dine meget store data betyder faktisk... Har lige prøvet dette på en tabel med omkring 500.000 rækker (med SELECT *
), og den vendte tilbage korrekt efter mindre end et minut. Håber, det er hurtigt nok...