通过 SQL Server 代理执行时,Select 语句会产生不同的结果
Posted
技术标签:
【中文标题】通过 SQL Server 代理执行时,Select 语句会产生不同的结果【英文标题】:Select Statement yields different result when executed via SQL Server Agent 【发布时间】:2018-12-10 09:33:27 【问题描述】:我在 SQL Server 2014 标准版(64 位)上观察到一个我无法解释的奇怪行为:
一个简单的 select 语句在手动执行或通过 SQL 作业执行时表现不同:
sql语句如下:
[USE DB2]
GO
Select * from DB1.dbo.price p
where
p.sec_id = 10 and
p.dt = CONVERT(date,getdate() - (case when datename(dw,getdate()) = 'Monday' then 3 else 1 end))
该语句从表 dbo.price 中提取前一个工作日(通常是前 1 天)的某个证券 (sec_id = 10) 的价格记录,但是在星期一它是前 3 天,因为只有价格记录在可用的工作日(每个工作日每个证券 1 个价格记录)。
此 sql 语句嵌入在存储过程中,该存储过程本身通过 SQL Server 代理作业执行。
发生的奇怪的事情是:
如果上述 sql 语句是“手动”执行的,即通过查询编辑器,它会产生正确的结果,即周一至周五执行时返回一条价格记录。 上述sql语句通过存储过程“手动”执行时也是如此。 但是,当包含上述语句的存储过程通过 SQL Server 代理作业执行时,该语句仅返回周二至周五的价格记录。在星期一,该语句不返回任何记录。 (即使存储过程和 sql 语句在手动执行时都会返回一条记录)。由于该作业在周二至周五工作,因此不应该有任何特权等问题。由于该语句在手动执行时有效,因此该语句本身也不应该有任何问题。
但是当通过 SQL 作业执行时,为什么它不能在星期一工作呢?
有人知道原因可能是什么吗?不幸的是,我没有...
非常感谢您的帮助。 干杯
【问题讨论】:
您似乎忘记包含失败的错误。这是谜题中非常重要的部分。您能否编辑您的问题以包含它。谢谢。 Larnu 是对的,这个错误会有所帮助。否则只是猜测。比如周一可能有另一份工作在同一时间运行吗? 没有错误... Select 语句只是不返回任何记录。 - 即使记录存在并且在手动执行语句时正确返回。 “不返回行”和“失败”是非常不同的事情。您声明“SQL Server 代理作业失败”,这就像说“代理作业失败”。你是说工作不会失败吗?如果是这样,就会总是出现错误。如果SELECT
没有返回任何行,则代理作业没有失败并且它没有返回任何行,因为表中没有行,或者没有满足WHERE
或ON
子句的要求。如果您的代理工作没有失败,我建议您重新措辞以真正代表您遇到的问题。
作业几点开始?是否有可能由于时区、时钟同步,您又获得了一天前的数据,所以实际上在星期二您会得到您在星期一所期望的结果......没有其他合乎逻辑的解释。
【参考方案1】:
这是由于代理作业运行时使用的默认身份语言所致。
在您的代理工作中将其添加到脚本中:
SET DATEFIRST 7
[或您希望被视为一周的第一天的任何一天]
(它是特定于连接的,因此不会影响其他连接。)
或者您可以更改 SQL 代理(或代理,如果您正在使用)使用的登录的默认语言:
USE [master]
GO
ALTER LOGIN [LoginName] WITH DEFAULT_LANGUAGE = [SomeLanguage]
GO
参考:SET DATEFIRST
【讨论】:
谢谢米奇,你解决了这个问题。代理用户语言是“德语”而不是英语。【参考方案2】:作为Mitch says,可能是因为代理作业使用的语言/日期设置不同。
虽然我的首选解决方法不是摆弄设置,而是选择具有正确属性的“已知良好”的日子:
datename(dw,getdate()) = datename(dw,'20150720')
碰巧 2015 年 7 月 20 日(选择完全是任意的,我刚好看到 2015 年的台历)是星期一,我使用明确的日期格式作为我的文字。因此,无论datename(dw,getdate())
碰巧在星期一返回应该始终是datename(dw,'20150720')
产生的结果。
【讨论】:
这也是个好主意。但请确保在代码中添加注释以解释原因....+1以上是关于通过 SQL Server 代理执行时,Select 语句会产生不同的结果的主要内容,如果未能解决你的问题,请参考以下文章
T-SQL Server 代理作业失败“用户无权执行此操作”
当我从 SQL Server 代理运行 Python 脚本时,为啥它会失败?