将 MS Access 查询(使用 IIF() 和 DATESERIAL())处理成 T-SQL
Transacting MS Access query (using IIF() and DATESERIAL()) into T-SQL
我正在尝试将一些 MS Access 查询转换为 T-SQL 以便在 SSIS 中使用(基本上是将 Access 数据库转换为 SQL server 2008),但我在转换 IIF 时遇到了问题() 陈述。我尝试了几种方法,但总是导致错误。
查询创建了一个日期为 "original Date + 2 years if the condition is met and original Date + 1 if the condition is not met" 的列。 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 服务器 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、THEN 等
SQL 服务器的 DATEADD 可能有助于简化这里的事情...
CASE WHEN (<your condition>)
THEN DATEADD(YEAR, 1, [OriginalDate])
ELSE DATEADD(YEAR, 2, [OriginalDate])
END
应该也应对闰年吧
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()
.
时不需要
我正在尝试将一些 MS Access 查询转换为 T-SQL 以便在 SSIS 中使用(基本上是将 Access 数据库转换为 SQL server 2008),但我在转换 IIF 时遇到了问题() 陈述。我尝试了几种方法,但总是导致错误。
查询创建了一个日期为 "original Date + 2 years if the condition is met and original Date + 1 if the condition is not met" 的列。 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 服务器 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、THEN 等
SQL 服务器的 DATEADD 可能有助于简化这里的事情...
CASE WHEN (<your condition>)
THEN DATEADD(YEAR, 1, [OriginalDate])
ELSE DATEADD(YEAR, 2, [OriginalDate])
END
应该也应对闰年吧
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()
.