2010-12-03 3 views
0

다른 테이블의 데이터로 테이블을 채우는 저장 프로 시저가 있습니다. 업데이트 트리거를 사용하여 SP 3을 실행하면 레코드가 테이블에 삽입됩니다.저장 프로 시저가 트리거 대 수동에서 실행될 경우 다른 결과를 반환합니다.

SP를 수동으로 실행하면 테이블에 6 개의 레코드가 생성됩니다.

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

은 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

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, 

을 대체한다? 그것은'sys.objects'에 대한 허가를 가지고 있습니까? –

답변

2

문제는 당신은 내가 제한된 권한 select * FROM master.sys.objects 반환을 가진 사용자로 로그인하면 숫자

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

의 집계 테이블을 생성하기 위해 사용하는 코드는 다음과 같습니다

은 SP입니다 sa로 로그인 한 경우 82 개에 비해 6 개 항목 만 표시됩니다. 결과적으로 탤리 테이블에는 특정 로그인하에 실행될 때 예상 한 12 개가 아닌 6 개의 항목 만 있습니다.

sysadmin 그룹에 로그인을 추가하는 "솔류션"은 말도 안됩니다. 다른 로그인이 트리거를 실행하고 응용 프로그램에 SQL 주입 취약점이있는 경우 로그인 sysadmin 권한을 부여하면 공격자가 아무 것도 할 수 없게되므로 문제가 계속 발생합니다.

당신이해야 할 모든이 동일한 로그인이 사용되는

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

+0

@Stan - 아니요. 당신의 코드'WITH Tally (N) (SELECT TOP (12) ROW_NUMBER() 이상 (ORDER BY (SELECT 0) FROM master.sys.objects) 이 쿼리로 12 개 미만의 행이 반환되면 1-12의 숫자 표를 생성 할 때 예상대로 작동합니다. 반환되는 행 수는 사용 권한에 따라 다릅니다. –

+0

@ 마틴 - 도와 줘서 고마워. 나는 당신의 말을 이해하고 있습니다 ... 제 SQL 경험은 매우 제한되어 있습니다. 당신이 말하는 것을 충분히 이해하지 못하고 있습니다 ... 나와 함께 견뎌주십시오. 귀하의 예제를 활용하기 위해 코드를 수정하는 방법은 무엇입니까? 귀하의 예를 사용하여 업데이트를 시도했지만 제대로 작동하지 않았습니다. – Stan

관련 문제