คำถามของคุณเป็นหลัก:
เหตุใดฉันจึงไม่สามารถทำสิ่งที่มีความเสี่ยงที่ฉันไม่ควรได้รับอนุญาตให้ทำตั้งแต่แรก?
คำตอบสำหรับคำถามนั้นส่วนใหญ่ไม่เกี่ยวข้อง (แม้ว่าคุณจะเห็นความคิดเห็นของ Microsoft บางอย่างในรายการเชื่อมต่อที่ขอใช้ฟังก์ชันนี้: # 294193และ# 252226) เพื่อความสมบูรณ์บทสรุปของฉันคือ: ความสามารถในการลบคุณสมบัติข้อมูลเฉพาะตัวเป็นผลข้างเคียงที่ไม่ได้ตั้งใจของการมีความสามารถในการยุ่งกับตารางระบบในตอนแรก นี่ไม่ได้มีวัตถุประสงค์เพื่อนำไปใช้ในหลาย ๆ วิธีที่มันเป็นบ่อยครั้งที่มีผลกระทบที่เลวร้ายมากและทำให้มันถูกลบออก มันเป็นแฮ็คตารางระบบที่ไม่มีเอกสารสนับสนุน ความสามารถในการเปลี่ยนแปลงข้อมูลในตารางระบบไม่ได้ถูกลบออกเนื่องจาก Microsoft ไม่ต้องการให้คุณแฮ็ควิธีการออกจากคอลัมน์ที่เป็นคอลัมน์ข้อมูลประจำตัว แต่มันถูกลบออกเพราะการเล่นกับตารางระบบมีความเสี่ยงอย่างยิ่ง การลบคุณสมบัติ IDENTITY นั้นไม่ได้เป็นการลบคุณลักษณะเฉพาะเป้าหมายและฉันจะไม่เชื่อมั่นในวิธีการนี้แม้จะย้อนกลับไปในสมัยโบราณเมื่อเป็นไปได้
ที่กล่าวมาเราจะตอบคำถามนี้แทนได้อย่างไร
ฉันจะลบคุณสมบัติตัวตนของคอลัมน์ด้วยเวลาที่น้อยที่สุดหรือไม่มีการหยุดทำงานได้อย่างไร
คุณสามารถทำโดยใช้ALTER TABLE ... SWITCH
เทคนิคที่ผมได้เรียนรู้บางอย่างที่ฉันเป็นครั้งแรกจากของเราเองพอลไวท์ในการแก้ไขปัญหาในการเชื่อมต่อ # ตัวอย่างด่วนให้ตารางง่าย ๆ นี้:
CREATE TABLE dbo.Original
(
ID INT IDENTITY(1,1) PRIMARY KEY,
name SYSNAME
);
GO
INSERT dbo.Original(name) VALUES(N'foo'),(N'bar');
GO
SELECT * FROM dbo.Original;
GO
ผล:
ID name
-- ----
1 foo
2 bar
ตอนนี้เรามาสร้างตารางเงาและสลับไปที่มันจากนั้นวางตารางเก่าเปลี่ยนชื่อใหม่จากนั้นกลับสู่กิจกรรมปกติ:
CREATE TABLE dbo.New
(
ID INT PRIMARY KEY,
name SYSNAME
);
GO
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
BEGIN TRANSACTION;
ALTER TABLE dbo.Original SWITCH TO dbo.New;
DROP TABLE dbo.Original;
EXEC sys.sp_rename N'dbo.New', N'Original', 'OBJECT';
COMMIT TRANSACTION;
GO
INSERT dbo.Original(ID,name) VALUES(3,N'splunge');
UPDATE dbo.Original SET ID = 6 WHERE ID = 1;
GO
SELECT * FROM dbo.Original;
GO
ผล:
ID name
-- -------
2 bar
3 splunge
6 foo
ตอนนี้ทำความสะอาด:
DROP TABLE dbo.Original;
นี่เป็นการดำเนินการเมตาดาต้าเท่านั้นโดยไม่มีการเคลื่อนย้ายข้อมูลและจะบล็อกผู้ใช้รายอื่นในขณะที่กำลังอัปเดตเมตาดาต้าเท่านั้น แต่เป็นที่ยอมรับว่าเป็นตัวอย่างที่ง่ายมาก หากคุณมีคีย์ต่างประเทศหรือใช้คุณสมบัติอื่น ๆ เช่นการจำลองการเปลี่ยนแปลงการเก็บข้อมูลเปลี่ยนการติดตาม ฯลฯ คุณอาจต้องปิดการใช้งานหรือลบบางส่วนก่อนทำการเปลี่ยนแปลงนี้ (ฉันยังไม่ได้ทดสอบชุดค่าผสมทั้งหมด) สำหรับคีย์ต่างประเทศโดยเฉพาะให้ดูเคล็ดลับนี้ซึ่งแสดงวิธีการสร้างสคริปต์เพื่อวางและสร้างข้อ จำกัด คีย์ต่างประเทศทั้งหมด (หรือเลือก) ใหม่
นอกจากนี้คุณจะต้องอัปเดตรหัสแอปพลิเคชันของคุณเพื่อไม่ให้ SQL Server เติมคอลัมน์นี้และตรวจสอบคำสั่งแทรกหรือเลือกใด ๆ ที่อาจขึ้นอยู่กับลำดับของคอลัมน์หรือคอลัมน์ที่พวกเขาต้องการระบุ โดยทั่วไปฉันจะ grep ฐานรหัสทั้งหมดของคุณสำหรับการเอ่ยถึงตารางนี้
โปรดดูสคริปต์นี้จาก Itzik Ben-Gan (ที่มา: บทความโบราณนี้ ) สำหรับวิธีการอื่นในการจัดการกับสิ่งนี้ แต่มีการเคลื่อนย้ายข้อมูลที่เกี่ยวข้องที่นี่ดังนั้นจึงไม่ส่งผ่านข้อกำหนด "ไม่มีหรือหยุดทำงานน้อยที่สุด"