查询基于用户提供的列名

时间:2012-02-27 00:49:52

标签: sql-server-2008

我有一个名为Student的表,其记录如下。

StudentId int PK NOT Null, 
Name Varchar(50),
Age int,
DateofBirth Datetime and 
ClassRecordID int NOT NULL
MajorID int NOT NULL

数据看起来像这样:

StudentID   Name      Age    Dateofbirth  ClassRecordID   MajorID
1234        Sam       21     1/10/1991        1122          1
1235        NULL      Null   1/12/1990        1123          2
1236        George    Null   NULL             1125          2
1237        Fanny     NULL   NULL             1155          1

我的要求是,

每当用户提供columnNameMajorID时,查询应从表中返回classRecordID,其中指定的columnName具有空值或空值。

例如,

当用户提供columnName = 'Age'MajorId = 2时,查询应返回1123和1125.

同样,当用户提供columnName = 'Dateofbirth'MajorId = 2时,查询应返回1125.

我尝试使用以下查询

Declare @ColumnName nvarchar(50)
Delcare @MajorId int

set @ColumnName = 'age' --for example
set @MajorId = 2 -- For example

SELECT DISTINCT TOP 10 
   ClassRecordID
FROM
   dbo.Student WITH (NOLOCK)
WHERE
   (@ColumnName IS NULL 
    OR LEN(LTRIM(RTRIM(@ColumnName))) = 0)
   AND 
   MajorId = @MajorId

但它返回空而不是预期的结果。这个查询有什么问题?有没有更好的方法来做到这一点?我不想使用IF else方法。

2 个答案:

答案 0 :(得分:2)

如果您真的希望能够按任意列进行过滤而无需在每次添加新列时扩展代码,则可以使用动态SQL和sp_executesql。此代码段应该适合您:

declare @nullFilterColumnName varchar(50)
set @nullFilterColumnName = 'Age'

declare @majorId int
set @majorId = 2

declare @sql nvarchar(max)
set @sql = 'select distinct ClassRecordID from Students where isnull('
    + quotename(@nullFilterColumnName)
    + ', '''') = '''' and MajorId = '
    + cast(@majorId as nvarchar(20))
exec sp_executesql @sql

但我建议使用此选项作为最后的手段。 @ron tornambe的版本更强大。

答案 1 :(得分:1)

我认为这种技巧是你所寻求的:

SELECT DISTINCT TOP 10 
    ClassRecordID
FROM
    dbo.Student WITH (NOLOCK)
WHERE
    1 = CASE WHEN @ColumnName = 'Age' THEN
            CASE WHEN Age IS NULL THEN 1 ELSE 0 END
        ELSE CASE WHEN @ColumnName = 'DateofBirth' THEN
            CASE WHEN DateOfBirth IS NULL THEN 1 ELSE 0 END
        END                    
AND MajorId = @MajorId