SQL动态WHERE子句

时间:2012-07-20 14:58:43

标签: sql sql-server-2008 dynamic-sql

全部,我有一个名为Foo的下表,它是复杂PIVOT查询的输出

Example Result Set

我需要删除此表中具有(DB1,DB2,DB3)全部NULL的行。为此通常我们可以使用

之类的东西
DELETE FROM Foo 
WHERE [DB1] IS NULL 
  AND [DB2] IS NULL 
  AND [DB3] IS NULL;

但问题是这个代码是从C#调用的,而列(DB1,DB2,DB3)将从执行变为执行。

如何动态执行此操作?

感谢您的时间。

Edit1。我有另一个表Bar,其中包含可用的DB#列,因此可以使用此表SELECT DISTINCT ...来获取我在WHERE子句中需要的列列表。但是,我以前从未这样做过,也不确定从哪里开始......感谢任何帮助。

EDIT2。我不能以任何方式使用C#。 C#代码是SQL的解析器,可以使用给定的.sql文件。这必须完全在SQL中完成。

4 个答案:

答案 0 :(得分:1)

您可以使用StringBuilder动态构建WHERE子句,假设C#代码知道输出中应该存在的列。

通常,当您这样做时,您希望在动态WHERE子句中包含参数占位符,并动态地向查询添加参数以避免SQL注入。但是,在这种情况下,没有变量值。只需在C#中动态连接WHERE子句的各个部分。

答案 1 :(得分:1)

sp_executesql允许您执行在SQL脚本中构建的SQL字符串。

http://msdn.microsoft.com/en-us/library/ms188001.aspx

从酒吧表

create proc DumpFooJunk 
as
begin 
    declare @strCols nvarchar(max)
    select @strCols = N''
    select @strCols = @strCols + ' AND ' + name + ' IS NULL ' from [bar]
    select @strCols = N'DELETE FROM [foo] WHERE ' + substring(@strCols,5,LEN(@strcols))
    select @strCols
    -- exec sp_executesql @strCols
end

答案 2 :(得分:1)

除了动态构建WHERE之外,您还可以尝试这样的事情:

DELETE FROM Foo 
WHERE
  (0 = @db1 AND [DB1] IS NULL)
  AND (0 = @db2 AND [DB2] IS NULL)
  AND (0 = @db3 AND [DB3] IS NULL)
  -- Etc...
;

通过将绑定参数@db_设置为0,您可以有效地“关闭”相应的IS NULL。因此,只需将需要测试的那些设置为不同于0的值。

答案 3 :(得分:0)

如果列始终位于相同位置并获取列标题名称然后使用它们构造SQL语句,请尝试按索引值获取列。

e.g。

string colHeader1 = (string)dr[3];
string colHeader2 = (string)dr[4];
string colHeader3 = (string)dr[5];