使用Case语句作为where子句的第二部分

时间:2013-08-14 15:50:53

标签: sql vb.net tsql vbscript

我在vb.net中使用当前的sql查询来获取返回到datagridview的一些数据。我正在检查日期时间选择器的年,月和日期,以获取从所选表返回的必要信息。我的查询工作正常减去案例陈述部分,以检查具体日期。任何人都可以帮我修复此查询或建议替代方法吗?

"SELECT * FROM " & Me.SelectedTable.SelectedItem.ToString & " 
WHERE(Datepart(yyyy," & colName & ") BETWEEN '" & Me.DateTimePicker1.Value.Year & "' AND '" & Me.DateTimePicker2.Value.Year & "' 
AND Datepart(mm," & colName & ") BETWEEN '" & Me.DateTimePicker1.Value.Month & "' AND '" & Me.DateTimePicker2.Value.Month & "' 
AND Datepart(dd," & colName & ") <= " & Me.DateTimePicker1.Value.Day 
& " CASE WHEN Datepart(mm," & colName & ")=" & Me.DateTimePicker1.Value.Month & " 
THEN Datepart(dd," & colName & ") = " & Me.DateTimePicker1.Value.Day & " 
WHEN Datepart(mm," & colName & ")= " & Me.DateTimePicker2.Value.Month 
& " Datepart(dd," & colName & ")= " & Me.DateTimePicker2.Value.Day & " 
ELSE Datepart(dd," & colName & ") BETWEEN 1 AND 31 END)"

2 个答案:

答案 0 :(得分:1)

首先,您的查询对SQL注入攻击开放。您需要通过参数化查询来修复它。

接下来,您不需要CASE:您可以将逻辑表达为复合逻辑条件。

我将查询从使用由colName变量的值定义的动态列名称的查询更改为使用col以获得更好的可读性。我还为各种选择器的值定义了参数。在查询之前,您需要在准备好的命令上设置它们。

最感兴趣的部分位于底部:我将您的CASE重写为三部分逻辑条件,根据@month1@month2的设置评估三个部分之一,表示DateTimePicker1DateTimePicker2的月份值。

SELECT * FROM Table
WHERE (Datepart(yyyy, col) BETWEEN @year1 AND @year2
  AND Datepart(mm, col) BETWEEN @month1 AND @month2
  AND Datepart(dd, col) <= @day1
  AND (
          (Datepart(mm, col)=@month1 AND Datepart(dd, col) = @day1)
      OR  (Datepart(mm, col)=@month2 AND Datepart(dd, col) = @day2)
      OR  (Datepart(dd, col) BETWEEN 1 AND 31)
  )

答案 1 :(得分:0)

看起来你在第二个条件结束时忘记了“那么”。

所以,做吧:

CASE 
WHEN Datepart(mm," & colName & ")=" & Me.DateTimePicker1.Value.Month & " THEN
        Datepart(dd," & colName & ") = " & Me.DateTimePicker1.Value.Day & " 

WHEN Datepart(mm," & colName & ")= " & Me.DateTimePicker2.Value.Month & " **THEN**
     Datepart(dd," & colName & ")= " & Me.DateTimePicker2.Value.Day & " 

ELSE Datepart(dd," & colName & ") BETWEEN 1 AND 31 
END