¿Cómo usar las transacciones con SQL Server DDL?


20

Tengo una tabla de inicio de sesión en la que todas las inserciones se realizan mediante un único procedimiento almacenado.

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

Actualmente hay alrededor de 45500000 filas en esa tabla y quiero dirigir el registro a una tabla diferente.

Mi idea es usar el siguiente 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;

¿Funciona y tiene un impacto mínimo en otros procedimientos que llaman a LogInsert?


2
No necesita la sp_recompile. El caché de procedimientos para cualquier objeto que use el objeto dbo.LogTable expirará automáticamente cuando cambie el nombre del objeto.
mrdenny

Respuestas:


24

Sí. Las transacciones se aplican a DDL y abarcan lotes.

Haría algo como esto. Tenga en cuenta el uso de AISLAMIENTO SERIALIZABLE para garantizar un aislamiento completo y XACT_ABORT, lo que forzará una reversión ante cualquier error.

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
¿Puede vincular a una referencia que muestre que las transacciones de SQL Server se aplican a DDL y abarcan lotes? Las páginas obvias de BOL no mencionan esto.
Nick Chammas

2
@ Nick: nunca he buscado uno. Yo que funciona como lo uso todo el tiempo. Depende de usted creerme o refutarme o probarlo usted mismo. Por supuesto, las transacciones son por conexión, como varias declaraciones establecidas que uso. Una conexión consta de múltiples lotes. ¿Qué más necesitas?
gbn

Te creo, pero esperaba alguna documentación "oficial" que enumerara todas las acciones vinculadas a transacciones explícitas y cuáles no. Por ejemplo, las variables de la tabla no se ven afectadas por las reversiones de transacciones (lo que, para mí, viola el Principio de Menos Sorpresa ).
Nick Chammas

2
Casi el mismo código, pero la transacción no funciona: stackoverflow.com/questions/47868213/…
aleyush
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.