当我从 SQL Server 作业运行此查询时,为什么它会失败?

SAK*_* UK 4 sql-server sql-server-agent jobs errors date

我知道如何解决这个问题,但我不明白为什么当我从SSMS运行下面的查询时它会起作用的技术细节运行下面的查询时它可以工作,但当我将它添加为 SQL Server 代理中的作业时相同的查询会失败,这背后的技术细节是什么。

查询:

select LEFT(datediff(day,GETDATE(),'31/08/20'+'26')/365.25,2) AS test
Run Code Online (Sandbox Code Playgroud)

作业失败时我收到的错误:

从字符串转换日期和/或时间时转换失败。[SQLSTATE 22007](错误 241)。这一步失败了。

SQL 代理是否使用不同的引擎或不同的技术?

Tib*_*szi 12

它失败是因为您没有使用语言中立的日期时间格式。您假设 SQL Server 理解先是日,然后是月,最后是年。

当您使用 SSMS 以交互方式运行此命令时,您使用的登录名(如 CREATE LOGIN 命令中所示)具有与该顺序相对应的日期格式。即,您的登录日期格式是 dmy。

显然,代理使用不同的日期时间格式进行登录。这就是它失败的原因。也许是 mdy(us_english 的默认值)。

您想要做的是使用不依赖于登录的日期时间设置的日期时间格式 - 我喜欢称之为“语言中性”日期时间格式。YYYYMMDD 就是这样一种格式。这是转换为该格式的表达式:

select LEFT(datediff(day,GETDATE(),'20' + '26' + '0831')/365.25,2) AS test
Run Code Online (Sandbox Code Playgroud)

另一种选择是在表达式之前添加 SET DATEFORMAT:

set dateformat dmy
select LEFT(datediff(day,GETDATE(),'31/08/20'+'26')/365.25,2) AS test
Run Code Online (Sandbox Code Playgroud)

这是我写的一篇关于日期时间的文章:https://karaszi.com/the-ultimate-guide-to-the-datetime-datatypes

我不会乱搞特工的语言!你永远不知道什么会破坏。只需使用 dateformat 命令或(最好)使用语言中立的日期时间格式。


Ron*_*ldo 7

我想说这个问题与查询运行时使用的语言有关。

请从 SSMS 和您创建的作业运行此命令,以检查两种方法所使用的语言是否相同:

SELECT @@LANGUAGE AS 'Language Name';
Run Code Online (Sandbox Code Playgroud)

当我从 SSMS 运行时,您的查询失败并出现相同的错误,原因是日期格式导致31/08成为无效日期,而08/31工作正常。我目前的语言是us_english.

如果需要,可以使用SET LANGUAGE命令设置会话的语言。