Ik weet niet of dit sneller is, maar je zou een truc kunnen gebruiken:FOR XML AUTO
zal kolommen zonder inhoud weglaten:
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
Dit is het resultaat:col3
ontbreekt...
<tbl col1="1" col2="2" />
<tbl col1="1" />
<tbl />
Als u dit weet, kunt u de lijst met kolommen, die niet in alle rijen NULL zijn, als volgt vinden:
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
De inhoud van @ColList
is nu col1,col2
. Deze string kun je plaatsen in een dynamisch aangemaakte SELECT
.
UPDATE:tips
Het zou heel slim zijn om de SELECT *
. te vervangen met een kolomlijst gemaakt op basis van INFORMATION_SCHEMA.COLUMNS
exclusief alle niet-nullable . En - indien nodig en mogelijk - typen, die zeer grote gegevens (BLOB's) bevatten.
UPDATE2:Prestaties
Weet niet wat uw zeer grote gegevens betekent eigenlijk... Ik heb dit net geprobeerd op een tafel met ongeveer 500.000 rijen (met SELECT *
) en het keerde correct terug na minder dan een minuut. Hoop, dit is snel genoeg...