คุณจะตัดทอนตารางทั้งหมดในฐานข้อมูลโดยใช้ TSQL ได้อย่างไร


204

ฉันมีสภาพแวดล้อมการทดสอบสำหรับฐานข้อมูลที่ฉันต้องการโหลดด้วยข้อมูลใหม่ที่จุดเริ่มต้นของรอบการทดสอบ ฉันไม่ได้สนใจในการสร้างฐานข้อมูลทั้งหมดใหม่เพียงแค่ "ตั้งค่าใหม่" ข้อมูล

เป็นวิธีที่ดีที่สุดในการลบข้อมูลทั้งหมดจากตารางทั้งหมดโดยใช้ TSQL อะไร มีขั้นตอนการจัดเก็บมุมมองและอื่น ๆ ของระบบที่สามารถใช้ได้หรือไม่? ฉันไม่ต้องการที่จะสร้างและรักษางบงบที่ถูกตัดทอนสำหรับแต่ละตารางด้วยตนเองฉันต้องการให้มันเป็นแบบไดนามิก

คำตอบ:


188

สำหรับ SQL 2005

EXEC sp_MSForEachTable 'TRUNCATE TABLE ?'

เชื่อมโยงเพิ่มเติมกับคู่สำหรับปี 2000และ2005/2008 ..


62
คุณไม่สามารถตัดทอนตารางที่มีคีย์ต่างประเทศได้ดังนั้นจะใช้งานได้เฉพาะในกรณีที่ไม่มีข้อ จำกัด ของรหัสต่างประเทศระหว่างตาราง (หรือถูกปิดใช้งาน)
marcj

1
agreed..i คิดว่านับตั้งแต่ที่เขาถามมาโดยเฉพาะสำหรับการตัดทอนตารางเขามีอยู่แล้วแก้ปัญหากับปุ่มต่างประเทศ ..
Gulzar ซิม

@ gulzar- การเรียงลำดับของ - ฉันโพสต์คำถามแยกต่างหากเกี่ยวกับวิธีการจัดการ FKs แต่คำตอบของคุณยืนอยู่บนข้อดีของตัวเอง
Ray

11
@ Sam: ไม่มันไม่ได้! ข้อมูลในตารางไม่เกี่ยวข้อง ตราบใดที่ยังมีข้อ จำกัด ของคีย์ต่างประเทศที่อ้างอิงตาราง (แม้จะปิดใช้งานอยู่) คุณจะไม่สามารถตัดทอน
TToni

3
'EXEC sp_MSForEachTable' DROP Table? ' ทำงานได้ดีเช่นกัน :) (สร้างความสุขให้กับตารางทั้งหมดจากฐานข้อมูล)
kuncevic.dev

418

เมื่อจัดการกับการลบข้อมูลจากตารางที่มีความสัมพันธ์กับคีย์ต่างประเทศ - ซึ่งเป็นกรณีของฐานข้อมูลที่ออกแบบมาอย่างถูกต้อง - เราสามารถปิดการใช้งานข้อ จำกัด ทั้งหมดลบข้อมูลทั้งหมดแล้วเปิดใช้งานข้อ จำกัด อีกครั้ง

-- disable all constraints
EXEC sp_MSForEachTable "ALTER TABLE ? NOCHECK CONSTRAINT all"

-- delete data in all tables
EXEC sp_MSForEachTable "DELETE FROM ?"

-- enable all constraints
exec sp_MSForEachTable "ALTER TABLE ? WITH CHECK CHECK CONSTRAINT all"

ข้อมูลเพิ่มเติมเกี่ยวกับการปิดใช้งานข้อ จำกัด และทริกเกอร์ที่นี่

หากบางตารางมีคอลัมน์ข้อมูลประจำตัวเราอาจต้องการให้ทำการบันทึกใหม่

EXEC sp_MSForEachTable "DBCC CHECKIDENT ( '?', RESEED, 0)"

โปรดทราบว่าพฤติกรรมของ RESEED นั้นแตกต่างกันไปตามตารางใหม่และสิ่งที่มีข้อมูลบางส่วนได้แทรกไว้ก่อนหน้านี้จากBOL :

DBCC CHECKIDENT ('table_name', RESEED, newReseedValue)

ค่าเอกลักษณ์ปัจจุบันถูกตั้งค่าเป็น newReseedValue หากไม่มีการแทรกแถวลงในตารางตั้งแต่สร้างขึ้นแถวแรกที่แทรกหลังจากดำเนินการ DBCC CHECKIDENT จะใช้ newReseedValue เป็นข้อมูลประจำตัว มิฉะนั้นการแทรกแถวถัดไปจะใช้ newReseedValue + 1 หากค่าของ newReseedValue น้อยกว่าค่าสูงสุดในคอลัมน์ข้อมูลประจำตัวข้อความแสดงข้อผิดพลาด 2627 จะถูกสร้างขึ้นในการอ้างอิงตาราง

ขอบคุณRobert ที่ชี้ให้เห็นข้อเท็จจริงที่ว่าการปิดใช้งานข้อ จำกัด ไม่อนุญาตให้ใช้การตัดทอนข้อ จำกัด นี้จะต้องถูกลดลงจากนั้นจึงสร้างใหม่


34
การปิดใช้งานข้อ จำกัด จะไม่อนุญาตให้มีการตัดทอนตารางที่อ้างถึงโดยข้อ จำกัด ของ FOREIGN KEY ข้อ จำกัด FK จะต้องลดลง โปรดตอบกลับหากฉันผิดเกี่ยวกับเรื่องนี้ แต่ฉันไม่พบวิธีที่จะหลีกเลี่ยง
Robert Claypool

1
คำหลักที่พิมพ์ผิด "ตาราง" ไม่ควรอยู่ในคำสั่งนี้ EXEC sp_MSForEachTable "ลบออกจากตารางหรือไม่" รุ่นที่ถูกต้องควรเป็น: EXEC sp_MSForEachTable "DELETE FROM?"
Raghav

4
หากคุณใช้ 2008 หรือใหม่กว่า SSMS คุณอาจต้องการเพิ่มSET ROWCOUNT 0ที่จุดเริ่มต้นของสคริปต์เนื่องจากค่าเริ่มต้นคือการ จำกัด การกระทำไว้ที่ 500 แถว! คุณจะได้รับข้อผิดพลาดที่น่าผิดหวังอย่างที่ฉันทำเพราะไม่ใช่ว่าข้อมูลทั้งหมดจะถูกลบจริง ๆ
Sean Hanley

1
มันใช้งานได้ดีมาก ในกรณีของฉันฉันต้องเพิ่ม EXEC sp_msforeachtable "ALTER TABLE? ปิดการใช้งาน TRIGGER all" และ EXEC sp_msforeachtable "ALTER TABLE เปิดใช้งาน TRIGGER ทั้งหมด" ก่อนและหลังคำสั่งลบ
RobC

2
คำตอบที่ฉันชอบ แต่ทำไมคุณ (ทุกคนถึงกับวิจารณ์) ใส่สตริง SQL ตามตัวอักษรในเครื่องหมายคำพูดคู่
bitoolean

57

นี่คือพ่อของฐานข้อมูลเช็ดสคริปต์ มันจะล้างตารางทั้งหมดและดำเนินการต่ออย่างถูกต้อง:

SET QUOTED_IDENTIFIER ON;
EXEC sp_MSforeachtable 'SET QUOTED_IDENTIFIER ON; ALTER TABLE ? NOCHECK CONSTRAINT ALL'  
EXEC sp_MSforeachtable 'SET QUOTED_IDENTIFIER ON; ALTER TABLE ? DISABLE TRIGGER ALL'  
EXEC sp_MSforeachtable 'SET QUOTED_IDENTIFIER ON; DELETE FROM ?'  
EXEC sp_MSforeachtable 'SET QUOTED_IDENTIFIER ON; ALTER TABLE ? CHECK CONSTRAINT ALL'  
EXEC sp_MSforeachtable 'SET QUOTED_IDENTIFIER ON; ALTER TABLE ? ENABLE TRIGGER ALL' 
EXEC sp_MSforeachtable 'SET QUOTED_IDENTIFIER ON';

IF NOT EXISTS (
    SELECT
        *
    FROM
        SYS.IDENTITY_COLUMNS
        JOIN SYS.TABLES ON SYS.IDENTITY_COLUMNS.Object_ID = SYS.TABLES.Object_ID
    WHERE
        SYS.TABLES.Object_ID = OBJECT_ID('?') AND SYS.IDENTITY_COLUMNS.Last_Value IS NULL
)
AND OBJECTPROPERTY( OBJECT_ID('?'), 'TableHasIdentity' ) = 1

    DBCC CHECKIDENT ('?', RESEED, 0) WITH NO_INFOMSGS;

สนุก แต่ระวัง!


2
น่าเสียดายที่คำสั่งข้างต้นล้มเหลวหากคุณคำนวณคอลัมน์เนื่องจาก sp_MSforeachtable มีSET QUOTED_IDENTITY OFFอยู่ในเนื้อความ ( ลิงก์ ) UPDATE: การแก้ไขคือการเพิ่ม "SET QUOTED_IDENTIFIERS ใน"; ถึงจุดเริ่มต้นของแต่ละคำสั่งที่ทำให้เกิดข้อผิดพลาดนี้ (ดังที่กล่าวไว้ที่นี่ )
Marchy

1
ดูเหมือนว่านี่จะไม่ส่งต่อตัวตนของฉัน
totooooo

48

วิธีที่ง่ายที่สุดในการทำเช่นนี้คือ

  1. เปิดสตูดิโอจัดการ SQL
  2. นำทางไปยังฐานข้อมูลของคุณ
  3. คลิกขวาและเลือก Tasks-> สร้างสคริปต์ (รูปที่ 1)
  4. ในหน้าจอ "เลือกวัตถุ" ให้เลือกตัวเลือก "เลือกวัตถุที่ต้องการ" แล้วเลือก "ตาราง" (รูปที่ 2)
  5. ในหน้าจอถัดไปเลือก "ขั้นสูง" จากนั้นเปลี่ยนตัวเลือก "Script DROP and CREATE" เป็น "Script DROP and CREATE" (รูปที่ 3)
  6. เลือกที่จะบันทึกสคริปต์ลงในหน้าต่างตัวแก้ไขใหม่หรือไฟล์และเรียกใช้ตามความจำเป็น

สิ่งนี้จะทำให้คุณมีสคริปต์ที่ปล่อยและสร้างตารางทั้งหมดของคุณใหม่โดยไม่จำเป็นต้องกังวลเกี่ยวกับการดีบักหรือว่าคุณรวมทุกอย่างแล้ว แม้ว่าสิ่งนี้จะมีประสิทธิภาพมากกว่าแค่การตัดทอนผลลัพธ์ก็เหมือนกัน โปรดทราบว่าคีย์หลักที่เพิ่มขึ้นอัตโนมัติของคุณจะเริ่มต้นที่ 0 ตรงข้ามกับตารางที่ถูกตัดทอนซึ่งจะจดจำค่าสุดท้ายที่กำหนดไว้ คุณยังสามารถเรียกใช้งานได้จากรหัสหากคุณไม่มีสิทธิ์เข้าถึงสตูดิโอการจัดการในสภาพแวดล้อม PreProd หรือการผลิตของคุณ

1

ป้อนคำอธิบายรูปภาพที่นี่

2

ป้อนคำอธิบายรูปภาพที่นี่

3

ป้อนคำอธิบายรูปภาพที่นี่


1
ข้อควรระวังถ้าคุณใช้สิ่งนี้กับฐานข้อมูลที่มี schema ที่ซับซ้อนมาก ฉันลองมันบนสำเนา dev ของฐานข้อมูลการผลิตของเราและมันทิ้งสคีมาเพื่อให้มีการใช้งานซ้ำทั้งหมด
Techrocket9

1
คุณต้องเขียนสคริปต์ทุกสิ่งที่คุณต้องการรักษา
Captain Kenpachi

13

การตัดทอนตารางทั้งหมดจะทำงานได้ก็ต่อเมื่อคุณไม่มีความสัมพันธ์กับต่างประเทศที่สำคัญระหว่างตารางของคุณเนื่องจาก SQL Server จะไม่อนุญาตให้คุณตัดทอนตารางด้วยรหัสต่างประเทศได้

อีกทางเลือกหนึ่งคือการกำหนดตารางด้วย foreign key และลบออกก่อนคุณสามารถตัดทอนตารางโดยไม่ต้องใช้ foreign key ภายหลัง

ดูhttp://www.sqlteam.com/forums/topic.asp?TOPIC_ID=65341และhttp://www.sqlteam.com/forums/topic.asp?TOPIC_ID=72957สำหรับรายละเอียดเพิ่มเติม


1
จุดดี. ไม่ได้คิดอย่างนั้น ฉันอาจปิดการใช้งานข้อ จำกัด ทั้งหมดก่อนแล้วจึงเปิดใช้งานอีกครั้งเมื่อข้อมูลถูกลบ
เรย์

7

ตัวเลือกอื่นที่ฉันต้องการใช้กับ MSSQL Server Deveploper หรือ Enterprise คือการสร้าง snapshot ของฐานข้อมูลทันทีหลังจากสร้าง schema ที่ว่างเปล่า ณ จุดนี้คุณสามารถกู้คืนฐานข้อมูลกลับไปเป็นสแน็ปช็อตต่อไปได้


น่าเสียดายที่คุณสูญเสียดัชนี FULLTEXT ทั้งหมดในแต่ละครั้ง
Chris KL

6

อย่าทำอย่างนี้! จริง ๆ ไม่ใช่ความคิดที่ดี

หากคุณรู้ว่าตารางใดที่คุณต้องการตัดให้สร้างกระบวนงานที่เก็บไว้ซึ่งตัดทอนตารางนั้น คุณสามารถแก้ไขคำสั่งเพื่อหลีกเลี่ยงปัญหาต่างประเทศที่สำคัญ

หากคุณต้องการตัดทอนพวกเขาทั้งหมด (เพื่อให้คุณสามารถโหลด BCP ได้) คุณจะสามารถปล่อยฐานข้อมูลได้อย่างรวดเร็วและสร้างฐานข้อมูลใหม่ตั้งแต่ต้นซึ่งจะมีประโยชน์เพิ่มเติมที่คุณรู้ว่าคุณอยู่ที่ไหน


วิธีอื่นที่ดีที่นี่
Sam

3
ปัญหาเกี่ยวกับวิธีการของคุณคือการวางตารางและฐานข้อมูลจะทำให้สูญเสียสิทธิ์ทั้งหมดที่ให้กับการเข้าสู่ระบบและสกีมาที่แตกต่างกัน สร้างใหม่ที่จะเจ็บปวดสำหรับฐานข้อมูลขนาดใหญ่ที่มีตารางจำนวนมาก
Punit Vora

4

หากคุณต้องการเก็บข้อมูลไว้ในตารางเฉพาะ (เช่นตารางการค้นหาแบบสแตติก) ในขณะที่ลบ / ตัดทอนข้อมูลในตารางอื่น ๆ ภายในฐานข้อมูลเดียวกันคุณต้องมีการวนรอบที่มีข้อยกเว้นอยู่ นี่คือสิ่งที่ฉันกำลังมองหาเมื่อฉันพบคำถามนี้

sp_MSForEachTable ดูเหมือนจะเป็นรถของฉัน (เช่นพฤติกรรมที่ไม่สอดคล้องกับคำสั่ง IF) ซึ่งอาจเป็นสาเหตุที่ไม่มีเอกสารของ MS

declare @LastObjectID int = 0
declare @TableName nvarchar(100) = ''
set @LastObjectID = (select top 1 [object_id] from sys.tables where [object_id] > @LastObjectID order by [object_id])
while(@LastObjectID is not null)
begin
    set @TableName = (select top 1 [name] from sys.tables where [object_id] = @LastObjectID)

    if(@TableName not in ('Profiles', 'ClientDetails', 'Addresses', 'AgentDetails', 'ChainCodes', 'VendorDetails'))
    begin
        exec('truncate table [' + @TableName + ']')
    end 

    set @LastObjectID = (select top 1 [object_id] from sys.tables where [object_id] > @LastObjectID order by [object_id])
end

4

ส่วนที่ยากที่สุดของการตัดทอนตารางทั้งหมดคือการลบและปรับเปลี่ยนข้อ จำกัด ของรหัสต่างประเทศอีกครั้ง

แบบสอบถามต่อไปนี้สร้างคำสั่งการวาง & สร้างสำหรับแต่ละข้อ จำกัด ที่เกี่ยวข้องกับแต่ละชื่อตารางใน @myTempTable หากคุณต้องการสร้างสิ่งเหล่านี้สำหรับตารางทั้งหมดคุณสามารถใช้เค้าร่างข้อมูลแบบง่าย ๆ เพื่อรวบรวมชื่อตารางเหล่านี้แทน

DECLARE @myTempTable TABLE (tableName varchar(200))
INSERT INTO @myTempTable(tableName) VALUES
('TABLE_ONE'),
('TABLE_TWO'),
('TABLE_THREE')


-- DROP FK Contraints
SELECT 'alter table '+quotename(schema_name(ob.schema_id))+
  '.'+quotename(object_name(ob.object_id))+ ' drop constraint ' + quotename(fk.name) 
  FROM sys.objects ob INNER JOIN sys.foreign_keys fk ON fk.parent_object_id = ob.object_id
  WHERE fk.referenced_object_id IN 
      (
         SELECT so.object_id 
         FROM sys.objects so JOIN sys.schemas sc
         ON so.schema_id = sc.schema_id
         WHERE so.name IN (SELECT * FROM @myTempTable)  AND sc.name=N'dbo'  AND type in (N'U'))


 -- CREATE FK Contraints
 SELECT 'ALTER TABLE [PIMSUser].[dbo].[' +cast(c.name as varchar(255)) + '] WITH NOCHECK ADD CONSTRAINT ['+ cast(f.name as varchar(255)) +'] FOREIGN KEY (['+ cast(fc.name as varchar(255)) +'])
      REFERENCES [PIMSUser].[dbo].['+ cast(p.name as varchar(255)) +'] (['+cast(rc.name as varchar(255))+'])'
FROM  sysobjects f
      INNER JOIN sys.sysobjects c ON f.parent_obj = c.id
      INNER JOIN sys.sysreferences r ON f.id = r.constid
      INNER JOIN sys.sysobjects p ON r.rkeyid = p.id
      INNER JOIN sys.syscolumns rc ON r.rkeyid = rc.id and r.rkey1 = rc.colid
      INNER JOIN sys.syscolumns fc ON r.fkeyid = fc.id and r.fkey1 = fc.colid
WHERE 
      f.type = 'F'
      AND
      cast(p.name as varchar(255)) IN (SELECT * FROM @myTempTable)

จากนั้นฉันก็แค่คัดลอกข้อความเพื่อเรียกใช้ - แต่ด้วยความพยายามเล็กน้อยคุณสามารถใช้เคอร์เซอร์เพื่อเรียกใช้มันแบบไดนามิก


3

มันง่ายกว่ามาก (และอาจจะเร็วกว่า) ในการเขียนสคริปต์ฐานข้อมูลของคุณจากนั้นเพียงแค่วางและสร้างจากสคริปต์


3

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


2

นี่เป็นวิธีหนึ่งในการทำ ... มีโอกาสอีก 10 คนที่ดีกว่า / มีประสิทธิภาพมากขึ้น แต่ดูเหมือนว่านี่จะทำไม่บ่อยนักดังนั้นที่นี่จะไป ...

รับรายการtablesจากจากsysobjectsนั้นวนรอบเคอร์เซอร์เรียกsp_execsql('truncate table ' + @table_name)หาแต่ละiterationรายการ


โพสต์เพิ่มด้วย sql ที่ทำแค่นี้ :) เนื่องจากนี่คือสิ่งที่ฉันกำลังมองหาเกินไป
Chris Smith

1

เรียกใช้ส่วนที่ถูกคอมเม้นต์ครั้งเดียวเติมข้อมูลตาราง _TruncateList ด้วยตารางที่คุณต้องการให้ตัดทอนแล้วเรียกใช้สคริปต์ที่เหลือ ตาราง _ScriptLog จะต้องได้รับการทำความสะอาดเมื่อเวลาผ่านไปหากคุณทำสิ่งนี้มาก

คุณสามารถแก้ไขสิ่งนี้ได้หากคุณต้องการทำตารางทั้งหมดเพียงแค่ใส่ชื่อที่เลือกไว้ใน #TruncateList FROM sys.tables อย่างไรก็ตามคุณมักจะไม่ต้องการทำทั้งหมด

นอกจากนี้สิ่งนี้จะมีผลกับคีย์ต่างประเทศทั้งหมดในฐานข้อมูลและคุณสามารถแก้ไขได้เช่นกันหากแรงเกินไปสำหรับการใช้งานของคุณ มันไม่ได้สำหรับวัตถุประสงค์ของฉัน

/*
CREATE TABLE _ScriptLog 
(
    ID Int NOT NULL Identity(1,1)
    , DateAdded DateTime2 NOT NULL DEFAULT GetDate()
    , Script NVarChar(4000) NOT NULL
)

CREATE UNIQUE CLUSTERED INDEX IX_ScriptLog_DateAdded_ID_U_C ON _ScriptLog
(
    DateAdded
    , ID
)

CREATE TABLE _TruncateList
(
    TableName SysName PRIMARY KEY
)
*/
IF OBJECT_ID('TempDB..#DropFK') IS NOT NULL BEGIN
    DROP TABLE #DropFK
END

IF OBJECT_ID('TempDB..#TruncateList') IS NOT NULL BEGIN
    DROP TABLE #TruncateList
END

IF OBJECT_ID('TempDB..#CreateFK') IS NOT NULL BEGIN
    DROP TABLE #CreateFK
END

SELECT Scripts = 'ALTER TABLE ' + '[' + OBJECT_NAME(f.parent_object_id)+ ']'+
' DROP  CONSTRAINT ' + '[' + f.name  + ']'
INTO #DropFK
FROM .sys.foreign_keys AS f
INNER JOIN .sys.foreign_key_columns AS fc
ON f.OBJECT_ID = fc.constraint_object_id

SELECT TableName
INTO #TruncateList
FROM _TruncateList

SELECT Scripts = 'ALTER TABLE ' + const.parent_obj + '
    ADD CONSTRAINT ' + const.const_name + ' FOREIGN KEY (
            ' + const.parent_col_csv + '
            ) REFERENCES ' + const.ref_obj + '(' + const.ref_col_csv + ')
'
INTO #CreateFK
FROM (
    SELECT QUOTENAME(fk.NAME) AS [const_name]
        ,QUOTENAME(schParent.NAME) + '.' + QUOTENAME(OBJECT_name(fkc.parent_object_id)) AS [parent_obj]
        ,STUFF((
                SELECT ',' + QUOTENAME(COL_NAME(fcP.parent_object_id, fcp.parent_column_id))
                FROM sys.foreign_key_columns AS fcP
                WHERE fcp.constraint_object_id = fk.object_id
                FOR XML path('')
                ), 1, 1, '') AS [parent_col_csv]
        ,QUOTENAME(schRef.NAME) + '.' + QUOTENAME(OBJECT_NAME(fkc.referenced_object_id)) AS [ref_obj]
        ,STUFF((
                SELECT ',' + QUOTENAME(COL_NAME(fcR.referenced_object_id, fcR.referenced_column_id))
                FROM sys.foreign_key_columns AS fcR
                WHERE fcR.constraint_object_id = fk.object_id
                FOR XML path('')
                ), 1, 1, '') AS [ref_col_csv]
    FROM sys.foreign_key_columns AS fkc
    INNER JOIN sys.foreign_keys AS fk ON fk.object_id = fkc.constraint_object_id
    INNER JOIN sys.objects AS oParent ON oParent.object_id = fkc.parent_object_id
    INNER JOIN sys.schemas AS schParent ON schParent.schema_id = oParent.schema_id
    INNER JOIN sys.objects AS oRef ON oRef.object_id = fkc.referenced_object_id
    INNER JOIN sys.schemas AS schRef ON schRef.schema_id = oRef.schema_id
    GROUP BY fkc.parent_object_id
        ,fkc.referenced_object_id
        ,fk.NAME
        ,fk.object_id
        ,schParent.NAME
        ,schRef.NAME
    ) AS const
ORDER BY const.const_name

INSERT INTO _ScriptLog (Script)
SELECT Scripts
FROM #CreateFK

DECLARE @Cmd NVarChar(4000)
    , @TableName SysName

WHILE 0 < (SELECT Count(1) FROM #DropFK) BEGIN
    SELECT TOP 1 @Cmd = Scripts 
    FROM #DropFK

    EXEC (@Cmd)

    DELETE #DropFK WHERE Scripts = @Cmd
END

WHILE 0 < (SELECT Count(1) FROM #TruncateList) BEGIN
    SELECT TOP 1 @Cmd = N'TRUNCATE TABLE ' +  TableName
        , @TableName = TableName
    FROM #TruncateList

    EXEC (@Cmd)

    DELETE #TruncateList WHERE TableName = @TableName
END

WHILE 0 < (SELECT Count(1) FROM #CreateFK) BEGIN
    SELECT TOP 1 @Cmd = Scripts 
    FROM #CreateFK

    EXEC (@Cmd)

    DELETE #CreateFK WHERE Scripts = @Cmd
END

0

ฉันไม่เห็นว่าทำไมการล้างข้อมูลจะดีกว่าสคริปต์เพื่อวางและสร้างแต่ละตารางใหม่

หรือสำรองฐานข้อมูลเปล่าของคุณไว้และกู้คืนจากฐานข้อมูลเก่า


2
เหตุผลคือโอเวอร์เฮดของการดร็อปและสร้างไฟล์ฐานข้อมูลบนดิสก์บันทึก ฯลฯ ช้ามากอย่างมาก คิดลบฐานข้อมูล 1,000 ครั้งในระหว่างการทดสอบหน่วยที่เหมาะสม
Chris KL

0

ก่อนที่จะตัดทอนตารางคุณจะต้องลบกุญแจต่างประเทศทั้งหมด ใช้สคริปต์นี้ เพื่อสร้างสคริปต์สุดท้ายเพื่อวางและสร้างคีย์ต่างประเทศทั้งหมดในฐานข้อมูล โปรดตั้งค่าตัวแปร @action เป็น 'CREATE' หรือ 'DROP'


0

เลือก 'ลบจาก' + TABLE_NAME จาก INFORMATION_SCHEMA.TABLES โดยที่ TABLE_TYPE = 'ฐานตาราง'

ที่มาผลลัพธ์

คัดลอกและวางบนหน้าต่างแบบสอบถามและเรียกใช้คำสั่ง


0

มันสายไปหน่อย แต่มันอาจช่วยใครซักคน ฉันสร้างโพรซีเดอร์บางครั้งกลับซึ่งใช้ T-SQL ต่อไปนี้:

  1. เก็บข้อ จำกัด ทั้งหมดในตารางชั่วคราว
  2. ปล่อยข้อ จำกัด ทั้งหมด
  3. ตัดทอนตารางทั้งหมดด้วยข้อยกเว้นของบางตารางซึ่งไม่จำเป็นต้องตัดทอน
  4. สร้างข้อ จำกัด ทั้งหมดใหม่

ฉันได้แสดงไว้ในบล็อกของฉันที่นี่

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