存储过程

时间:2010-07-08 15:22:42

标签: sql sql-server stored-procedures calculated-columns

我坚持创建一个应该每天更新计算列的存储过程。 不幸的是,我对存储过程的了解有限,但它似乎是正确的地方。我尝试提供更多背景信息:

主表存储声明,称为tabData。它有一个'IsReturn'列,数据类型为bit(boolean)。

1.Rule :声明是一个返回,当它的列值fimaxActionCode是这些1,2,3,4,5,8,9,12,14,17,18之一时,20,21,22,23,24,25,30,31,32,35。

2.Rule :声明 a具有先前声明(通过日期值和IMEI(移动设备的ID号码)识别的声明) ficlaimeStatus 1,4,6,254,255中的fimaxActionCode为8,10,11,13,19,23,24,26,27,28,29,30,33,34,36,37。

第一个Return-Rule是旧的,在ssas多维数据集中实现为计算列。因为现在情况比较复杂,我认为将计算放在每天早上执行的存储过程中会更好。

这是我必须检查候选人声明(规则1)是否因规则2而失败: 我创建了一个View'PrevClaim',它选择了之前的所有声明:

SELECT     TOP (100) PERCENT Claim.idData AS ClaimID, PrevClaim.idData AS PrevClaimID, Claim.IMEI, 
                      Claim.Repair_Completion_Date AS ClaimRepDate, PrevClaim.Repair_Completion_Date AS PrevClaimRepDate, 
                      PrevClaim.fimaxActionCode AS PrevFiMaxActionCode, PrevClaim.fiClaimStatus AS PrevFiClaimStatus, Claim.IsReturn AS ClaimIsReturn
FROM         dbo.tabData AS Claim INNER JOIN
                      dbo.tabData AS PrevClaim ON Claim.IMEI = PrevClaim.IMEI AND Claim.idData <> PrevClaim.idData AND 
                      Claim.Repair_Completion_Date > PrevClaim.Repair_Completion_Date
ORDER BY PrevClaimRepDate DESC

我可以使用此sql语句获取给定ID的最后一个Parent-Claim(此声明必须根据规则2进行验证):

SELECT     TOP (1) ClaimID, PrevClaimID, IMEI, ClaimRepDate, PrevClaimRepDate, PrevFiMaxActionCode, PrevFiClaimStatus
FROM         PrevClaim
WHERE     (ClaimID = 44921287)
ORDER BY PrevClaimRepDate DESC

但是现在我不知道如何/在哪里检查这个父索赔是否是规则2中的失败索赔。如果我修改此sql并将条件放入where子句我将得到错误的声明(考虑有4个父母索赔,最后时间还可以,但第四个失败,因此我将获得第四个回来,但必须与最后一个进行核对):

SELECT     TOP (1) ClaimID, PrevClaimID, ClaimRepDate, PrevClaimRepDate, PrevFiMaxActionCode, PrevFiClaimStatus
FROM         PrevClaim
WHERE     (ClaimID = 44921287) AND (PrevFiMaxActionCode IN (8, 10, 11, 13, 19, 23, 24, 26, 27, 28, 29, 30, 33, 34, 36, 37)) AND (PrevFiClaimStatus IN (1, 4, 254, 255, 6))
ORDER BY PrevClaimRepDate DESC

我要进入圈子,或者对于类似的东西来说太热了。 我希望有人可以引导我朝着正确的方向和/或向我展示如何在存储过程中实现它(UPDATE ... CASE但是如何?)。

编辑:我想我现在正走在正确的轨道上。也许有人可以告诉我如何在一个sql语句中更新整个表。以下用户定义的函数为我提供了正确的值:

    SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

CREATE FUNCTION dbo._isClaimReturn 
(
    @claimID  int,
    @fimaxActionCode int
)
RETURNS int
AS
BEGIN
 DECLARE @isReturn int

  IF(@fimaxActionCode in (1, 2, 3, 4, 5, 8, 9, 12, 14, 17, 18, 20, 21, 22, 23, 24, 25, 30, 31, 32, 35))
  AND (SELECT     TOP (1) PrevFiMaxActionCode
  FROM   PrevClaim
  WHERE     (ClaimID = @claimID))IN(8, 10, 11, 13, 19, 23, 24, 26, 27, 28, 29, 30, 33, 34, 36, 37)
  AND 
  (SELECT     TOP (1)PrevFiClaimStatus
  FROM         PrevClaim
  WHERE     (ClaimID = @claimID))IN(1, 4, 254, 255, 6)
  BEGIN
   Set @isReturn = 0
  END
 ELSE
  BEGIN
   Set @isReturn = 1
  END 

 RETURN @isReturn

END
GO

另一个问题:是否可以只使用一个查询?在我的函数中,我在PrevClaim-View上使用两个查询来检查Prev.Claim是否处于临界状态并且具有关键的MaxActioncode。

2 个答案:

答案 0 :(得分:1)

以下几行是否符合您的要求?

UPDATE tabData TD1
    SET TD1.IsReturn = 1
    WHERE TD1.fimaxActionCode IN (1, ...etc... , 35) AND
          NOT EXISTS (SELECT *
                          FROM tabData TD2
                          WHERE TD1.IMEI = TD2.IMEI AND
                                TD2.fimaxActionCode IN (8, ...etc... , 35) AND
                                TD2.fiClaimStatus   IN (1, 4, 254, 255, 6) AND
                                TD2.Repair_Completion_Date > TD1.Repair_Completion_Date);

我认为第一条规则是WHERE TD1.fimaxActionCode IN (1, ...etc... , 35)部分。 NOT EXISTS内的查询旨在检查第二条规则。如果我有点不对劲,您可能会看到正确的解决方案。如果我完全错了......呃......好吧,我们会尝试解决问题,希望我不会把你送错,浪费你的时间。

编辑以考虑第一条评论。

答案 1 :(得分:1)

您可以创建一个新的计算列,该列使用您在编辑中列出的UDF。这将确保价值始终是最新的。