我有一个存储过程,用另一个表中的数据填充表。 当我使用Update Trigger执行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
答案 0 :(得分:2)
问题是您用于生成数字计数表的代码
WITH Tally (N) AS
(SELECT TOP (12) ROW_NUMBER() OVER (ORDER BY (SELECT 0)) FROM master.sys.objects)
当我以具有有限权限的用户身份登录时select * FROM master.sys.objects
仅返回6个项目,而以sa登录时返回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,