Sql-Server-2008

如何在 SQL Server DDL 中使用事務?

  • August 17, 2016

我有一個登錄表,其中所有插入都由一個儲存過程完成。

CREATE TABLE dbo.LogTable(
   LogRefnr int IDENTITY(1, 1) NOT NULL,
   LogQuery varchar(255) NOT NULL,
   LogTime datetime NOT NULL,
   logQueryDuration int NULL,
   LogSessionID int NULL,
CONSTRAINT PK_Log PRIMARY KEY CLUSTERED  (LogRefnr)
)
go


Create procedure DBO.LogInsert ( @Query varchar(255), @time datetime, @duration int, @SessinID int) as
begin
   Insert into LogTable ( LogRefnr, LogQuery, logQueryDuration, LogSessionID)
   Values  (@Query, @time, @duration, @SessinID);
end;
GO

目前該表中有大約 45500000 行,我想將日誌記錄定向到另一個表。

我的想法是使用以下腳本

begin Transaction

exec sp_rename LogTable, LogTableOld;

CREATE TABLE dbo.LogTable(
   LogRefnr int IDENTITY(46000000, 1) NOT NULL,            -- greater than select max(LogRefnr) from LogTableOld
   LogQuery varchar(255) NOT NULL,
   LogTime datetime NOT NULL,
   logQueryDuration int NULL,
   LogSessionID int NULL,
CONSTRAINT PK_Log2 PRIMARY KEY CLUSTERED  (LogRefnr);
)
go

sp_recompile LogTable;
go

Commit;

這是否有效並且對呼叫 LogInsert 的其他過程的影響最小?

是的。事務適用於 DDL 和跨批次。

我會做這樣的事情。請注意使用 SERIALIZABLE ISOLATION 來確保完全隔離和 XACT_ABORT 這將強制回滾任何錯誤。

SET XACT_ABORT ON
GO
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE
GO
begin Transaction
GO
exec sp_rename LogTable, LogTableOld;
GO
CREATE TABLE dbo.LogTable(
   LogRefnr int IDENTITY(46000000, 1) NOT NULL,            -- greater than select max(LogRefnr) from LogTableOld
   LogQuery varchar(255) NOT NULL,
   LogTime datetime NOT NULL,
   logQueryDuration int NULL,
   LogSessionID int NULL,
CONSTRAINT PK_Log2 PRIMARY KEY CLUSTERED  (LogRefnr);
)
go
EXEC sp_recompile LogTable;
go

Commit;

引用自:https://dba.stackexchange.com/questions/4356