SQL存储过程变得与众不同并更新

时间:2014-07-16 09:50:04

标签: sql sql-server sql-server-2008

首先让我先说我可以在.NET中执行以下操作,但我希望它在正确的位置并减轻服务器上的压力。所以我可能会以我试图构建它的方式倾向于.NET!

查询/目标:

显示用户(通过EmployeeID)在TblTableList中的次数,然后更新TblTableStatusCount

现在我假设EmployeeID存在。我已经查看了stackoverflow上的各种示例,包括游标,但说实话,我有点困惑,并会对任何指导感到高兴。

还需要了解如何将值传递给@ Status0Count等。

使用:Microsoft SQL Server 2008(在这种情况下为.NET2,但通常为3.5或4)

代码:

 USE [Database]
    GO
    /****** Object:  StoredProcedure [dbo].[spUpdatePassword]    Script Date: 07/16/2014 10:15:58 ******/
    SET ANSI_NULLS ON
    GO
    SET QUOTED_IDENTIFIER ON
    GO
    ALTER PROCEDURE [dbo].[spActionsDashboardSitesSummary]
        -- Add the parameters for the stored procedure here

    @EmployeeID NvarChar(10), --These may change to limited size i.e. 10
    @Status0 Int,
    @Status1 Int,
    @Status2 Int,
    @Status3 Int

    AS
    BEGIN

    SELECT * FROM [TblTableMain] 

      BEGIN
        SELECT COUNT(DISTINCT(ID)) FROM TblTableList WHERE EmployeeID = @EmployeeID  
        SELECT COUNT(DISTINCT(ID)) FROM TblTableList WHERE EmployeeID = @EmployeeID AND CurrentAlertStatus = '0'
        SELECT COUNT(DISTINCT(ID)) FROM TblTableList WHERE EmployeeID = @EmployeeID AND CurrentAlertStatus = '1'
        SELECT COUNT(DISTINCT(ID)) FROM TblTableList WHERE EmployeeID = @EmployeeID AND CurrentAlertStatus = '2'

        -- Check if ID Exists       

        IF EXISTS (SELECT @EmployeeID FROM TblTableStatusCount WHERE EmployeeID = @EmployeeID)

            UPDATE TblTableStatusCount 
            SET StatusTotalCount = @StatusTotal, Status0Count = @Status0, Status1Count = @Status1, Status2Count = @Status2
            WHERE EmployeeID = @EmployeeID
          Else
            INSERT INTO TblTableStatusCount 
            EmployeeID , StatusTotalCount, Status0Count, Status1Count , Status2Count) VALUES (@EmployeeID , @StatusTotal,@Status0, @Status1, @Status2 )
            WHERE EmployeeID = @EmployeeID

        END

    END

我非常乐意澄清任何事情

编辑 - 包含SELECT和DECLARE的更新代码

  USE [database] 
GO
/****** Object:  StoredProcedure [dbo].[spUpdatePassword]    Script Date: 07/16/2014 10:15:58 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
Alter PROCEDURE [dbo].[spActionsDashboardSitesSummary]
    -- Add the parameters for the stored procedure here

AS

BEGIN

DECLARE @StatusTotal AS Int
DECLARE @Status0 AS Int
DECLARE @Status1 AS Int
DECLARE @Status2 AS Int
DECLARE @Status3 AS Int

--Cursor to loop through
DECLARE @PropertyID  AS NvarChar(10);
DECLARE propCurs CURSOR FOR
SELECT  PropertyID FROM [tbPropertyDetails]

--Open Loop Code
OPEN propCurs;
FETCH NEXT FROM propCurs INTO @PropertyID
WHILE @@FETCH_STATUS = 0  
--Now do repeated code

  BEGIN

 --   SELECT @StatusTotal = COUNT(ID) FROM TblActions WHERE PropertyID = @PropertyID  
    --SELECT @Status0 =  COUNT(DISTINCT(ID)) FROM TblActions WHERE PropertyID = @PropertyID AND CurrentAlertStatus = '0'
    --SELECT @Status1 =  COUNT(DISTINCT(ID)) FROM TblActions WHERE PropertyID = @PropertyID AND CurrentAlertStatus = '1'
    --SELECT @Status2 =  COUNT(DISTINCT(ID)) FROM TblActions WHERE PropertyID = @PropertyID AND CurrentAlertStatus = '2'
    --SELECT @Status3 =  COUNT(DISTINCT(ID)) FROM TblActions WHERE PropertyID = @PropertyID AND CurrentAlertStatus = '3'

with cnt as ( 
   SELECT 
     1 as cntAll 
     , case WHEN CurrentAlertStatus = '0' then 1 else 0  end as cnt1
     , case WHEN CurrentAlertStatus = '1' then 1 else 0  end as cnt2
     , case WHEN CurrentAlertStatus = '2' then 1 else 0  end as cnt3
      , case WHEN CurrentAlertStatus = '3' then 1 else 0  end as cnt4
   from TblActions where PropertyID = @PropertyID
)
SELECT @StatusTotal = sum(cntAll),  
  @Status0  = sum(cnt1),
  @Status1  = sum(cnt2),
  @Status2  = sum(cnt3),
  @Status3  = sum(cnt4)
  FROM cnt;
    -- Check if ID Exists

    --HERE NEED TO CHECK IF EXISTS OR SHOULD I WIPE THE TABLE AT THE START? 
    IF EXISTS (SELECT PropertyID FROM [TblActionsCount] WHERE @PropertyID = PropertyID)

        UPDATE TblActionsCount 
        SET StatusTotalCount = @StatusTotal, Status0 = @Status0, Status1 = @Status1, Status2 = @Status2, Status3 = @Status3
        WHERE PropertyID = @PropertyID
      Else
        INSERT INTO [TblActionsCount] 
        (PropertyID, StatusTotalCount, Status0, Status1 , Status2, Status3) VALUES (@PropertyID, @StatusTotal,@Status0, @Status1, @Status2,@Status3 )

    END

    -- Now we bookend the loop code

    FETCH NEXT FROM propCurs INTO @PropertyID

END

--Tidy up and close loop code
CLOSE propCurs;
DEALLOCATE propCurs;

2 个答案:

答案 0 :(得分:1)

您需要赋予@Status0,...适当的值。尝试这样做:

SELECT @Status0 = COUNT(DISTINCT(ID)) FROM TblTableList 
  WHERE EmployeeID = @EmployeeID;
SELECT @Status1 = COUNT( ...

此外,可以使用CTE(公用表表达式)简化计数查询:

; with cnt as ( 
   SELECT 
     1 as cntAll 
     , case WHEN CurrentAlertStatus = '0' then 1 else 0  end as cnt1
     , case WHEN CurrentAlertStatus = '1' then 1 else 0  end as cnt2
     , case WHEN CurrentAlertStatus = '2' then 1 else 0  end as cnt3
   from TblTableList where EmployeeID = @EmployeeID
)
select @StatusTotal = sum(cntAll),  
  @Status0  = sum(cnt1),
  @Status1  = sum(cnt2),
  @Status2  = sum(cnt3),
  from cnt;

我认为,您的ID是唯一的主键,因此不需要DISTINCT过滤

修改

上面代码周围的光标:

DECLARE @PropertyID int;
DECLARE propCurs CURSOR FOR  
SELECT PropertyID
FROM tbPropertyDetails;

OPEN propCurs
FETCH NEXT FROM propCurs INTO @PropertyID
WHILE @@FETCH_STATUS = 0   
BEGIN 
  ...--code here

  FETCH NEXT FROM propCurs INTO @PropertyID;  
END   
CLOSE propCurs;
DEALLOCATE propCurs;

答案 1 :(得分:0)

您可以使用与@StatusTotal相同的查询但没有distinct.That会获取table.distinct中的用户始终只给出'1'的次数,因为我们在where子句中有id。