วิธีใช้ธุรกรรมกับ SQL Server DDL


20

ฉันมีตารางเข้าสู่ระบบที่แทรกทั้งหมดจะทำโดยขั้นตอนการจัดเก็บเดียว

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

ขณะนี้มีแถวประมาณ 45,500,000 แถวในตารางนั้นและฉันต้องการบันทึกโดยตรงไปยังตารางอื่น

ความคิดของฉันคือการใช้สคริปต์ต่อไปนี้

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


2
คุณไม่ต้องการ sp_recompile โพรซีเดอร์แคชสำหรับวัตถุใด ๆ ที่ใช้วัตถุ dbo.LogTable จะหมดอายุโดยอัตโนมัติเมื่อคุณเปลี่ยนชื่อวัตถุ
mrdenny

คำตอบ:


24

ใช่. ธุรกรรมที่ใช้กับ 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;

1
คุณสามารถลิงค์ไปยังการอ้างอิงที่แสดงธุรกรรม SQL Server ที่ใช้กับ DDL และขยายแบทช์ได้หรือไม่? ชัดเจน หน้า BOLไม่ได้กล่าวถึงนี้
Nick Chammas

2
@Nick: ฉันไม่เคยมองหาใคร ฉันรู้ว่ามันใช้งานได้ดีตลอดเวลา ขึ้นอยู่กับคุณที่จะเชื่อฉันหรือหักล้างฉันหรือลองด้วยตัวคุณเอง แน่นอนว่าการทำธุรกรรมมีการเชื่อมต่อเหมือนชุดคำสั่งต่าง ๆ ที่ฉันใช้ การเชื่อมต่อประกอบด้วยหลายแบตช์ คุณต้องการอะไรอีก
gbn

ฉันเชื่อว่าคุณ แต่ฉันหวังว่าจะมีเอกสาร "ทางการ" ที่ระบุการกระทำทั้งหมดที่ผูกพันกับธุรกรรมที่ชัดเจน ตัวอย่างเช่นตัวแปรตารางไม่ได้รับผลกระทบจากการย้อนกลับการทำธุรกรรม (ซึ่งสำหรับฉันนั้นเป็นการละเมิดหลักการของความประหลาดใจอย่างน้อย )
Nick Chammas

2
เกือบรหัสเดียวกัน แต่การทำธุรกรรมไม่ทำงาน: stackoverflow.com/questions/47868213//
aleyush
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.