テーブルと列名がわかっている場合は、次のようになります。
DECLARE @tn sysname;
SELECT @tn = TYPE_NAME(system_type_id)
FROM sys.columns
WHERE name = @column_name
AND [object_id] = OBJECT_ID(N'dbo.tablename');
IF @tn = N'nvarchar'
DECLARE @x nvarchar(32);
IF @tn = N'int'
DECLARE @i int;
ただし、SQL Server がそれらの 1 つにしか到達しない場合でも、この方法では異なるデータ型で同じ変数名を宣言することはできないことに注意してください。次のようなものが得られます。
メッセージ 134、レベル 15、状態 1
変数名 '@i' は既に宣言されています。変数名は、クエリ バッチまたはストアド プロシージャ内で一意である必要があります。
テーブルの名前がわかっている場合は、次のように提案するような動的 SQL ステートメントを作成できます (これは型のサブセットのみをカバーすることに注意してください - ただし、アイデアを提供する必要があります)。
DECLARE @table nvarchar(512) = N'dbo.whatever';
DECLARE @sql nvarchar(max) = N'SELECT ';
SELECT @sql = @sql
+ STUFF((SELECT N',' + QUOTENAME(c.name) + N' = COALESCE('
+ QUOTENAME(c.name) + N',' + CASE
WHEN t.name LIKE N'%int' THEN N'0'
WHEN t.name LIKE N'%char' THEN N''' '''
END + N')'
FROM sys.types AS t
INNER JOIN sys.columns AS c
ON t.system_type_id = c.system_type_id
AND t.user_type_id = c.user_type_id
WHERE c.[object_id] = OBJECT_ID(@table)
ORDER BY c.column_id
FOR XML PATH(''),
TYPE).value(N'./text()[1]', N'nvarchar(max)'), 1, 1, N'');
SET @sql = @sql + N' FROM ' + @table;
--SET @sql = @sql + N' WHERE...'
EXEC sys.sp_executesql @sql;
動的 SQL なしでこれを行うことをどのように夢見ることができるかわかりません。そして、プレゼンテーション層が NULL を処理する必要がないようにするのは大変な作業です。それはおそらくこれに対処するためのより良い場所です。