Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/27.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server 在SQL Server中使用嵌套游标更新表_Sql Server_Join_Sql Update_Cursor_Dynamicquery - Fatal编程技术网

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语句。