【问题标题】:SQL Cast works in Select but not in Where clauseSQL Cast 适用于 Select 但不适用于 Where 子句
【发布时间】:2016-02-09 11:28:29
【问题描述】:

我在 SQL Server 语句中遇到了一个奇怪的问题,我很难理解。希望有人可以提供帮助。

在返回事件返回的查询中,查询工作正常,所以我知道所有链接都正常,我在 Select 子句中有这个来返回日期:

Select Cast(DATENAME(WEEKDAY, Cast(dbo.TimeZone(Incidents.IncidentDate, Sites.TimeZone) As Date)) As VarChar) As 'IncidentDay',

正确地将星期几作为 varchar 返回。

我还想让这一天成为 Where 条件的一部分,因此我将一个 varchar 变量 @IncidentDay 传递给查询并将其添加到 Where 子句中:

Where (@IncidentDay Is Null 
    Or Cast(DATENAME(WEEKDAY, Cast(dbo.TimeZone(Incidents.IncidentDate, Sites.TimeZone) As Date)) As VarChar) = @IncidentDay)

但是,如果我将值传递给 @IncidentDay,则不会返回任何结果。 Cast 语句是相同的,我在 Where 语句的其他地方使用 Cast 按日期过滤没有问题。

谁能解释一下为什么日过滤器不起作用?

谢谢。

编辑:到目前为止使用案例的回答对我不起作用,建议我需要澄清这个问题。

问题是我需要在 Where 子句中设置一个条件,以将存储日期的星期几(例如“星期五”)与传递给查询的变量进行比较。

Select Cast.. 语句正确地将星期几作为 varchar 返回,但 Where 子句中的相同 Cast.. 语句不会根据传递的 varchar 变量进行评估。我需要检查 Null,因为该查询也会针对不会设置 @IncidentDay 变量的其他条件调用。

【问题讨论】:

  • 你的变量是varchar还是date类型?我认为问题就在那里(删除 varchar 演员并保留日期)
  • @sagi,变量是星期几,例如'Friday',所以它需要是varchar而不是日期。
  • 首先@IncidentDay是什么datatpe? - 发布您的所有 SQL,而不仅仅是其中的一部分。二、这是什么样子的:Select Cast(DATENAME(WEEKDAY, Cast(dbo.TimeZone(Incidents.IncidentDate, Sites.TimeZone) As Date)) As VarChar) As IncidentDay, @IncidentDay as C2, CASE WHEN Cast(DATENAME(WEEKDAY, Cast(dbo.TimeZone(Incidents.IncidentDate, Sites.TimeZone) As Date)) As VarChar) = @IncidentDay THEN 'Y' ELSE 'N' END As Compare From MyTable
  • 数据库是什么排序规则(不区分大小写吗?)还要小心使用cast 和日期。我总是建议使用带有明确格式代码的CONVERT。还有一点令人担忧的是,一个名为 TimeZone 的函数似乎返回 varchar 而不是 date
  • varchar = varchar(1)。因此,您放入变量中的任何内容都会被截断为一个字符。

标签: sql-server where


【解决方案1】:

虽然只在 cmets 中提及,但您的变量是这样定义的:

@IncidentDay VARCHAR

这相当于

@IncidentDay VARCHAR(1)

这意味着进入变量的任何内容都会被截断为一个字符。所以 'Thursday' 变成了 'T' 这显然不等同于 'Thursday'

此外,这个较小的表达式应该等同于您当前使用的表达式:

DATENAME(
    WEEKDAY,
    dbo.TimeZone(Incidents.IncidentDate, Sites.TimeZone)
)

你做了很多多余的转换。

【讨论】:

    【解决方案2】:

    就用这个

    AND  Cast(DATENAME(WEEKDAY, Cast(dbo.TimeZone(Incidents.IncidentDate, Sites.TimeZone) AS DATE)) AS VARCHAR) = CASE 
        WHEN @IncidentDay IS NULL THEN Cast(DATENAME(WEEKDAY, Cast(dbo.TimeZone(Incidents.IncidentDate, Sites.TimeZone) AS DATE)) AS VARCHAR)
        ELSE  @IncidentDay END
    

    【讨论】:

      【解决方案3】:

      在您的查询中使用 OR 子句。

      如果您的意图是每当@IncidentDay 为空,那么所有记录都应该出现,如果@IncidentDay 有任何值,那么它应该过滤该日期值。那么下面的代码就可以工作了。

      注意:如果没有搜索,这里你需要为@IncidentDay发送“A”而不是NULL

      AND CASE 
              WHEN @IncidentDay 'A'
                  THEN 'A'
              ELSE Cast(DATENAME(WEEKDAY, Cast(dbo.TimeZone(Incidents.IncidentDate, Sites.TimeZone) AS DATE)) AS VARCHAR)
              END = @IncidentDay
      

      【讨论】:

        【解决方案4】:

        确保变量被定义为 varchar(max) 而不仅仅是 varchar 解决了这个问题。

        感谢您的 cmets。

        【讨论】:

          猜你喜欢
          • 2019-02-25
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2023-03-15
          • 1970-01-01
          • 2021-02-23
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多