获取SQL Server中不具有NULL值的所有列的列表

时间:2014-05-30 19:39:42

标签: sql-server

我从不在SQL中做复杂的事情 - 直到现在......

我有一个包含超过2000个表的数据库,每个表有大约200列。

我需要获取其中一个表中至少填充一次的所有列的列表。

我可以获得所有列的列表:

SELECT [name] AS [Column name] 
FROM syscolumns with (nolock) 
WHERE id = (SELECT id FROM sysobjects where name like 'DOCSDB_TDCCINS')

但我只需要填充1次或更多次的列。

任何帮助都将不胜感激。

4 个答案:

答案 0 :(得分:1)

我将如何做到这一点,首先运行:

SELECT 'SELECT '''+syscolumns.name+''' FROM '+sysobjects.name+' HAVING COUNT('+syscolumns.name+') > 0'
FROM syscolumns with (nolock) 
JOIN sysobjects with (nolock) ON syscolumns.id = sysobjects.id
WHERE syscolumns.id = (SELECT id FROM sysobjects where name like 'Email')

复制所有select语句并运行它们。

这将为您提供一个没有空值的列名列表。

(nb我没有测试,因为我现在没有SQL服务器可用,所以我可能会输入错字)

答案 1 :(得分:0)

计算非空实例可能也很有用,显然0或不是0是你的初始问题,并且计算实例与存在不存在/存在将会更慢。

select 'union select ''' + Column_Name + ''',count(*)'
  + ' from ' + table_name
  + ' where ' + column_name + ' is not null'
from 
(
select * from information_schema.columns with (nolock)
    where Is_Nullable = 'YES'
AND Table_Name like 'DOCSDB_TDCCINS'
) DD

然后删除多余的前导“联合”并运行查询

答案 2 :(得分:0)

另一个想法是为每个表创建一个动态的unpivot。

Declare @q NVarchar(MAX) = NULL

;With D AS (
    SELECT TABLE_SCHEMA
         , TABLE_NAME
         , STUFF((SELECT ', ' + QUOTENAME(ci.COLUMN_NAME) 
                  FROM   INFORMATION_SCHEMA.COLUMNS ci
                  WHERE  (ci.TABLE_NAME = c.TABLE_NAME) 
                    AND  (ci.TABLE_SCHEMA = c.TABLE_SCHEMA)
                  FOR XML PATH(''),TYPE).value('.','NVARCHAR(MAX)')
               ,1,2,'') AS _Cols
         , STUFF((SELECT ', Count(' + QUOTENAME(ci.COLUMN_NAME) + ') ' 
                              + QUOTENAME(ci.COLUMN_NAME) 
                  FROM   INFORMATION_SCHEMA.COLUMNS ci
                  WHERE  (ci.TABLE_NAME = c.TABLE_NAME) 
                    AND  (ci.TABLE_SCHEMA = c.TABLE_SCHEMA)
                  FOR XML PATH(''),TYPE).value('.','NVARCHAR(MAX)')
               ,1,2,'') AS _ColsCount
    FROM INFORMATION_SCHEMA.COLUMNS c
    GROUP BY TABLE_SCHEMA, TABLE_NAME
)
SELECT @q = COALESCE(@q + ' UNION ALL ', '') + '
SELECT ''' + TABLE_SCHEMA + ''' _Schema, ''' + TABLE_NAME + ''' _Table, _Column 
FROM   (SELECT ' + _ColsCount + ' from ' + TABLE_SCHEMA + '.' + TABLE_NAME + ') x
       UNPIVOT 
       (_Count FOR _Column IN (' + _Cols + ')) u
WHERE  _Count > 0'
FROM D

exec sp_executesql @q

CTE _Cols中,以逗号分隔的表格列引用名称,而_ColsCount返回与COUNT函数相同的列表,例如我的一排表D

TABLE_SCHEMA | TABLE_NAME      | _Cols                        | _ColsCount
------------- ----------------- ------------------------------ -----------------------------------------------------------------------------
dbo          | AnnualInterests | [Product_ID], [Rate], [Term] | Count([Product_ID]) [Product_ID], Count([Rate]) [Rate], Count([Term]) [Term]

,而主查询在UNPIVOT中转换此行以返回行中的列

SELECT 'dbo' _Schema, 'AnnualInterests' _Table, _Column 
FROM   (SELECT Count([Product_ID]) [Product_ID], Count([Term]) [Term]
             , Count([Rate]) [Rate] from dbo.AnnualInterests) x
       UNPIVOT 
       (_Count FOR _Column IN ([Product_ID], [Term], [Rate])
WHERE  _Count > 0

使用字符串变量concatenation和sp_executesql来运行字符串,完成脚本。

答案 3 :(得分:0)

希望您可以通过对代码进行简单更改来实现这一目标,例如

SELECT [name] AS [Column name] 
FROM syscolumns with (nolock) 
WHERE id = (SELECT id FROM sysobjects where name like 'DOCSDB_TDCCINS')
and (select count(*) from DOCSDB_TDCCINS)>0