这将是一个漫长的过程,对不起...
我的客户有SQL Server 2008 R2。我已经制定了更新特定表的过程。目标是在运行过程的同一天更新行(但为了安全起见,它会更新过去和将来的几天。我有一个SQL Agent作业是计划每天午夜运行一次以运行我的程序。
如果我手动运行该过程,它将起作用。如果我手动运行该作业(即,在Management Studio中左击该作业,然后选择“在步骤开始作业”),则它可以正常工作。但是,如果作业按计划运行,则它将无法正常工作。根据历史记录,带有过程调用的步骤已正确运行。
如果我以任何方式更改计划(例如将其更改为运行00:10),则该过程仅在该天有效,而在第二天则不起作用。通过将过程调用放入事务中,可以成功地手动复制了一次问题-回滚然后查看结果,但是我无法弄清楚为什么我能够一次复制该问题。仅在5分钟后运行相同的操作再次成功。
我有一个日志记录,显示成功的手动运行和不成功的计划运行之间的参数完全相同。我什至已经针对日志记录的参数测试了proc的更新部分,并且它以这种方式工作。我尝试增加计划工作的次数(每小时最多一次),但无济于事。我还创建了一个探查器跟踪,以检查作业在调用作业时如何运行,但是在其中找不到任何错误。也没有死锁。
我认为问题不在于它没有更新任何内容,而是问题在于更新了空值。但是我也不明白这一点,因为日志记录显示了变量(@DayWorkGroupNum)的值,该变量保存更新值,而为什么空值仅在计划中出现仍然没有意义。
最后,失败的更新似乎持续了2天,然后突然更新了所有丢失的内容(这是proc的设计方式,它找到了第一个丢失的日期,然后从那时起更新了所有内容,但是由于某种原因,按计划运行,仅每3天工作一次)。例如,现在,空值涵盖今天和昨天,但是明天运行时,它将更新所有3天。但是,这确实告诉我这不是用户权限问题。
该过程的问题部分是:
UPDATE Dim_Shift SET WorkGroupNo = @DayWorkGroupNum
--SELECT * FROM Dim_Shift
WHERE date = DATEADD(DAY,@shiftIndex,@StartDate)
and ShiftNo = 15
and WorkPhaseID in (
SELECT WorkPhaseID FROM [Dim_WorkPhase]
WHERE MillID = @pMillNo
)
该更新在一个循环中运行,该循环将@shiftIndex加1(从0开始),该循环是从当日-1到当日+2。错误的更新仅涉及@shiftIndex 1或0和1。>
如前所述,我包含的日志记录向我显示了@ DayWorkGroupNum,@ shiftIndex,@ StartDate是正确的。 @pMillNo是一个参数,始终为13。这也是我使用从日志记录中获取的参数进行测试的部分,如果我禁用了更新部分并启用了选择部分,则选择将精确显示应更新的结果集。
我还尝试了整个过程,并设置为分别记录错误,但没有记录错误。
例如,当天更新语句的参数为:
@shiftIndex = 1(昨天是0),@ DayWorkGroupNum = 1,@ StartDate = 2019-05-01(始终是今天的日期-1天)
表在更新前很少有示例行
+-------------+------------+---------+-------------+
| WorkPhaseID | Date | ShiftNo | WorkGroupNo |
+-------------+------------+---------+-------------+
| 206 | 2019-05-02 | 15 | NULL |
| 207 | 2019-05-02 | 15 | NULL |
| 208 | 2019-05-02 | 15 | NULL |
| 209 | 2019-05-02 | 15 | NULL |
+-------------+------------+---------+-------------+
,更新后应该如下所示:
+-------------+------------+---------+-------------+
| WorkPhaseID | Date | ShiftNo | WorkGroupNo |
+-------------+------------+---------+-------------+
| 206 | 2019-05-02 | 15 | 1 |
| 207 | 2019-05-02 | 15 | 1 |
| 208 | 2019-05-02 | 15 | 1 |
| 209 | 2019-05-02 | 15 | 1 |
+-------------+------------+---------+-------------+
,但WorkGroupNo仍为NULL。就在最近,我注意到,如果workGroupNo上有任何旧数据,那么proc会将其转换为NULL,但这仅适用于当前日期,有时甚至是前一天。
-编辑- 上面我没有解释,所讨论的数据库很旧,并且流量很大。考虑到这一点,我发现问题是特定于表的:我在工作中增加了一个新步骤,即调用新过程,该过程将写入我自己创建的全新表中,并且效果很好。