Sql server 在SQL Server中使用嵌套游标更新表
请帮助我优化这段代码,或者让我知道我是否可以用更好的方式来做 请求:我正在更新包含产品信息的Sql server 在SQL Server中使用嵌套游标更新表,sql-server,join,sql-update,cursor,dynamicquery,Sql Server,Join,Sql Update,Cursor,Dynamicquery,请帮助我优化这段代码,或者让我知道我是否可以用更好的方式来做 请求:我正在更新包含产品信息的产品表 其思想是通过join从其他表中获取一些列。(curTaxonomy正在这样做。) 然后将获取的记录更新到Product表中 但在此之前,我需要检查我在product表中更新的列是否为NULL或具有不同的值(与来自join的值不同) 如果这些条件匹配,则仅更新列 我正在使用游标获取记录,并创建动态更新查询来更新记录 代码: CREATE PROCEDURE [dbo].[UpdateProdCa
产品表
- 其思想是通过join从其他表中获取一些列。(curTaxonomy正在这样做。)
- 然后将获取的记录更新到
Product
表中
- 但在此之前,我需要检查我在
product
表中更新的列是否为NULL或具有不同的值(与来自join的值不同)
- 如果这些条件匹配,则仅更新列李>
我正在使用游标获取记录,并创建动态更新查询来更新记录
代码:
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
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
但我还需要检查产品
表中的现有记录,并满足上述要求。如果有更好的方法,我们将不胜感激 到目前为止,我已经提出了这个解决方案……但游标执行仍将循环nxm次
代码:
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
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
创建过程[dbo]。[UpdateProdCatalog]
作为
开始
声明@Product_Code_Tbl NVARCHAR(100)=空
声明@Tier_1_Tbl NVARCHAR(100)=空
声明@Tier_2_Tbl NVARCHAR(100)=空
声明@Flag_Tbl NVARCHAR(100)=空
声明@Product_代码NVARCHAR(100)=空
声明@Tier_1 NVARCHAR(100)=空
声明@Tier_2 NVARCHAR(100)=空
声明@Flag NVARCHAR(100)=NULL
声明的CurTaxonomy游标
选择MPC.Product\U代码,
CFR.T1,
CFR.T2,
CFR.旗
来自产品目录MPC
在MPC.Product\U Code=CF.Product\U Code上加入ControlFlow1 CF
在CF.MajorFamily=CFR.Product\u系列上加入ControlFlow2 CFR
其中,MPC.Manufacturer_Name='DELL';
开放式屈膝术
如果@@CURSOR\u行>0
从CurTaxonomy获取下一个到@Product_Code、@Tier_1、@Tier_2、@Flag
而@@Fetch\u status=0
开始
将CurProd游标声明为
选择MPC.Product\U代码,
MPC.Tier_1,
MPC.Tier_2,
旗帜
来自产品目录MPC
在MPC.Product\U Code=CF.Product\U Code上加入ControlFlow1 CF
在CF.MajorFamily=CFR.Product\u系列上加入ControlFlow2 CFR
其中MPC.Manufacturer_Name='DELL'
开放式CurProd
如果@@CURSOR\u行>0
从CurProd获取下一个到@Product\u Code\u Tbl、@Tier\u 1\u Tbl、@Tier\u 2\u Tbl、@Flag\u Tbl
而@@Fetch\u status=0
开始
声明@sqlCommand VARCHAR(8000)
声明@Starter VARCHAR(100)
SET@Starter='SET'
SET@sqlCommand='updateproductcatalog'
如果(@Product\U Code不为空)和(@Product\U Code\U Tbl=@Product\U Code)
开始
如果(@Tier_1不为空)和(@Tier_1_Tbl为空或@Tier_1_Tbl@Tier_1)
开始设置@sqlCommand=@sqlCommand++@Starter+'Tier_1=''''+@Tier_1+'''''''SET@Starter='','结束
如果(@Tier_2不为空)和(@Tier_2_Tbl为空或@Tier_2_Tbl@Tier_2)
开始设置@sqlCommand=@sqlCommand+@Starter+'Tier_2=''''+@Tier_2+''''''SET@Starter=','结束
如果(@Flag不为NULL)和(@Flag\u Tbl为NULL或@Flag\u Tbl@Flag)
开始设置@sqlCommand=@sqlCommand++@Starter+'Flag='''+@Flag++'''设置@Starter='','结束
结束
如果(@Starter=','))
开始
SET@sqlCommand=@sqlCommand++@Starter+'Last\u Modify\u Date=''''+转换(VARCHAR(22),SYSDATETIME(),121)+'''
设置@sqlCommand=@sqlCommand+',其中产品代码=''+@Product\u代码+'',制造商名称='''+'戴尔'+'''''
EXEC(@sqlCommand)
结束
从CurProd获取下一个到@Product\u Code\u Tbl、@Tier\u 1\u Tbl、@Tier\u 2\u Tbl、@Flag\u Tbl
结束
闭合电流
解除分配CurProd
从CurTaxonomy获取下一个到@Product_Code、@Tier_1、@Tier_2、@Flag
结束
近距离屈膝术
解除分配权责
结束
去
您应该尝试删除光标。您可以使用UPDATE语句的OUTPUT子句输出到一个临时表,该临时表可用于更新产品表。请在产品表中向我们显示您要更新的内容。@SteveFord:嗨,Steve,我提到我需要更新,Tier_1
,Tier_2
,Flag
和Last_Modify_Date
值到product
表中。当这些列为null或与我们从加入产品
、控制流1
和控制流2
表中得到的值不同时,也会出现这种情况。有关更多说明,请参阅游标CurTaxonomy
的Select语句。