我刚刚完成了使用数据加载新表的过程。我目前正在尝试验证数据。我设计数据库的方式确实不应该是NULL
的任何值,所以我试图找到所有NULL
值的行。
是否有一种快速简便的方法来执行此操作,而不是编写冗长的WHERE
子句,并使用OR
语句检查每列?
更新:更多细节...... NULL
值最初有效,因为有时数据丢失。它只是帮助我找出我需要在其他地方寻找的数据。我的一些表有50多列,因此写出整个WHERE
子句并不方便。
答案 0 :(得分:4)
针对Information_Schema.Columns
(documentation)编写一个查询,为您的if子句输出SQL。
这里有一些东西让你入门:
select 'OR ([' + TABLE_NAME + '].[' + TABLE_SCHEMA + '].[' + COLUMN_NAME + '] IS NULL)'
from mydatabase.Information_Schema.Columns
order by TABLE_NAME, ORDINAL_POSITION
答案 1 :(得分:1)
短版本答案,使用SET CONCAT_NULL_YIELDS_NULL ON并将整个事物作为字符串打包并检查是否为NULL(一次)。这样任何null都会传播,使整行比较为空。
这里是演示主体的愚蠢示例代码,如果您想将其包装在自动生成模式脚本中(仅检查Nullable列并执行所有适当的转换),由您决定。效率很高,但几乎任何削减方式都需要进行表格扫描。
CREATE TABLE dbo.Example
(
PK INT PRIMARY KEY CLUSTERED IDENTITY(1,1),
A nchar(10) NULL,
B int NULL,
C nvarchar(50) NULL
) ON [PRIMARY]
GO
INSERT dbo.Example(A, B, C)
VALUES('Your Name', 1, 'Not blank'),
('My Name', 3, NULL),
('His Name', NULL, 'Not blank'),
(NULL, 5, 'It''s blank');
SET CONCAT_NULL_YIELDS_NULL ON
SELECT E.PK
FROM dbo.Example E
WHERE (E.A + CONVERT(VARCHAR(32), E.B) + E.C) IS NULL
SET CONCAT_NULL_YIELDS_NULL OFF
答案 2 :(得分:0)
正如评论中所提到的,如果你真的希望列不为null,那么就会对它们加上NOT NULL
约束。那说......
这是一种略有不同的方法,使用INFORMATION_SCHEMA
:
DECLARE @sql NVARCHAR(max) = '';
SELECT @sql = @sql + 'UNION ALL SELECT ''' + cnull.TABLE_NAME + ''' as TableName, '''
+ cnull.COLUMN_NAME + ''' as NullColumnName, '''
+ pk.COLUMN_NAME + ''' as PkColumnName,' +
+ 'CAST(' + pk.COLUMN_NAME + ' AS VARCHAR(500)) as PkValue '
+ ' FROM ' + cnull.TABLE_SCHEMA + '.' + cnull.TABLE_NAME
+ ' WHERE ' +cnull.COLUMN_NAME + ' IS NULL '
FROM INFORMATION_SCHEMA.COLUMNS cnull
INNER JOIN (SELECT Col.Column_Name, col.TABLE_NAME, col.TABLE_SCHEMA
from INFORMATION_SCHEMA.TABLE_CONSTRAINTS Tab
INNER JOIN INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE Col
ON Col.Constraint_Name = Tab.Constraint_Name AND Col.Table_Name = Tab.Table_Name
WHERE CONSTRAINT_TYPE = 'PRIMARY KEY') pk
ON pk.TABLE_NAME = cnull.TABLE_NAME AND cnull.TABLE_SCHEMA = pk.TABLE_SCHEMA
WHERE cnull.IS_NULLABLE = 'YES'
set @sql = SUBSTRING(@sql, 11, LEN(@sql)) -- remove the initial 'UNION ALL '
exec(@sql)
而是一个巨大的where子句,这将告诉您表中的主键,该表中的任何字段为null。请注意,如果您有一些CAST
/ int
/ varchar
等,我uniqueidentifier
所有主键值都可以避免操作数冲突。如果您有PK,不适合VARCHAR(500)
您可能还有其他问题......
如果您有任何具有复合主键的表,这可能需要一些调整 - 因为它是,我很确定它只会为键的每个成员输出单独的行而不是连接它们,并且不一定按照你想要的方式将它们组合在一起。
另一个想法只是来自任何表SELECT *
并将输出保存为格式(Excel,纯文本csv),您可以轻松搜索字符串NULL
。