一次运行1000条查询的大量更新查询的最佳方法

时间:2018-11-09 00:06:31

标签: sql sql-server tsql

我有一个带有50,000个更新查询的SQL Server文件,如下所示:

UPDATE [dbo].[TABLE1] SET [COLUMN2] = 'abc123' WHERE [Id] = 100;
UPDATE [dbo].[TABLE1] SET [COLUMN2] = 'def456' WHERE [Id] = 101;
UPDATE [dbo].[TABLE1] SET [COLUMN2] = 'ghi789' WHERE [Id] = 205;
UPDATE [dbo].[TABLE1] SET [COLUMN2] = 'jkl012' WHERE [Id] = 216;
UPDATE [dbo].[TABLE1] SET [COLUMN2] = 'mno345' WHERE [Id] = 350;

我不想运行此文件并一次执行所有50,000个查询。 通过一次执行1000个查询来执行此操作的最佳方法是什么,当这些查询完成后,继续执行下一个1000个查询,直到全部执行完毕? 另外,如果出现错误,我该如何回滚?

3 个答案:

答案 0 :(得分:3)

您应该使用这些值创建一个临时表。然后,您可以将其用于public class MovieLink { public MovieLink() { } public int Hash { get; set; } public string VideoLink { get; set; } public string ImageLink { get; set; } } List<MovieLink> MoviesLinks = new List<MovieLink>(); private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e) { if (webBrowser1.ReadyState != WebBrowserReadyState.Complete) return; var DocumentFrames = webBrowser1.Document.Window.Frames; foreach (HtmlWindow Frame in DocumentFrames) { try { var VideoElement = Frame.Document.Body .GetElementsByTagName("VIDEO").Cast<HtmlElement>().FirstOrDefault(); if (VideoElement != null) { string VideoLink = VideoElement.Children[0].GetAttribute("src"); int Hash = VideoLink.GetHashCode(); if (MoviesLinks.Any(m => m.Hash == Hash)) { // Done parsing this URL: remove handler or whatever // else is planned to move to the next site/page return; } string SourceImage = VideoElement.GetAttribute("poster"); MoviesLinks.Add(new MovieLink() { Hash = Hash, VideoLink = VideoLink, ImageLink = SourceImage }); } } catch (UnauthorizedAccessException) { } catch (InvalidOperationException) { } } } 。如果没有,您可以在查询中创建派生表:

update

答案 1 :(得分:2)

使用CASE WHEN语句

UPDATE [dbo].[TABLE1] 
SET    [COLUMN2] = CASE [Id]
                   WHEN 100 THEN 'abc123'
                   WHEN 101 THEN 'def456'
                   WHEN 205 THEN 'ghi789'
                   WHEN 216 THEN 'jkl012'
                   WHEN 350 THEN 'mno345'
                   END
WHERE  [Id] IN ( 100 , 101, 205, 216, 350 )

答案 2 :(得分:1)

您可以尝试使用UNION ALL创建结果集并为其写入行号,然后执行UPDATE .... JOIN

  

通过一次执行1000个查询来做到这一点的最佳方法是什么?

如果要更新1000个批次的日期,可以尝试使用带变量的循环(while)进行控制。

DECLARE @fromNum int = 1;
DECLARE @toNum int = 1000;
DECLARE @totalRowNum int;

;with cte as (
    SELECT 'abc123' COLUMN2,100 ID
    UNION ALL
    SELECT 'def456'        ,101 
    UNION ALL              
    SELECT 'ghi789'        ,205 
    UNION ALL              
    SELECT 'jkl012'        ,216 
    UNION ALL              
    SELECT 'mno345'        ,350 
), cteRowNum as(
    SELECT *,ROW_NUMBER() OVER(ORDER BY (SELECT ID)) rn
    FROM cte
)
SELECT *
INTO #Temp
FROM cteRowNum

SELECT @totalRowNum = MAX(rn) 
FROM #Temp

While(@toNum < @totalRowNum)
BEGIN
    BEGIN TRY
        BEGIN TRAN
        update t1
        set t1.COLUMN2 = t2.COLUMN2
        from TABLE1 t1 join #Temp t2 on t1.id = t2.ID 
        where t2.rn between @fromNum and @toNum
        COMMIT TRAN
    END TRY
    BEGIN CATCH
     ROLLBACK TRAN
     SELECT ERROR_NUMBER() AS ErrorNumber,ERROR_SEVERITY() AS ErrorSeverity,ERROR_STATE() AS ErrorState,ERROR_PROCEDURE() AS ErrorProcedure,ERROR_LINE() AS ErrorLine,ERROR_MESSAGE() AS ErrorMessage
    END CATCH

    SET @fromNum = @toNum
    SET @toNum = @toNum + 1000
END

IF OBJECT_ID('dbo.Scores', 'U') IS NOT NULL 
DROP TABLE #Temp