Come utilizzare le transazioni con DDL di SQL Server?


20

Ho una tabella di login in cui tutti gli inserimenti vengono eseguiti da un'unica procedura memorizzata.

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

Attualmente ci sono circa 45500000 righe in quella tabella e voglio indirizzare la registrazione su una tabella diversa.

La mia idea è di usare il seguente script

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;

Funziona e ha un impatto minimo su altre procedure che chiamano LogInsert?


2
Non hai bisogno di sp_recompile. La cache delle procedure per tutti gli oggetti che utilizzano l'oggetto dbo.LogTable scadrà automaticamente quando si rinomina l'oggetto.
mrdenny,

Risposte:


24

Sì. Le transazioni si applicano ai batch DDL e span.

Farei qualcosa del genere. Notare l'uso di ISOLATION SERIALIZZABILE per garantire il completo isolamento e XACT_ABORT che forzerà un rollback su qualsiasi errore.

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;

1
È possibile collegarsi a un riferimento che mostra che le transazioni di SQL Server si applicano ai batch DDL e span? Le ovvie pagine BOL non menzionano questo.
Nick Chammas,

2
@ Nick: non ne ho mai cercato uno. Io so che funziona come io lo uso per tutto il tempo. Spetta a te credermi o confondermi o provarlo tu stesso. Ovviamente, le transazioni sono per connessione come le varie dichiarazioni impostate che uso. Una connessione è composta da più batch. Cosa ti serve ancora?
gbn

Ti credo, ma speravo in una documentazione "ufficiale" che elenca tutte le azioni legate a transazioni esplicite e quali no. Ad esempio, le variabili della tabella non sono influenzate dai rollback delle transazioni (che, a mio avviso, violano il Principio della minima sorpresa ).
Nick Chammas,

2
Quasi lo stesso codice, ma la transazione non funziona: stackoverflow.com/questions/47868213/...
aleyush
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.