具有最近添加的关键字的SQL Server如何支持旧版本的SQL Server

问题描述 投票:2回答:1

我们正在编写要在客户服务器上运行的数据库升级脚本,该脚本可以是2012年以后的任何版本的SQL Server。

我们正在做的一件事是将DATETIME列从本地时区格式迁移到UTC格式。

我编写了一个可以从迁移SQL调用的函数。

该函数使用2种方法之一,具体取决于SQL Server的版本-如果使用2016年或更高版本,则使用DATETIMEOFFSET;如果使用旧版本,则使用后备。

问题在于,较旧的服务器不允许包含该函数,因为它包含DATETIMEOFFSET关键字。

[我尝试将DATETIMEOFFSET SQL移至字符串并使用sp_executesql进行调用,但发现我无法从函数中调用存储过程。

关于如何处理此问题的任何想法?

我可以编写2个函数并根据服务器版本安装一个或另一个,但是不确定SQL Server数据工具和dacpacs是否可以实现。

这里是功能:

CREATE FUNCTION [dbo].[ConvertLocalDateToUtc]
    (@LocalDate DATETIME2, 
     @LocalZone NVARCHAR(128))
RETURNS DATETIME2
AS
BEGIN
    DECLARE @convertedDate DATETIME2;

    IF (SELECT CAST(SERVERPROPERTY('ProductMajorVersion') AS INT)) >= 13
    BEGIN
        -- if SQL Server 2016 or later, this takes account of historical daylight saving times
        DECLARE @ZonedLocalDate DATETIMEOFFSET = @LocalDate AT TIME ZONE @LocalZone;
        DECLARE @ZonedUtcDate DATETIMEOFFSET = @ZonedLocalDate AT TIME ZONE 'UTC';
        SET @convertedDate = CAST(@ZonedUtcDate AS DATETIME2);
    END
    ELSE
    BEGIN
        -- if earlier than SQL Server 2016 this uses the current time zone
        -- which may or may not be the same DST as historical dates
        SET @convertedDate = DATEADD(MI,(DATEDIFF(MI, SYSDATETIME(), SYSUTCDATETIME())), @LocalDate);
    END

    RETURN(@convertedDate);  
END
sql-server function stored-procedures sql-server-data-tools
1个回答
0
投票

我们设法通过以下部署后脚本对其进行修复。这与Martin Smith在评论中建议的解决方法类似。我们决定将这两个功能放在一个脚本中,而不是将一个基本功能和一个升级放在一个脚本中,以提高可维护性。

-- delete function if we already have it
IF object_id(N'ConvertLocalDateToUtc', N'FN') IS NOT NULL
    DROP FUNCTION ConvertLocalDateToUtc
GO

DECLARE @SQLString nvarchar(MAX);  

-- build server version specific function

-- if SQL Server 2016 or later, this takes account of historical daylight saving times
IF (SELECT CAST(SERVERPROPERTY('ProductMajorVersion') AS INT)) >= 13
BEGIN
SET @SQLString = N'
CREATE FUNCTION [dbo].[ConvertLocalDateToUtc]
(
    @LocalDate DATETIME2, 
    @LocalZone NVARCHAR(128)
)
RETURNS DATETIME2
AS
BEGIN
    DECLARE @convertedDate DATETIME2;
    DECLARE @ZonedLocalDate DATETIMEOFFSET = @LocalDate AT TIME ZONE @LocalZone;
    DECLARE @ZonedUtcDate DATETIMEOFFSET = @ZonedLocalDate AT TIME ZONE ''UTC'';
    SET @convertedDate = CAST(@ZonedUtcDate AS DATETIME2);
    RETURN(@convertedDate);  
END
';
END
ELSE
BEGIN
-- if earlier than SQL Server 2016 this uses the current time zone
-- which may or may not be the same DST as historical dates
SET @SQLString = N'
CREATE FUNCTION [dbo].[ConvertLocalDateToUtc]
(
    @LocalDate DATETIME2, 
    @LocalZone NVARCHAR(128)
)
RETURNS DATETIME2
AS
BEGIN
    DECLARE @convertedDate DATETIME2;
    SET @convertedDate = DATEADD(MI,(DATEDIFF(MI, SYSDATETIME(), SYSUTCDATETIME())), @LocalDate);
    RETURN(@convertedDate);  
END
';
END

-- run the sql to create the function
EXECUTE sp_executesql @SQLString;
© www.soinside.com 2019 - 2024. All rights reserved.