Bagaimana cara menggunakan transaksi dengan SQL Server DDL?

20

Saya memiliki tabel login tempat semua sisipan dilakukan oleh satu prosedur tersimpan.

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

Saat ini ada sekitar 45500000 baris dalam tabel itu dan saya ingin langsung masuk ke tabel lain.

Ide saya adalah menggunakan skrip berikut

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;

Apakah ini berfungsi dan memiliki dampak minimal terhadap prosedur lain yang memanggil LogInsert?

bernd_k
sumber
2
Anda tidak memerlukan sp_recompile. Tembolok prosedur untuk objek apa pun yang menggunakan objek dbo.LogTable akan kedaluwarsa secara otomatis saat Anda mengganti nama objek.
mrdenny

Jawaban:

24

Iya nih. Transaksi berlaku untuk DDL dan span batch.

Saya akan melakukan sesuatu seperti ini. Perhatikan penggunaan ISOLASI SERIALISASI untuk memastikan isolasi penuh dan XACT_ABORT yang akan memaksa rollback pada kesalahan apa pun.

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;
gbn
sumber
1
Bisakah Anda menautkan ke referensi yang menunjukkan transaksi SQL Server berlaku untuk DDL dan span batch? The jelas halaman BOL tidak menyebutkan ini.
Nick Chammas
2
@Nick: Saya belum pernah mencari satu. Saya tahu ini berfungsi saat saya menggunakannya setiap saat. Terserah Anda untuk mempercayai saya atau menyangkal saya atau mencobanya sendiri. Tentu saja, transaksi adalah per koneksi seperti berbagai set pernyataan yang saya gunakan. Koneksi terdiri dari beberapa batch. Apa lagi yang kamu butuhkan?
gbn
Saya percaya Anda, tetapi saya berharap untuk dokumentasi "resmi" yang menyebutkan semua tindakan yang terikat pada transaksi eksplisit dan mana yang tidak. Misalnya, variabel tabel tidak terpengaruh oleh kemunduran transaksi (yang, bagi saya, melanggar Prinsip Terkejut ).
Nick Chammas
2
Hampir kode yang sama, tetapi transaksi tidak berfungsi: stackoverflow.com/questions/47868213/…
aleyush