SQL Server 2014,'format' 不是可识别的内置函数名称

SQL Server 2014, 'format' is not a recognized built-in function name

我的数据库有这个table

| Name | Score | Date_time      |
---------------------------------
| A    |  100  | 20200601000000 |
| B    |  120  | 20200615000000 |
| C    |  110  | 20200629000000 |
| B    |  150  | 20200701000000 |
  ...

我想在 'Date_time' 工作日之前得到 'Name' 和 'Score'。

例如,当工作日是星期一(= 2)时,我得到两个数据。

| A    |  100  |
| B    |  120  |

并且我尝试使用以下 sql 语句。

select Name, Score 
from SCORE_DATA 
where   
datepart(dw, format(cast(Date_time as bigint),'####-##-## ##:##:##')) = 2 

正在转换 202006010000002020-06-01 00:00:00 并获取工作日 (dw) 并比较它是 2.

但是我得到一个错误:

'format' is not a recognized built-in function name.

我不明白为什么。

https://docs.microsoft.com/en-us/sql/t-sql/functions/format-transact-sql?view=sql-server-ver15&viewFallbackFrom=sql-server-2014

解释format函数。

它不适用于 SQL Server 2014 吗?我能做什么?

您应该检查您的兼容性级别如下:

SELECT compatibility_level  
FROM sys.databases 
WHERE name = 'YourDb';  
GO  

110 是 SQL 服务器 2012

120 是 SQL 服务器 2014

130 是 SQL 服务器 2016

140 是 SQL 服务器 2017

150 是 SQL 服务器 2019

要更改它,您可以使用以下脚本:

ALTER DATABASE YourDb
SET COMPATIBILITY_LEVEL = 120;  
GO  

FORMAT 函数要求兼容级别 >= 110

从技术上讲,Gabriele 的回答是正确的 - 他正在解释您收到错误消息的原因。

但是,有一个更好的方法来获得结果,它不涉及 Format

第一件事:您应该认真考虑将您现在拥有的 [Date_Time] 列从(我根据问题中的代码猜测的)字符串转换为适当的 DateTime
这不仅会解决这个特定问题,还会解决许多其他问题,其中一些您可能以前遇到过。
即使这涉及大量工作,从长远来看也是值得的 运行,相信我。

但是,考虑到这不是一种选择,我建议对您现有的代码进行一些改进:

  1. 使用 cast 将前 8 个字符直接转换为日期,而不是将整个字符转换为 bigint,然后像您的代码尝试那样使用格式和隐式转换现在。

  2. DatePart函数中使用WeekDay代替dw。它只是更具可读性。

  3. 根据 @@DateFirst 值计算星期几 - 因为 SQL 服务器正是这样做的,这意味着如果有人首先更改日期设置,您当前的代码将生成结果错误。

说了这么多,让我们看看它在代码中的样子。

首先,创建并填充示例 table(在您以后的问题中为我们省去这一步):

CREATE TABLE SCORE_DATA (
  [Name] varchar(1), 
  [Score] int, 
  [Date_time] char(14)
);
    
INSERT INTO SCORE_DATA ([Name], [Score], [Date_time]) VALUES
('A', 100, '20200601000000'),
('B', 120, '20200615000000'),
('C', 110, '20200629000000'),
('B', 150, '20200701000000');

查询(带注释):

SELECT  [Name]
      , [Score]
FROM SCORE_DATA
      -- using full name for readability
WHERE (DATEPART(WeekDay, 
                 -- ISO8601 format is unambiguous and will always be converted correctly
                 CAST(
                   -- A string representation of date in ISO8601 Format: yyyyMMdd
                   LEFT([Date_Time], 8) 
                 AS Date) -- You don't need DateTime, just the date...
        -- taking datefirst settings into consideration to get a fixed number
        ) + @@DATEFIRST) % 7 = 2

结果:

Name    Score
A       100
B       120
C       110 -- June 29th 2020 was a Monday too...