如何使用 GETDATE 解决 SQL 标量变量的错误
How to resolve error with SQL Scalar variable using GETDATE
我正在 SQL 中编写标量变量来定义季节年(从日历年的中途开始)。它需要随着日期的变化而变化,即此日期为 2021 年,2022 年 6 月 1 日则应更改为 2022 年。
它正在生成此错误代码:
"Error referencing function 'GETDATE': non-deterministic, security and metadata function calls are not allowed in user-defined functions."
我在网上看不到任何可以详细解决该问题的解决方法。有什么想法吗?
密码是:
CREATE FUNCTION CDP.fn_SeasonYear
(
)
RETURNS INT
AS
BEGIN
DECLARE @ThisSeason INT
SET @ThisSeason =
CASE
WHEN DatePart(Month, GETDATE()) < 6
THEN CONVERT(int,DatePart(Year, GETDATE()) -1)
ELSE CONVERT(int,DatePart(Year, GETDATE()))
End
RETURN @ThisSeason
END;
这并不理想,但这是我使用过的一种方法。如前所述,在给定相同输入的情况下,函数需要 return 相同的值。您将 getdate() 作为参数传递给函数。
CREATE FUNCTION dbo.fn_SeasonYear( @currdate datetime )
RETURNS INT
AS
BEGIN
DECLARE @ThisSeason INT
SET @ThisSeason =
CASE
WHEN DatePart(Month, @currdate) < 6
THEN CONVERT(int,DatePart(Year, @currdate) -1)
ELSE CONVERT(int,DatePart(Year, @currdate))
End
RETURN @ThisSeason
END;
GETDATE() 是 MS SQL 服务器。您应该这样标记问题。您可能应该指出您拥有的 SQL 服务器版本,因为该功能在 SQL 服务器 2017 中运行良好:
SET NOCOUNT ON;
SELECT @@VERSION;
GO
DROP FUNCTION IF EXISTS dbo.fn_SeasonYear;
GO
CREATE FUNCTION dbo.fn_SeasonYear()
RETURNS INT
AS
BEGIN
DECLARE @ThisSeason INT;
SET @ThisSeason =
CASE
WHEN DatePart(Month, GETDATE()) < 6
THEN CONVERT(INT, DatePart(Year, GETDATE()) -1)
ELSE CONVERT(INT, DatePart(Year, GETDATE()))
END;
RETURN @ThisSeason;
END;
GO
SELECT dbo.fn_SeasonYear();
/*
OUTPUT:
----------------------------------------------------------------------------
Microsoft SQL Server 2017 (RTM) - 14.0.1000.169 (X64)
Aug 22 2017 17:04:49
Copyright (C) 2017 Microsoft Corporation
Express Edition (64-bit) on Windows Server 2016 Datacenter 10.0 <X64> (Build 14393: ) (Hypervisor)
-----------
2021
*/
我正在 SQL 中编写标量变量来定义季节年(从日历年的中途开始)。它需要随着日期的变化而变化,即此日期为 2021 年,2022 年 6 月 1 日则应更改为 2022 年。
它正在生成此错误代码:
"Error referencing function 'GETDATE': non-deterministic, security and metadata function calls are not allowed in user-defined functions."
我在网上看不到任何可以详细解决该问题的解决方法。有什么想法吗?
密码是:
CREATE FUNCTION CDP.fn_SeasonYear
(
)
RETURNS INT
AS
BEGIN
DECLARE @ThisSeason INT
SET @ThisSeason =
CASE
WHEN DatePart(Month, GETDATE()) < 6
THEN CONVERT(int,DatePart(Year, GETDATE()) -1)
ELSE CONVERT(int,DatePart(Year, GETDATE()))
End
RETURN @ThisSeason
END;
这并不理想,但这是我使用过的一种方法。如前所述,在给定相同输入的情况下,函数需要 return 相同的值。您将 getdate() 作为参数传递给函数。
CREATE FUNCTION dbo.fn_SeasonYear( @currdate datetime )
RETURNS INT
AS
BEGIN
DECLARE @ThisSeason INT
SET @ThisSeason =
CASE
WHEN DatePart(Month, @currdate) < 6
THEN CONVERT(int,DatePart(Year, @currdate) -1)
ELSE CONVERT(int,DatePart(Year, @currdate))
End
RETURN @ThisSeason
END;
GETDATE() 是 MS SQL 服务器。您应该这样标记问题。您可能应该指出您拥有的 SQL 服务器版本,因为该功能在 SQL 服务器 2017 中运行良好:
SET NOCOUNT ON;
SELECT @@VERSION;
GO
DROP FUNCTION IF EXISTS dbo.fn_SeasonYear;
GO
CREATE FUNCTION dbo.fn_SeasonYear()
RETURNS INT
AS
BEGIN
DECLARE @ThisSeason INT;
SET @ThisSeason =
CASE
WHEN DatePart(Month, GETDATE()) < 6
THEN CONVERT(INT, DatePart(Year, GETDATE()) -1)
ELSE CONVERT(INT, DatePart(Year, GETDATE()))
END;
RETURN @ThisSeason;
END;
GO
SELECT dbo.fn_SeasonYear();
/*
OUTPUT:
----------------------------------------------------------------------------
Microsoft SQL Server 2017 (RTM) - 14.0.1000.169 (X64)
Aug 22 2017 17:04:49
Copyright (C) 2017 Microsoft Corporation
Express Edition (64-bit) on Windows Server 2016 Datacenter 10.0 <X64> (Build 14393: ) (Hypervisor)
-----------
2021
*/