更新sql server子表中的记录时更新父表计数

更新sql server子表中的记录时更新父表计数,sql,sql-server,Sql,Sql Server,我有两张桌子 部门(部门编号(primarykey)、部门名称、empcount) 员工信息(empid(primarykey)、姓名、deptid(外键)引用deptid) 当我更新EmployeeInfo中记录的deptid时,可以立即修改计数以适应相应的更改 子表中的更新将导致父表中的增量和减量。 我知道这可以通过触发器来完成,但是有没有一种方法可以使用存储过程IMHO,聚合值应该是需要更新的静态列 风景会更好。按需计数 但如果您坚持……这里有一个选项……它不需要与存储过程进行nsyn

我有两张桌子

  • 部门(部门编号(primarykey)、部门名称、empcount)
  • 员工信息(empid(primarykey)、姓名、deptid(外键)引用deptid)
当我更新
EmployeeInfo
中记录的
deptid
时,可以立即修改计数以适应相应的更改

子表中的更新将导致父表中的增量和减量。
我知道这可以通过触发器来完成,但是有没有一种方法可以使用存储过程

IMHO,聚合值应该是需要更新的静态列

风景会更好。按需计数

但如果您坚持……这里有一个选项……它不需要与存储过程进行nsync

-- START TSQL

SET NOCOUNT ON


IF EXISTS ( SELECT * FROM INFORMATION_SCHEMA.TABLES where TABLE_SCHEMA = N'dbo' and TABLE_NAME = N'Employee' and TABLE_TYPE = N'BASE TABLE' ) 
BEGIN 
DROP TABLE [dbo].[Employee] 
END 
GO


IF EXISTS ( SELECT * FROM INFORMATION_SCHEMA.TABLES where TABLE_SCHEMA = N'dbo' and TABLE_NAME = N'Department' and TABLE_TYPE = N'BASE TABLE' ) 
BEGIN 
DROP TABLE [dbo].[Department] 
END 
GO


DROP FUNCTION dbo.udfEmployeeCountByDepartment
GO



CREATE TABLE [dbo].[Department](
    [DepartmentUUID] [uniqueidentifier] NOT NULL,
    [TheVersionProperty] [timestamp] NOT NULL,
    [DepartmentName] [nvarchar](80) NULL,
    [CreateDate] [datetime] NOT NULL,
    [MyTinyInt] tinyint not null
    )


ALTER TABLE dbo.[Department] ADD CONSTRAINT PK_Department PRIMARY KEY NONCLUSTERED ([DepartmentUUID]) 
GO

ALTER TABLE [dbo].[Department] ADD CONSTRAINT CK_DepartmentName_Unique UNIQUE ([DepartmentName]) 
GO






CREATE TABLE [dbo].[Employee] ( 

    [EmployeeUUID] [uniqueidentifier] NOT NULL,
    [ParentDepartmentUUID] [uniqueidentifier] NOT NULL,
    [TheVersionProperty] [timestamp] NOT NULL,
    [SSN] [nvarchar](11) NOT NULL,
    [LastName] [varchar](64) NOT NULL,
    [FirstName] [varchar](64) NOT NULL,
    [CreateDate] [datetime] NOT NULL,
    [HireDate] [datetime] NOT NULL
    )

GO

ALTER TABLE dbo.Employee ADD CONSTRAINT PK_Employee PRIMARY KEY NONCLUSTERED (EmployeeUUID) 
GO


ALTER TABLE [dbo].[Employee] ADD CONSTRAINT CK_SSN_Unique UNIQUE (SSN) 
GO

ALTER TABLE [dbo].[Employee] ADD CONSTRAINT FK_EmployeeToDepartment FOREIGN KEY (ParentDepartmentUUID) REFERENCES dbo.Department (DepartmentUUID) 
GO

CREATE FUNCTION dbo.udfEmployeeCountByDepartment(@DepartmentUUID uniqueidentifier)
RETURNS int
AS
BEGIN
    DECLARE @returnCount int
    select @returnCount = count(*) from dbo.Employee e where e.ParentDepartmentUUID = @DepartmentUUID
    RETURN @returnCount
END

GO



ALTER TABLE [dbo].[Department] ADD [ComputedEmployeeCount] as (dbo.udfEmployeeCountByDepartment(DepartmentUUID))

GO



Select * from dbo.Department

INSERT [dbo].[Department] ( DepartmentUUID , DepartmentName , CreateDate )
Select NEWID() , 'DepartmentOne', CURRENT_TIMESTAMP
UNION ALL Select NEWID() , 'DepartmentTwo', CURRENT_TIMESTAMP
UNION ALL Select NEWID() , 'DepartmentThree', CURRENT_TIMESTAMP
UNION ALL Select NEWID() , 'DepartmentFour', CURRENT_TIMESTAMP



INSERT INTO [dbo].[Employee] ( 
    [EmployeeUUID] ,
    [ParentDepartmentUUID] ,
    [SSN] ,
    [LastName] ,
    [FirstName] ,
    [CreateDate],
    [HireDate] 
    )
SELECT NEWID() , (select top 1 DepartmentUUID from dbo.Department order by newid()), '111-11-1111', 'OneLN', 'OneFN',  CURRENT_TIMESTAMP,  CURRENT_TIMESTAMP
UNION ALL SELECT NEWID() , (select top 1 DepartmentUUID from dbo.Department order by newid()), '222-22-2222', 'TwoLN', 'TwoFN',  CURRENT_TIMESTAMP,  CURRENT_TIMESTAMP
UNION ALL SELECT NEWID() , (select top 1 DepartmentUUID from dbo.Department order by newid()), '333-33-3333', 'ThreeLN', 'ThreeFN',  CURRENT_TIMESTAMP,  CURRENT_TIMESTAMP
UNION ALL SELECT NEWID() , (select top 1 DepartmentUUID from dbo.Department order by newid()), '444-44-4444', 'FourLN', 'FourFN',  CURRENT_TIMESTAMP,  CURRENT_TIMESTAMP
UNION ALL SELECT NEWID() , (select top 1 DepartmentUUID from dbo.Department order by newid()), '555-55-5555', 'FiveLN', 'FiveFN',  CURRENT_TIMESTAMP,  CURRENT_TIMESTAMP
UNION ALL SELECT NEWID() , (select top 1 DepartmentUUID from dbo.Department order by newid()), '666-66-6666', 'SixLN', 'SixFN',  CURRENT_TIMESTAMP,  CURRENT_TIMESTAMP
UNION ALL SELECT NEWID() , (select top 1 DepartmentUUID from dbo.Department order by newid()), '777-77-7777', 'SevenLN', 'SevenFN',  CURRENT_TIMESTAMP,  CURRENT_TIMESTAMP
UNION ALL SELECT NEWID() , (select top 1 DepartmentUUID from dbo.Department order by newid()), '888-88-8888', 'EightLN', 'EightFN',  CURRENT_TIMESTAMP,  CURRENT_TIMESTAMP
UNION ALL SELECT NEWID() , (select top 1 DepartmentUUID from dbo.Department order by newid()), '999-99-9999', 'NineLN', 'NineFN',  CURRENT_TIMESTAMP,  CURRENT_TIMESTAMP


Select * from dbo.Department

我想这就是你想要的:

CREATE PROCEDURE dbo.UpdateDeptId(
@p_Employee_id int,
@p_NewDept_id int 
)
AS
BEGIN

UPDATE EmployeeInfo SET deptid = @p_NewDept_id
WHERE empid = @p_Employee_id

UPDATE T1  SET T1.EmpCount = T2.CountEmp
FROM Departments AS T1 INNER JOIN (SELECT deptid , Count(*) as CountEmp FROM EmployeeInfo GROUP BY deptid) AS T2
ON T1.deptid = T2.deptid

END

旁注:在列中存储聚合值不是最佳做法,请尝试使用视图,或者在需要时运行查询来检索它

当然有。你被什么卡住了?@Ghost我试图在更新之前保存deptid,然后减少计数,更新之后再次增加计数。这是一种令人厌烦的方式,为什么您仍然需要持久化
empcount
?您不能创建一个视图来返回此信息吗<代码>选择d.deptid、d.deptname、count(*)empcount从d.deptid=e.deptid上的部门d内部加入EmployeeInfo e。这些信息总是正确的,而不必在存储过程或触发器中编写任何代码。此外,存储过程不能在更新子表时自动运行-这就是触发器的作用。
empcount
自动更新的唯一方法是在存储过程中而不是直接在表中执行
EmployeeInfo
更新。@Skippy我只想在StoredProcess中更新EmployeeInfo,也要在同一StoredProcess中更新相应的计数