Jag vet inte om detta är snabbare, men du kan använda ett knep:FOR XML AUTO
kommer att utelämna kolumner utan innehåll:
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
Detta är resultatet:col3
saknas...
<tbl col1="1" col2="2" />
<tbl col1="1" />
<tbl />
När du vet detta kan du hitta listan över kolumner som inte är NULL i alla rader, så här:
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
Innehållet i @ColList
är nu col1,col2
. Denna sträng kan du placera i en dynamiskt skapad SELECT
.
UPPDATERING:Tips
Det skulle vara mycket smart att ersätta SELECT *
med en kolumnlista skapad från INFORMATION_SCHEMA.COLUMNS
exklusive alla icke-nullbara . Och - om det behövs och är möjligt - typer som innehåller mycket stora data (BLOBs).
UPPDATERING2:Prestanda
Vet inte vad din mycket stora data betyder faktiskt... Testade precis detta på en tabell med cirka 500 000 rader (med SELECT *
) och det returnerade korrekt efter mindre än en minut. Hoppas, det här är tillräckligt snabbt...