小编典典

为什么YEAR会因日期转换错误而失败?

sql

我有一个名为“ FechasFirmaHorometros”的视图,定义为

SELECT IdFormulario, 
       CONVERT(Date, RValues) AS FechaFirma 
FROM   dbo.Respuestas 
WHERE  ( IdPreguntas IN (SELECT IdPregunta 
                         FROM   dbo.Preguntas 
                         WHERE 
         ( FormIdentifier = dbo.IdFormularioHorometros() ) 
         AND ( Label = 'SLFYHDLR' )) )

我有一个名为[RespuestaPreguntaHorometrosFecha]的函数定义为

SELECT Respuestas.RValues 
FROM   Respuestas 
       JOIN Preguntas 
         ON Preguntas.Label = @LabelPregunta 
       JOIN FechasFirmaHorometros 
         ON FechasFirmaHorometros.IdFormulario = Respuestas.IdFormulario 
WHERE  Respuestas.IdPreguntas = Preguntas.IdPregunta 
       AND YEAR(FechasFirmaHorometros.FechaFirma) = @Anio 
       AND MONTH(FechasFirmaHorometros.FechaFirma) = @Mes

@LabelPregunta VARCHAR(MAX)
@Anio INT
@Mes INT

在调试使用该函数的另一个存储过程时,我一直在碰到上述函数时收到此消息

Conversion failed when converting date and/or time from character string.

但是我可以自由地做类似的事情

SELECT DAY(FechaFirma) FROM FechasFirmaHorometros

为什么会发生这种情况,我该如何解决或解决呢?


阅读 219

收藏
2021-04-14

共1个答案

小编典典

RValues由于某种原因,我认为这是某种类型的字符串列。您应该解决该问题,并使用日期数据类型存储日期数据(显然,此数据包与混合包位于不同的列中)。

如果您无法解决该问题,则可以通过以下方法阻止Damien所说的事情:

CASE WHEN ISDATE(RValues) = 1 THEN CONVERT(Date, RValues) END AS FechaFirma

NULL如果SQL Server无法确定如何将其转换为日期,则将使用“日期” 。)

您不能仅仅通过添加一个WHERE子句来阻止这种情况,因为SQL
Server经常会SELECT在执行过滤器之前尝试尝试列表中的转换(这完全取决于计划)。您也不能通过使用子查询,CTE,联接顺序提示等来强制执行操作顺序

如果缺少CASE表达式,它将迫使SQL
Server在尝试进行转换之前评估ISDATE()结果(只要任何分支中都没有聚合),您可以:

  • 将过滤后的结果转储到#temp表中,然后从该#temp表中进行选择,然后仅应用转换。
  • 只需返回字符串,并将其视为客户端上的日期,然后从中取出YEAR / MONTH等部分
  • 只需使用字符串操作即可拉YEAR = LEFT(col,4)等。
  • 使用,TRY_CONVERT()因为我刚刚注意到您使用的是SQL Server 2012:
    TRY_CONVERT(DATE, RValues) AS FechaFirma
    
2021-04-14