1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130
| IF OBJECT_ID('WaterLevelGaugeHistory_New', 'U') IS NOT NULL DROP TABLE WaterLevelGaugeHistory_New;
CREATE TABLE WaterLevelGaugeHistory_New ( ID int IDENTITY(1,1) NOT NULL, stt_no nvarchar(50) NULL, dev_id nvarchar(50) NULL, measure_time datetime NULL, upload_time nvarchar(50) NULL, val decimal(10, 3) NULL, Voltage decimal(10, 3) NULL, Power nvarchar(10) NULL, DataLogPeriod nvarchar(50) NULL, Status int NULL, flood_season int NULL, cstatus nvarchar(2) NULL, nodata bit NULL, StationClass int NULL, CONSTRAINT PK_WaterLevelGaugeHistory_New PRIMARY KEY CLUSTERED (ID) );
CREATE TABLE #ProcessedRows ( BatchID INT IDENTITY(1,1) PRIMARY KEY, LastProcessedID INT, RowsProcessed INT, ProcessedTime DATETIME DEFAULT GETDATE() );
DECLARE @BatchSize INT = 50000; DECLARE @LastProcessedID INT = 0; DECLARE @RowsAffected INT; DECLARE @TotalRowsProcessed INT = 0; DECLARE @TotalRowsOld INT; DECLARE @TotalRowsNew INT; DECLARE @StartTime DATETIME = GETDATE();
SELECT @TotalRowsOld = COUNT(*) FROM WaterLevelGaugeHistory;
WHILE @LastProcessedID IS NOT NULL BEGIN BEGIN TRY BEGIN TRANSACTION; INSERT INTO WaterLevelGaugeHistory_New ( stt_no, dev_id, measure_time, upload_time, val, Voltage, Power, DataLogPeriod, Status, flood_season, cstatus, nodata, StationClass ) SELECT TOP (@BatchSize) stt_no, dev_id, measure_time, upload_time, val, Voltage, Power, DataLogPeriod, Status, 0 AS flood_season, cstatus, nodata, StationClass FROM WaterLevelGaugeHistory WHERE ID > @LastProcessedID ORDER BY ID;
SET @RowsAffected = @@ROWCOUNT; SET @TotalRowsProcessed = @TotalRowsProcessed + @RowsAffected;
IF @RowsAffected > 0 BEGIN SELECT @LastProcessedID = MAX(ID) FROM WaterLevelGaugeHistory WHERE ID > @LastProcessedID AND ID <= @LastProcessedID + @BatchSize; INSERT INTO #ProcessedRows (LastProcessedID, RowsProcessed) VALUES (@LastProcessedID, @RowsAffected); END ELSE BEGIN SET @LastProcessedID = NULL; END
COMMIT TRANSACTION;
PRINT 'Processed ' + CAST(@RowsAffected AS NVARCHAR(10)) + ' rows. Last ID: ' + ISNULL(CAST(@LastProcessedID AS NVARCHAR(20)), 'NULL') + '. Total Processed: ' + CAST(@TotalRowsProcessed AS NVARCHAR(20)) + '. Elapsed Time: ' + CAST(DATEDIFF(SECOND, @StartTime, GETDATE()) AS NVARCHAR(10)) + ' seconds';
WAITFOR DELAY '00:00:00.1'; END TRY BEGIN CATCH IF @@TRANCOUNT > 0 ROLLBACK TRANSACTION;
PRINT 'Error occurred: ' + ERROR_MESSAGE(); PRINT 'Error Line: ' + CAST(ERROR_LINE() AS NVARCHAR(10)); PRINT 'Last processed ID: ' + ISNULL(CAST(@LastProcessedID AS NVARCHAR(20)), 'NULL');
SET @LastProcessedID = ISNULL(@LastProcessedID + 1, 0); END CATCH END
SELECT @TotalRowsNew = COUNT(*) FROM WaterLevelGaugeHistory_New;
IF @TotalRowsOld = @TotalRowsNew BEGIN EXEC sp_rename 'WaterLevelGaugeHistory', 'WaterLevelGaugeHistory_Old'; EXEC sp_rename 'WaterLevelGaugeHistory_New', 'WaterLevelGaugeHistory'; PRINT '表格更新成功完成。'; PRINT '總行數: ' + CAST(@TotalRowsNew AS NVARCHAR(20)); END ELSE BEGIN PRINT '數據驗證失敗,請檢查並重試。'; PRINT '原表行數: ' + CAST(@TotalRowsOld AS NVARCHAR(20)); PRINT '新表行數: ' + CAST(@TotalRowsNew AS NVARCHAR(20)); PRINT '處理的行數: ' + CAST(@TotalRowsProcessed AS NVARCHAR(20)); SELECT TOP 100 * FROM #ProcessedRows ORDER BY BatchID DESC; END
DROP TABLE #ProcessedRows;
|