更新父表计数在SQL Server更新在子表中的记录
问题描述:
我有两个表更新父表计数在SQL Server更新在子表中的记录
- 部门(DEPTID(PrimaryKey的),DEPTNAME,empcount)
- EmployeeInfo( empid(primarykey),名称,deptid(foreign_key)参考deptid)
当我在EmployeeInfo
中更新deptid
记录,立即可以修改计数以适应相应的更改。
子表中的更新将导致父表中的增量和减量。 我知道这可以用一个触发器来完成,但有使用存储过程
答
我认为这是你在找什么:
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
侧面说明:这是不是最好的做法来存储,总价值IA柱,请尝试使用视图或只是运行一个查询在需要时检索它
答
恕我直言的方式,总价值应该不是静态列需要更新。
视图会更好。这可以按需点播。
但是,如果你坚持......这是一个选项....不需要具有存储过程的nsync-ness。
-- 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
当然有。你被卡住了什么? – UnhandledExcepSean
@Ghost我想在更新之前保存deptid,然后在更新之后递减计数,再次递增计数。这是乏味的方式 – Advaitha
为什么你需要坚持'empcount'呢?你不能只是创建一个视图来返回这些信息? 'select d.deptid,d.deptname,从Departments d的inner(*)empcount统计d.deptid = e.deptid'的内部联接EmployeeInfo。这些信息总是正确的,无需在存储过程或触发器中编写任何代码。此外,存储过程无法在更新子表时自动运行 - 这就是触发器的作用。 empcount更新自动发生的唯一方法是在存储过程中执行EmployeeInfo更新,而不是直接在表中执行。 – Skippy