Q:

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

I am new to SQL and SQL Server 2008 R2.  I have found a cursor based approach to find all columns in a particular table that contain null values, but I am hoping to find a simpler set-based solution. 
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

The above code currently returns all columns in myTable.  If I change the EXISTS clause to NOT EXISTS, it returns no columns.  The result should be a comma-separated string of column names that contain at least 1 null value. 
Thanks for your help

A:

Your code isn't working because the EXISTS subquery is just checking the name of your column isn't null, which it can't be.  The subquery doesn't expand out the "WHERE c.name IS NULL" into "WHERE MyColumnName IS NULL", it just sees that c.name = 'MyColumnName' which is not null and always returns false. 
The cursor based approach probably works by building a seperate string query for each column and then excuting the string. 
You could unpivot the table and look for nulls in that result set, i.e. 
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

