Nie wiem, czy jest to szybsze, ale możesz użyć jednej sztuczki:FOR XML AUTO
pominie kolumny bez zawartości:
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
Oto wynik:col3
brakuje...
<tbl col1="1" col2="2" />
<tbl col1="1" />
<tbl />
Wiedząc o tym, możesz znaleźć listę kolumn, które nie mają wartości NULL we wszystkich wierszach, tak jak poniżej:
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
Zawartość @ColList
to teraz col1,col2
. Ten ciąg można umieścić w dynamicznie tworzonym SELECT
.
AKTUALIZACJA:wskazówki
Byłoby bardzo sprytnie zamienić SELECT *
z listą kolumn utworzoną z INFORMATION_SCHEMA.COLUMNS
wykluczając wszystkie nie-nullable . Oraz – jeśli to konieczne i możliwe – typy, które zawierają bardzo duże dane (BLOB).
AKTUALIZACJA2:Wydajność
Nie wiem, jakie są Twoje bardzo duże dane oznacza właściwie... Po prostu wypróbowałem to na tabeli z około 500 000 wierszy (za pomocą SELECT *
) i wróciła poprawnie po mniej niż jednej minucie. Mam nadzieję, że to wystarczająco szybko...