将MS Access查询(使用IIF()和DATESERIAL())转换为T-SQL

时间:2015-10-02 08:30:44

标签: tsql ms-access case iif

我正在尝试将一些MS Access查询转换为T-SQL以在SSIS中使用(基本上将Access数据库转换为SQL Server 2008)并且我在转换IIF()语句时遇到问题。我尝试了几种方法,但总是导致错误。

该查询创建一个日期为“原始日期+ 2年(如果条件满足)和原始日期+ 1(如果条件不满足)”的列。 IIF()的第一部分消除了原始年份是闰年的情况,因此可能产生不存在的日期。

最初的IIF()声明是:

IIf((Day(Date)=29 And Month(Date)=2),   
IIf(Desc Like "*" & "123" & "*",
    DateSerial(Year(Date)+2,Month(Date),Day(Date)-1),
    DateSerial(Year(Date)+1,Month(Date),Day(Date)-1)),  
IIf(Desc Like "*" & "123" & "*",
    DateSerial(Year(Date)+2,Month(Date),Day(Date)),
    DateSerial(Year(Date)+1,Month(Date),Day(Date)))) AS Term

所以问题不仅是IIF()语句,还有DATESERIAL函数。我找到了使用CAST()的DATESERIAL()函数的解决方案(SQL Server 2008没有DATEFROMPARTS()函数...)。

我试过像这样使用CASE():

CASE
WHEN DAY(Date)=29 AND Month(Date)=2 THEN
    CASE
        WHEN Desc LIKE "%123%" THEN
    CAST(CAST(YEAR(Date)+2 AS VARCHAR(4)) + RIGHT('0' + CAST(MONTH(Date) AS VARCHAR(2)), 2) + RIGHT('0' + CAST(DAY(Date)-1 AS VARCHAR(2)), 2) AS DATETIME )
        ELSE CAST(CAST(YEAR(Date)+1 AS VARCHAR(4)) + RIGHT('0' + CAST(MONTH(Date) AS VARCHAR(2)), 2) + RIGHT('0' + CAST(DAY(Date)-1 AS VARCHAR(2)), 2) AS DATETIME ) END

ELSE CASE
    WHEN Desc LIKE "%123%" THEN
    THEN CAST(CAST(YEAR(Date)+2 AS VARCHAR(4)) + RIGHT('0' + CAST(MONTH(Date) AS VARCHAR(2)), 2) + RIGHT('0' + CAST(DAY(Date) AS VARCHAR(2)), 2) AS DATETIME )
    ELSE CAST(CAST(YEAR(Date)+1 AS VARCHAR(4)) + RIGHT('0' + CAST(MONTH(Date) AS VARCHAR(2)), 2) + RIGHT('0' + CAST(DAY(Date) AS VARCHAR(2)), 2) AS DATETIME )END END AS Term

我也尝试过使用COAELSCE()但没有更好的结果。

我真的不知道是否出现了某种语法错误或问题出在哪里。

提前感谢您的帮助。

编辑:我将添加我收到的错误消息:'...'附近的语法不正确。当我尝试不同的方法时,'...'会发生变化,有时是ELSE,等等。

2 个答案:

答案 0 :(得分:1)

SQL Server的DATEADD可能有助于简化这里的事情......

 CASE WHEN (<your condition>) 
 THEN DATEADD(YEAR, 1, [OriginalDate]) 
 ELSE DATEADD(YEAR, 2, [OriginalDate])
 END

也应该应对闰年。

答案 1 :(得分:0)

DateSerial是一个非常有用的功能,只需创建自己的功能 我从here得到了我的版本:

CREATE FUNCTION dbo.DateSerial
(
  @year int,
  @month int,
  @day int
)
RETURNS datetime
AS
BEGIN
   DECLARE @date datetime

   -- convert date by adding together like yyyymmdd
   SET @date = cast(@year * 10000 + 101 AS char(8));

   -- Add to date the proper months subtracting 1, since we used 1 as start instead of zero.    
   SET @date = dateadd(mm , @month - 1 , @date)
   -- Add to date the proper days subtracting 1, since we used 1 as start instead of zero.    
   SET @date = dateadd(dd , @day - 1 , @date);

   RETURN @date ;
END;
GO

这是另一种方式:Date serial in SQL?

然后像在Access中一样使用该功能。

编辑:只是注意到你的外部IIF将处理闰年。使用dateadd()时不需要这样做。