簡體   English   中英

基於集合的查詢,以查找表中包含至少一個空值的所有列

[英]Set-based query to find all columns in table that contain at least one null value

我是SQL和SQL Server 2008 R2的新手。 我找到了一種基於游標的方法來查找特定表中包含空值的所有列,但我希望找到一個更簡單的基於集合的解決方案。

USE QC_TEST

DECLARE @colName nvarchar(100)
DECLARE @nullCols nvarchar(max)

SELECT @colName = c.name, @nullCols = COALESCE(@nullCols+', ','')+@colName
FROM sys.tables AS t
    JOIN sys.columns AS c
        ON t.object_id = c.object_id
WHERE t.name = 'myTable' 
AND 
EXISTS(SELECT * FROM myTable WHERE c.name IS NULL)

SELECT @colName, @nullCols

上面的代碼當前返回myTable所有列。 如果我將EXISTS子句更改為NOT EXISTS ,則不返回任何列。 結果應該是以逗號分隔的列名字符串,其中包含至少1個空值。

謝謝你的幫助

你可以用這種方式得到一個結果

declare @sql varchar(max), @t varchar(max);
set @t = 'your_table';
select @sql = (select stuff(
    (select 
            '] is null union select ''' + c.name + 
            ''' from ' + @t + ' where [' + c.name
        from
            (select
                    c.name
                from sys.tables AS t
                inner join sys.columns AS c
                    ON t.object_id = c.object_id
                where
                    t.name = @t
            ) as c
        for xml path('')
    ), 1, 16, '' ) + '] is null' )
;
exec(@sql);

但我不知道你真的認為那更好。

您的代碼無法正常工作,因為EXISTS子查詢只是檢查列的名稱是否為空,這是不可能的。 子查詢不會將“WHERE c.name IS NULL”擴展為“WHERE MyColumnName IS NULL”,它只會看到c.name ='MyColumnName',它不是null並且始終返回false。

基於游標的方法可能通過為每列構建單獨的字符串查詢然后激活字符串來工作。

您可以將表格取消,並在該結果集中查找空值,即

WITH myTable_unpvt AS (
    SELECT ContactID, FieldName, FieldValue
    FROM 
       (SELECT ContactID
            , cast(Forename as sql_variant) Forename
            , cast(Surname as sql_variant) Surname
            , cast(Extn as sql_variant) Extn
            , cast(Email as sql_variant) Email
            , cast(Age as sql_variant) Age
       FROM myTable) p
    UNPIVOT
       (FieldValue FOR FieldName IN 
          (Forename, Surname, Extn, Email, Age)
    ) AS myTable_unpvt
)

SELECT DISTINCT FieldName FROM myTable_unpvt WHERE FieldValue IS NULL

這有點不同尋常,但試試這個:

--set up test table
--the BEGIN TRY and ALTERs allow you to rerun entire script over and over again
BEGIN TRY
    CREATE TABLE YourTable (PK int not null primary key, RowValue1 int null, RowValue2 varchar(5) null, RowValue3 datetime)
END TRY
BEGIN CATCH END CATCH
delete YourTable
ALTER TABLE YourTable ALTER COLUMN RowValue1 int  NULL
ALTER TABLE YourTable ALTER COLUMN RowValue2 varchar(5)  NULL
ALTER TABLE YourTable ALTER COLUMN RowValue3 datetime  NULL

--setup test data
INSERT INTO YourTable VALUES  (1,1111,'AAAA',GETDATE())
INSERT INTO YourTable VALUES  (2,2222,'BBBB',GETDATE())
INSERT INTO YourTable VALUES  (3,3333,'CCCC',GETDATE())
INSERT INTO YourTable VALUES  (4,NULL,'DDDD',GETDATE())
INSERT INTO YourTable VALUES  (5,5555,'EEEE',NULL)

--determine null columns
DECLARE @BadColumns  varchar(50)

BEGIN TRY
    ALTER TABLE YourTable ALTER COLUMN RowValue1 int NOT NULL
END TRY
BEGIN CATCH
    SET @BadColumns=ISNULL(@BadColumns+', ','')+'RowValue1'
END CATCH    
----------------------------------
BEGIN TRY
    ALTER TABLE YourTable ALTER COLUMN RowValue2 varchar(5) NOT NULL
END TRY
BEGIN CATCH
    SET @BadColumns=ISNULL(@BadColumns+', ','')+'RowValue2'
END CATCH  
----------------------------------
BEGIN TRY
    ALTER TABLE YourTable ALTER COLUMN RowValue3 datetime NOT NULL
END TRY
BEGIN CATCH
    SET @BadColumns=ISNULL(@BadColumns+', ','')+'RowValue3'
END CATCH  

--report null columns
SELECT @BadColumns AS [Columns having NULLs]

OUTPUT:

Columns having NULLs
--------------------------------------------------
RowValue1, RowValue3

(1 row(s) affected)

如果您因為不知道列名而需要變為動態,則可以在字符串中構建類似的命令,然后執行該命令。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM