Comment utiliser les transactions avec SQL Server DDL?


20

J'ai une table de connexion dans laquelle toutes les insertions sont effectuées par une seule procédure stockée.

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

Actuellement, il y a environ 45 500 000 lignes dans cette table et je souhaite diriger la journalisation vers une autre table.

Mon idée est d'utiliser le script suivant

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;

Est-ce que cela fonctionne et a un impact minimal sur les autres procédures appelant LogInsert?


2
Vous n'avez pas besoin de sp_recompile. Le cache de procédure pour tous les objets qui utilisent l'objet dbo.LogTable expirera automatiquement lorsque vous renommez l'objet.
mrdenny

Réponses:


24

Oui. Les transactions s'appliquent aux lots DDL et span.

Je ferais quelque chose comme ça. Notez l'utilisation de SERIALIZABLE ISOLATION pour assurer une isolation complète et XACT_ABORT qui forcera un retour en arrière sur toute erreur.

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
Pouvez-vous créer un lien vers une référence indiquant que les transactions SQL Server s'appliquent aux lots DDL et span? Les pages BOL évidentes ne le mentionnent pas.
Nick Chammas

2
@ Nick: Je n'en ai jamais cherché. Je sais que cela fonctionne car je l'utilise tout le temps. A vous de me croire ou de me réfuter ou de l'essayer par vous-même. Bien sûr, les transactions se font par connexion, comme les différentes instructions que j'utilise. Une connexion se compose de plusieurs lots. Qu'as-tu besoin de plus?
gbn

Je vous crois, mais j'espérais une documentation "officielle" qui énumère toutes les actions liées à des transactions explicites et celles qui ne le sont pas. Par exemple, les variables de table ne sont pas affectées par les annulations de transactions (ce qui, pour moi, viole le principe de la moindre surprise ).
Nick Chammas

2
Presque le même code, mais la transaction ne fonctionne pas: stackoverflow.com/questions/47868213/…
aleyush
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.