请帮助我优化此代码,或者让我知道我是否可以更好地完成此操作。
请求:我正在更新Product
表,其中包含产品信息。
Product
表。product
表中更新的列是否为NULL或具有不同的值(与来自连接的值不同)。我正在使用游标来获取记录并创建动态更新查询,这将更新记录。
代码:
CREATE PROCEDURE [dbo].[UpdateProdCatalog]
AS
BEGIN
DECLARE @Tier_1_Tbl NVARCHAR(100) = NULL
DECLARE @Tier_2_Tbl NVARCHAR(100) = NULL
DECLARE @Flag_Tbl NVARCHAR(100) = NULL
DECLARE @Tier_1 NVARCHAR(100) = NULL
DECLARE @Tier_2 NVARCHAR(100) = NULL
DECLARE @Flag NVARCHAR(100) = NULL
DECLARE CurTaxonomy CURSOR FOR
SELECT CFR.T1,
CFR.T2,
CFR.Flag
FROM ProductCatalogue MPC
JOIN ControlFlow1 CF ON MPC.Product_Code = CF.Product_Code
JOIN ControlFlow2 CFR ON CF.MajorFamily = CFR.Product_Family
WHERE MPC.Manufacturer_Name = 'DELL';
OPEN CurTaxonomy
IF @@CURSOR_ROWS > 0
FETCH NEXT FROM CurTaxonomy INTO @Tier_1,@Tier_2,@Flag
WHILE @@Fetch_status = 0
BEGIN
--print @Tier_1 + ' : '+ @Tier_2 + ' : '+ @Flag
DECLARE CurProd CURSOR FOR
SELECT MPC.Tier_1,
MPC.Tier_2,
MPC.Flag
FROM ProductCatalogue MPC
WHERE MPC.Manufacturer_Name = 'DELL'
OPEN CurProd
IF @@CURSOR_ROWS > 0
FETCH NEXT FROM CurProd INTO @Tier_1_Tbl,@Tier_2_Tbl,@Flag_Tbl
WHILE @@Fetch_status = 0
BEGIN
--print @Tier_1_Tbl + ' : '+ @Tier_2_Tbl + ' : '+ @Flag_Tbl
DECLARE @sqlCommand VARCHAR(8000)
DECLARE @Starter VARCHAR(100)
--Generating dynamic update Query
SET @Starter = 'SET '
SET @sqlCommand = 'UPDATE ProductCatalogue '
BEGIN
IF ( @Tier_1 IS NOT NULL) AND (@Tier_1_Tbl IS NULL or @Tier_1_Tbl <> @Tier_1)
BEGIN SET @sqlCommand = @sqlCommand + @Starter + 'Tier_1 = ''' + @Tier_1 + '''' SET @Starter = ', ' END
IF ( @Tier_2 IS NOT NULL) AND (@Tier_2_Tbl IS NULL or @Tier_2_Tbl <> @Tier_2)
BEGIN SET @sqlCommand = @sqlCommand + @Starter + 'Tier_2 = ''' + @Tier_2 + '''' SET @Starter = ', ' END
IF ( @Flag IS NOT NULL) AND (@Flag_Tbl IS NULL or @Flag_Tbl <> @Flag)
BEGIN SET @sqlCommand = @sqlCommand + @Starter + 'Flag = ''' + @Flag + '''' SET @Starter = ', ' END
END
IF (@Starter = ', ')
BEGIN
SET @sqlCommand = @sqlCommand + @Starter + ' Last_Modify_Date = ''' + CONVERT(VARCHAR(22),SYSDATETIME(),121) + ''''
SET @sqlCommand = @sqlCommand + ' FROM ProductCatalogue MPC
JOIN ControlFlow1 CF ON MPC.Product_Code = CF.Product_Code
JOIN ControlFlow2 CFR ON CF.MajorFamily = CFR.Product_Family
WHERE MPC.Manufacturer_Name = ''' + 'DELL' + ''''
EXEC (@sqlCommand)
END
FETCH NEXT FROM CurProd INTO @Tier_1_Tbl,@Tier_2_Tbl,@Flag_Tbl
END
CLOSE CurProd
DEALLOCATE CurProd
FETCH NEXT FROM CurTaxonomy INTO @Tier_1,@Tier_2,@Flag
END
CLOSE CurTaxonomy
DEALLOCATE CurTaxonomy
END
我担心的是,这两个游标会运行一些 n x m 次,并且它也会为所有记录更新相同的值。我甚至试过这个工作正常。
update ProductCatalogue
set Tier_1 = CFR.T1,
Tier_2 = CFR.T2,
Flag=CFR.Flag,
Last_Modify_Date = SYSDATETIME()
from ProductCatalogue MPC
join ControlFlow1 CF on MPC.Product_Code = CF.Product_Code
join ControlFlow2 CFR on CF.MajorFamily = CFR.Product_Family;
但我还需要检查product
表中的现有记录并满足上述要求。如果有更好的方法可以做同样的事情,我将非常感激。
答案 0 :(得分:0)
到目前为止,我已经提出了这个解决方案....但是光标执行仍会循环 N x M 次。
代码:
CREATE PROCEDURE [dbo].[UpdateProdCatalog]
AS
BEGIN
DECLARE @Product_Code_Tbl NVARCHAR(100) = NULL
DECLARE @Tier_1_Tbl NVARCHAR(100) = NULL
DECLARE @Tier_2_Tbl NVARCHAR(100) = NULL
DECLARE @Flag_Tbl NVARCHAR(100) = NULL
DECLARE @Product_Code NVARCHAR(100) = NULL
DECLARE @Tier_1 NVARCHAR(100) = NULL
DECLARE @Tier_2 NVARCHAR(100) = NULL
DECLARE @Flag NVARCHAR(100) = NULL
DECLARE CurTaxonomy CURSOR FOR
SELECT MPC.Product_Code,
CFR.T1,
CFR.T2,
CFR.Flag
FROM ProductCatalogue MPC
JOIN ControlFlow1 CF ON MPC.Product_Code = CF.Product_Code
JOIN ControlFlow2 CFR ON CF.MajorFamily = CFR.Product_Family
WHERE MPC.Manufacturer_Name = 'DELL';
OPEN CurTaxonomy
IF @@CURSOR_ROWS > 0
FETCH NEXT FROM CurTaxonomy INTO @Product_Code, @Tier_1,@Tier_2,@Flag
WHILE @@Fetch_status = 0
BEGIN
DECLARE CurProd CURSOR FOR
SELECT MPC.Product_Code,
MPC.Tier_1,
MPC.Tier_2,
MPC.Flag
FROM ProductCatalogue MPC
JOIN ControlFlow1 CF ON MPC.Product_Code = CF.Product_Code
JOIN ControlFlow2 CFR ON CF.MajorFamily = CFR.Product_Family
WHERE MPC.Manufacturer_Name = 'DELL'
OPEN CurProd
IF @@CURSOR_ROWS > 0
FETCH NEXT FROM CurProd INTO @Product_Code_Tbl,@Tier_1_Tbl,@Tier_2_Tbl,@Flag_Tbl
WHILE @@Fetch_status = 0
BEGIN
DECLARE @sqlCommand VARCHAR(8000)
DECLARE @Starter VARCHAR(100)
SET @Starter = 'SET '
SET @sqlCommand = 'UPDATE ProductCatalogue '
if (@Product_Code IS NOT NULL) AND (@Product_Code_Tbl = @Product_Code)
BEGIN
IF ( @Tier_1 IS NOT NULL) AND (@Tier_1_Tbl IS NULL or @Tier_1_Tbl <> @Tier_1)
BEGIN SET @sqlCommand = @sqlCommand + @Starter + 'Tier_1 = ''' + @Tier_1 + '''' SET @Starter = ', ' END
IF ( @Tier_2 IS NOT NULL) AND (@Tier_2_Tbl IS NULL or @Tier_2_Tbl <> @Tier_2)
BEGIN SET @sqlCommand = @sqlCommand + @Starter + 'Tier_2 = ''' + @Tier_2 + '''' SET @Starter = ', ' END
IF ( @Flag IS NOT NULL) AND (@Flag_Tbl IS NULL or @Flag_Tbl <> @Flag)
BEGIN SET @sqlCommand = @sqlCommand + @Starter + 'Flag = ''' + @Flag + '''' SET @Starter = ', ' END
END
IF (@Starter = ', ')
BEGIN
SET @sqlCommand = @sqlCommand + @Starter + ' Last_Modify_Date = ''' + CONVERT(VARCHAR(22),SYSDATETIME(),121) + ''''
SET @sqlCommand = @sqlCommand + ' WHERE Product_Code = ''' + @Product_Code + ''' and Manufacturer_Name = ''' + 'DELL' + ''''
EXEC (@sqlCommand)
END
FETCH NEXT FROM CurProd INTO @Product_Code_Tbl,@Tier_1_Tbl,@Tier_2_Tbl,@Flag_Tbl
END
CLOSE CurProd
DEALLOCATE CurProd
FETCH NEXT FROM CurTaxonomy INTO @Product_Code, @Tier_1,@Tier_2,@Flag
END
CLOSE CurTaxonomy
DEALLOCATE CurTaxonomy
END
GO