逐行更新SQL表中的数据
我正在使用SQLServer2008R2。我有一个链接服务器的视图[EmployeeMaster]和数据库中的表[EmployeeDetails]。我有一个每天早上12点运行的服务,它调用一个存储过程来同步表和视图。即,存储过程检查[EmployeeDetails]中的每一行,并使用视图中的匹配行更新该行。我的存储过程是这样的逐行更新SQL表中的数据,sql,sql-server,stored-procedures,sql-server-2008-r2,Sql,Sql Server,Stored Procedures,Sql Server 2008 R2,我正在使用SQLServer2008R2。我有一个链接服务器的视图[EmployeeMaster]和数据库中的表[EmployeeDetails]。我有一个每天早上12点运行的服务,它调用一个存储过程来同步表和视图。即,存储过程检查[EmployeeDetails]中的每一行,并使用视图中的匹配行更新该行。我的存储过程是这样的 CREATE PROCEDURE usp_OracleSyncUpdate AS CREATE TABLE #ActiveEmployees ( RowID int
CREATE PROCEDURE usp_OracleSyncUpdate
AS
CREATE TABLE #ActiveEmployees (
RowID int IDENTITY(1, 1),
[EmployeeId] nvarchar(50),
)
DECLARE @NumberRecords int, @RowCount int
DECLARE @EmployeeId nvarchar(50)
,@EmployeeName nvarchar(50)
,@EmployeeLastName nvarchar(50)
,@EmployeeCategory nvarchar(50)
,@ContactNo nvarchar(50)
,@Email nvarchar(50)
,@Gender nvarchar(50)
,@JoiningDate DATETIME
-- into the temporary table
INSERT INTO #ActiveEmployees ([EmployeeId])
SELECT [EMPLOYEE_NUMBER]
FROM [dbo].[EmployeeMaster]
WHERE [EMPLOYEE_NUMBER] IN (
SELECT EmployeeId
FROM [dbo].[EmployeeDetails]
)
-- Get the number of records in the temporary table
SET @NumberRecords = @@ROWCOUNT
SET @RowCount = 1
-- loop through all records in the temporary table
-- using the WHILE loop construct
WHILE @RowCount <= @NumberRecords
BEGIN
SELECT @EmployeeId = EmployeeId
FROM #ActiveEmployees
WHERE RowID = @RowCount
SELECT @EmployeeName = EmployeeName FROM [dbo].[EmployeeDetails] WHERE [EmployeeId] = @EmployeeId
IF(LTRIM(RTRIM(@EmployeeName)) <> (SELECT LTRIM(RTRIM([FIRST_NAME])) FROM [dbo].[EmployeeMaster] WHERE [EMPLOYEE_NUMBER] = @EmployeeId))
BEGIN
UPDATE [dbo].[EmployeeDetails] SET EmployeeName = (SELECT LTRIM(RTRIM([FIRST_NAME])) FROM [dbo].[EmployeeMaster] WHERE [EMPLOYEE_NUMBER] = @EmployeeId)
WHERE EmployeeId = @EmployeeId
END
SELECT @EmployeeLastName = EmployeeLastName FROM [dbo].[EmployeeDetails] WHERE [EmployeeId] = @EmployeeId
IF(LTRIM(RTRIM(@EmployeeLastName)) <> (SELECT LTRIM(RTRIM([LAST_NAME])) FROM [dbo].[EmployeeMaster] WHERE [EMPLOYEE_NUMBER] = @EmployeeId))
BEGIN
UPDATE [dbo].[EmployeeDetails] SET EmployeeLastName = (SELECT LTRIM(RTRIM([LAST_NAME])) FROM [dbo].[EmployeeMaster] WHERE [EMPLOYEE_NUMBER] = @EmployeeId)
WHERE EmployeeId = @EmployeeId
END
SELECT @EmployeeCategory = [Category] FROM [dbo].[EmployeeCategory] WHERE [EmployeeCategoryId] = (SELECT [EmployeeCategoryId] FROM [dbo].[EmployeeDetails] WHERE [EmployeeId] = @EmployeeId)
IF(LTRIM(RTRIM(@EmployeeCategory)) <> (SELECT LTRIM(RTRIM([JOB_NAME])) FROM [dbo].[EmployeeMaster] WHERE [EMPLOYEE_NUMBER] = @EmployeeId))
BEGIN
UPDATE [dbo].[EmployeeDetails] SET [EmployeeCategoryId] = (SELECT [EmployeeCategoryId] FROM [dbo].[EmployeeCategory] WHERE [Category] = (SELECT LTRIM(RTRIM([JOB_NAME])) FROM [dbo].[EmployeeMaster] WHERE [EMPLOYEE_NUMBER] = @EmployeeId))
WHERE EmployeeId = @EmployeeId
END
SELECT @Email = Email FROM [dbo].[EmployeeDetails] WHERE [EmployeeId] = @EmployeeId
IF(LTRIM(RTRIM(@Email)) <> (SELECT LTRIM(RTRIM([EMAIL_ADDRESS])) FROM [dbo].[EmployeeMaster] WHERE [EMPLOYEE_NUMBER] = @EmployeeId))
BEGIN
UPDATE [dbo].[EmployeeDetails] SET Email = (SELECT LTRIM(RTRIM([EMAIL_ADDRESS])) FROM [dbo].[EmployeeMaster] WHERE [EMPLOYEE_NUMBER] = @EmployeeId)
WHERE EmployeeId = @EmployeeId
END
SELECT @Gender = Gender FROM [dbo].[EmployeeDetails] WHERE [EmployeeId] = @EmployeeId
IF(LTRIM(RTRIM(@Gender)) <> (SELECT LTRIM(RTRIM([GENDER])) FROM [dbo].[EmployeeMaster] WHERE [EMPLOYEE_NUMBER] = @EmployeeId))
BEGIN
UPDATE [dbo].[EmployeeDetails] SET Gender = (SELECT LTRIM(RTRIM([GENDER])) FROM [dbo].[EmployeeMaster] WHERE [EMPLOYEE_NUMBER] = @EmployeeId)
WHERE EmployeeId = @EmployeeId
END
SELECT @JoiningDate = JoiningDate FROM [dbo].[EmployeeDetails] WHERE [EmployeeId] = @EmployeeId
IF(LTRIM(RTRIM(@JoiningDate)) <> (SELECT LTRIM(RTRIM([DATE_OF_JOINING])) FROM [dbo].[EmployeeMaster] WHERE [EMPLOYEE_NUMBER] = @EmployeeId))
BEGIN
UPDATE [dbo].[EmployeeDetails] SET JoiningDate = (SELECT LTRIM(RTRIM([DATE_OF_JOINING])) FROM [dbo].[EmployeeMaster] WHERE [EMPLOYEE_NUMBER] = @EmployeeId)
WHERE EmployeeId = @EmployeeId
END
SET @RowCount = @RowCount + 1
END
-- drop the temporary table
DROP TABLE #ActiveEmployees
谢谢@marc_s好吧,不用循环,而是在一条sql语句中完成它,然后用它来完成。真的 我看到了一个循环,看到了大量的独立语句,我可以想象这只是一个UPATE语句
在顶部,这不是“休表”。它很小。超小的。一百万行很小。这还不到27000行。你只是通过“程序员方法”——循环,太多的语句来滥用服务器。使用基于集合的方法,您的整个循环可以写成一条语句。摆脱RBAR(一行一行)处理-关系数据库在数据集合中工作-使用单个基于集合的
语句,您就完成了
大致如下:
CREATE PROCEDURE usp_OracleSyncUpdate
AS
CREATE TABLE #ActiveEmployees (
RowID int IDENTITY(1, 1),
[EmployeeId] nvarchar(50),
)
-- into the temporary table
INSERT INTO #ActiveEmployees ([EmployeeId])
SELECT [EMPLOYEE_NUMBER]
FROM [dbo].[EmployeeMaster]
WHERE [EMPLOYEE_NUMBER] IN (SELECT EmployeeId
FROM [dbo].[EmployeeDetails])
UPDATE dbo.EmployeeDetails
SET ed.EmployeeName = LTRIM(RTRIM(ae.FIRST_NAME)),
ed.EmployeeLastName = (SELECT LTRIM(RTRIM(ae.LAST_NAME)),
ed.EmployeeCategoryId = ec.EmployeeCategoryId,
ed.Email = ae.Email,
ed.Gender = ae.Gender,
ed.JoiningDate = ae.JoiningDate
FROM dbo.EmployeeDetails ed
INNER JOIN #ActiveEmployees ae ON ed.EmployeeId = ae.EmployeeId
INNER JOIN dbo.EmployeeCategory ec ON .......
WHERE EmployeeId = @EmployeeId
我不知道EmployeeCategory
表是如何链接到其他表的-您需要在那里的内部联接
行中添加JOIN
条件
另外,您也可以完全删除临时表,直接从
EmployeeMaster
更新EmployeeDetails
,作为节省内存和处理时间的第二步。请更改标题:更新超小表。甚至没有一百万行——这是很小的。优化的一种方法是避免RBAR(一行接一行)处理,而是使用基于集合的UPDATE
语句……感谢您的快速响应。我将实施这一计划,并让所有人都知道结果。非常感谢。
CREATE PROCEDURE usp_OracleSyncUpdate
AS
CREATE TABLE #ActiveEmployees (
RowID int IDENTITY(1, 1),
[EmployeeId] nvarchar(50),
)
-- into the temporary table
INSERT INTO #ActiveEmployees ([EmployeeId])
SELECT [EMPLOYEE_NUMBER]
FROM [dbo].[EmployeeMaster]
WHERE [EMPLOYEE_NUMBER] IN (SELECT EmployeeId
FROM [dbo].[EmployeeDetails])
UPDATE dbo.EmployeeDetails
SET ed.EmployeeName = LTRIM(RTRIM(ae.FIRST_NAME)),
ed.EmployeeLastName = (SELECT LTRIM(RTRIM(ae.LAST_NAME)),
ed.EmployeeCategoryId = ec.EmployeeCategoryId,
ed.Email = ae.Email,
ed.Gender = ae.Gender,
ed.JoiningDate = ae.JoiningDate
FROM dbo.EmployeeDetails ed
INNER JOIN #ActiveEmployees ae ON ed.EmployeeId = ae.EmployeeId
INNER JOIN dbo.EmployeeCategory ec ON .......
WHERE EmployeeId = @EmployeeId