Sql server 如何编辑此SQL Server查询以使其更准确?

Sql server 如何编辑此SQL Server查询以使其更准确?,sql-server,sql-server-2005,Sql Server,Sql Server 2005,我将根据SQLServer2005中的内置功能安排每30-35分钟执行一次。 以下是查询: UPDATE PREMIUM_SERVICE2 SET ndays = ndays - 1 WHERE strAccountID NOT IN (SELECT strAccountID FROM CURRENTUSER) AND ndays > 0 AND (PremStart < DATEADD(DAY,-1,GETDATE())) DELETE FROM PREMIUM

我将根据SQLServer2005中的内置功能安排每30-35分钟执行一次。 以下是查询:

UPDATE PREMIUM_SERVICE2 SET ndays = ndays - 1 
WHERE strAccountID NOT IN
    (SELECT strAccountID FROM CURRENTUSER) 
    AND ndays > 0 AND (PremStart < DATEADD(DAY,-1,GETDATE()))
DELETE FROM PREMIUM_SERVICE2 where nDays = 0
因此,当它更新时,它也会更新
PremStart
,但这会使它变得很糟糕,因为现在它可能会错过30分钟,而当他们有30天的额外时间时。。它可能会在至少一天内错误地添加它们,这有点糟糕,因为计划的作业将每30分钟执行一次。那么,如何编辑第一个查询以确保它更准确,并且只有当它真正通过时才实际减去1天?我希望你们能理解我的意思。
我使用SQL Server 2005

与特优期相关的所有属性是什么?只是开始日期/时间和剩余天数?计数器每天滴答一次就足够了,但是每30-35分钟一次?在某种程度上,你需要知道今天是否已经减去了nDays——仅仅这两列你无法分辨,这就是问题所在

如果强制要求任何需要知道剩余天数的人都应该从表中的专用列中读取该值,而不是每次根据固定的初始值计算该值,然后,您需要再分配一列,以便能够以一种或另一种形式获得结束点——这是我可以想象的唯一一种方法,即您可以跟踪每天多次运行查询时剩余的天数

例如,第三列可以是保费期的初始长度。这样,您就可以使用以下语句更新
ndays

UPDATE PREMIUM_SERVICE2
SET ndays = TotalDays - DATEDIFF(MINUTE, PremStart, GETDATE()) / 1440
WHERE strAccountID NOT IN
    (SELECT strAccountID FROM CURRENTUSER) 
    AND ndays > 0
;
其中,
TotalDays
是第三列的名称。如您所见,
ndays
并不是简单地递减的,而是在每次运行时计算得出的

这实际上是您的应用程序(或任何需要
ndays
值的程序)可以做的,而不是提取预先计算的值,也就是说,您可以将该表达式放入用于请求剩余天数的查询中,从而去掉
ndays
。当然,您还需要修改DELETE语句,将
ndays
条件替换为使用与上面相同或类似的表达式的条件,以检查应该删除哪些行

不过,我并不是说绝对不需要
ndays
。拥有它是有价值的,在你的特殊情况下分配它可能是有意义的,但是你确实需要以某种形式记住结束点


还有一个潜在的问题需要解决,这主要是由于计算
ndays
的新方法引起的。如果运行脚本的作业由于某种原因延迟(停止一段时间,然后恢复),理论上可能会导致负值
ndays
值,因此使用诸如
ndays=0
条件的DELETE语句肯定会错过这些值。因此,我只需将条件更改为
ndays您每天都在倒计时ndays计数器。我只需跟踪特优期开始的时间,并在使用特优“功能”时对照当前时间进行检查。这样你就没有了持续的维护和完美的准确性。那么如何通过我当前的查询实现这一点呢?根本不需要,因为你不需要它们。这是一个错误的开始。所以我的方法目前很适合做我想做的事??不,你不能用你尝试的方式做你想做的事。错误不在你的查询中,而在你的方法中。很好的解释。我真的很感激。如果可能的话,我有几个问题要问。所以,如果你查看了我在主帖子中的第二个查询示例,你会发现我认为如果ndays是更新的,它也会更新PremStart,所以下次它会在1天后再次更新。这不是基本上和你建议的一样,只是用另一种方式吗?此外,如果我使用你的方法,他们再次购买,这将增加他们+30天,因此他们将有例如60。。这不是问题吗?如果您看到我的第二个查询示例,请告诉我。我将不胜感激。我想我不会对你的第二个问题发表评论,因为你自己已经认为这很糟糕了。:)不过,我不喜欢它的原因有些不同:您正在重写
PremStart
,因此丢失了关于确切开始日期/时间的信息。也许这些信息在你的情况下并不重要,但我个人很少考虑这样的方法(当然不是第一个解决方案)。但是,是的,这种方法相当于我所建议的方法,因为它确实每天更新一次
ndays
(可能会给您带来将近30分钟的额外时间)…至于在一个仍在等待的时间上增加更多的额外时间,我相信您可以在不更改
PremStart
的情况下,按增加的天数增加
TotalDays
。根据我的建议,
ndays
值将在最近的作业调用时相应更新,因为它将重新计算。例如,它看起来是这样的:开始日期
10/1/2013
,长度
30
,最后计算的
ndays
value
16
,将
30
添加到长度(
TotalDays
)中,使其
60
PremStart
保持不变,在作业的下一次迭代中,
ndays
变为
46
(或
45
,取决于实际执行时间)。非常感谢。我会接受你的答案只是需要知道,所以这两种方式都有可能放弃大约30分钟的额外时间,对吗?正确。碰巧的是,你的另一种方法可能对你来说并没有那么糟糕。事实上,它的好处是使用的列比我的建议少。我自己仍然对重写这两列的想法感到不安,但我想如果没有必要保留原始值,应该这样做
UPDATE PREMIUM_SERVICE2
SET ndays = TotalDays - DATEDIFF(MINUTE, PremStart, GETDATE()) / 1440
WHERE strAccountID NOT IN
    (SELECT strAccountID FROM CURRENTUSER) 
    AND ndays > 0
;