2010-12-03 27 views
0

我有一個存儲過程,使用另一個表中的數據填充表。 當我使用更新觸發器執行SP 3記錄被插入到表中。存儲過程返回不同的結果,如果從觸發器與手動執行

如果我手動執行SP,我會在表中獲得6條記錄。

'SET ANSI_NULLS ON', 
'SET QUOTED_IDENTIFIER ON', 
'SET NOCOUNT ON' 

在SP和觸發器中是相同的。

這是SP:

SET ANSI_NULLS ON 
GO 
SET QUOTED_IDENTIFIER ON 
GO 
-- ============================================= 
-- Author:  
-- Create date: 
-- Description:  
-- ============================================= 
ALTER PROCEDURE [dbo].[Residency_Date_Summary_Populate] 
-- Add the parameters for the stored procedure here 

AS 
BEGIN 
-- SET NOCOUNT ON added to prevent extra result sets from 
-- interfering with SELECT statements. 
SET NOCOUNT ON; 

DECLARE @StartDate datetime; 
SET @StartDate = DateAdd(year, DateDiff(year, 0, GetDate()), 0); 

WITH Tally (N) AS 
(SELECT TOP (12) ROW_NUMBER() OVER (ORDER BY (SELECT 0)) 
FROM master.sys.objects), CTE1 AS 
(SELECT c.First_Name, 
    c.Last_Name, 
    c.ID, 
    r.Building,  
    r.Move_In_Date, 
    r.Move_Out_Date, 
    StartOfMonth = DateAdd(month, t1.N-1, @StartDate), 
    EndOfMonth = DateAdd(day, -1, DateAdd(month, t1.N, @StartDate)), 
    MonthNbr = t1.N 
FROM CONTACTS c 
    JOIN Residency_Dates r 
    ON c.ID = r.ID_U  
    JOIN Tally t1 
    ON t1.N between month(r.move_in_date) and month(coalesce(r.move_out_date,  getdate ()))), CTE2 AS 
    (SELECT First_Name, 
    Last_Name, 
    Building, 
    MonthNbr, 
    ID 
    ,StayForMonth = CASE WHEN Move_In_Date > StartOfMonth AND Move_out_Date <=  EndOfMonth 
    THEN DateDiff(day, Move_In_Date, Move_Out_Date) 
     WHEN Move_In_Date > StartOfMonth 
    THEN DateDiff(day, Move_In_Date, EndOfMonth) 
     WHEN Move_out_Date > EndOfMonth 
    THEN DateDiff(day, StartOfMonth, EndOfMonth) 
     WHEN Move_out_Date IS NULL AND month(StartOfMonth) = month(GetDate()) 
    THEN DateDiff(day, StartOfMonth, GetDate()) 
     ELSE DateDiff(day, StartOfMonth, COALESCE(Move_Out_Date, EndOfMonth)) 
    END  
FROM CTE1) 
INSERT into Residency_Date_Summary 

SELECT First_Name, 
    Last_Name, 
    Building, 
    January = MAX(CASE WHEN MonthNbr = 1 THEN StayForMonth ELSE 0 END), 
    February = MAX(CASE WHEN MonthNbr = 2 THEN StayForMonth ELSE 0 END), 
    March = MAX(CASE WHEN MonthNbr = 3 THEN StayForMonth ELSE 0 END), 
    April = MAX(CASE WHEN MonthNbr = 4 THEN StayForMonth ELSE 0 END), 
    May = MAX(CASE WHEN MonthNbr = 5 THEN StayForMonth ELSE 0 END), 
    June = MAX(CASE WHEN MonthNbr = 6 THEN StayForMonth ELSE 0 END), 
    July = MAX(CASE WHEN MonthNbr = 7 THEN StayForMonth ELSE 0 END), 
    August = MAX(CASE WHEN MonthNbr = 8 THEN StayForMonth ELSE 0 END), 
    September = MAX(CASE WHEN MonthNbr = 9 THEN StayForMonth ELSE 0 END), 
    October = MAX(CASE WHEN MonthNbr = 10 THEN StayForMonth ELSE 0 END), 
    November = MAX(CASE WHEN MonthNbr = 11 THEN StayForMonth ELSE 0 END), 
    December = MAX(CASE WHEN MonthNbr = 12 THEN StayForMonth ELSE 0 END) 
FROM CTE2 
GROUP BY First_Name, Last_Name, Building 
ORDER BY Last_Name, First_Name, Building; 

End 
+1

它是否正在使用相同的登錄?它對`sys.objects`有權限嗎? – 2010-12-03 23:21:15

回答

2

的問題是您正在使用,以生成數字

WITH Tally (N) AS 
(SELECT TOP (12) ROW_NUMBER() OVER (ORDER BY (SELECT 0)) FROM master.sys.objects) 

的計數表時,我的身份登錄的權限有限select * FROM master.sys.objects回報用戶代碼以sa身份登錄時只有6個項目與82個項目相比較。因此,您的理貨表只會有6個項目,而不是您在某些登錄時運行時預期的12個項目。

坦率地說,將登錄添加到sysadmin組中的「修復」是可笑的。如果另一個登錄觸發觸發器,並且如果您的應用程序有任何SQL注入漏洞給予登錄系統管理員權限將允許攻擊者執行任何操作,您仍然會遇到問題。

所有你需要做的是更換

WITH Tally (N) AS 
(SELECT TOP (12) ROW_NUMBER() OVER (ORDER BY (SELECT 0)) 
FROM master.sys.objects), CTE1 AS 
(SELECT c.First_Name, 
    c.Last_Name, 

WITH E00(N) AS (SELECT 1 UNION ALL SELECT 1), 
    E02(N) AS (SELECT 1 FROM E00 a, E00 b), 
    E04(N) AS (SELECT 1 FROM E02 a, E02 b), 
    Tally (N) AS (SELECT TOP (12) ROW_NUMBER() OVER (ORDER BY (SELECT 0)) FROM E04), 
    CTE1 AS 
(SELECT c.First_Name, 
    c.Last_Name, 
+0

對不起,但我不太明白你的答案。你是否說數據庫用戶分配的權限過多? – Stan 2010-12-04 00:58:05

相關問題