これが速いかどうかはわかりませんが、FOR XML AUTO
という1つのトリックを使用できます。 コンテンツのない列を省略します:
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
結果は次のとおりです:col3
行方不明です...
<tbl col1="1" col2="2" />
<tbl col1="1" />
<tbl />
これを知っていると、次のように、すべての行でNULLではない列のリストを見つけることができます。
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
@ColList
のコンテンツ 現在はcol1,col2
です 。この文字列は、動的に作成されたSELECT
に配置できます 。
更新:ヒント
SELECT *
を置き換えるのは非常に賢いでしょう INFORMATION_SCHEMA.COLUMNS
から作成された列リスト null許容でないすべてを除外する 。そして、必要に応じて、可能であれば、非常に大きなデータ(BLOB)を含むタイプ。
UPDATE2:パフォーマンス
非常に大きなデータが何であるかわからない は実際に...約500.000行のテーブルでこれを試してみました(SELECT *
を使用) )そしてそれは1分未満後に正しく戻りました。うまくいけば、これは十分に速いです...