حذف سریع تمام رکوردها در SQL server
اندازه‌ی قلم متن
تخمین مدت زمان مطالعه‌ی مطلب: یک دقیقه


فرض کنید یک دیتابیس آزمایشی دارید که می‌خواهید تمام رکوردهای آن‌را حذف کنید. اگر در این دیتابیس انواع و اقسام کلیدهای خارجی و تریگر و امثال آن وجود داشته باشند، صرفا با یک دستور delete ساده کار به پایان نمی‌رسد و موفق به حذف رکوردها نخواهید شد (چون این قید و بندها به همین جهت طراحی شده‌اند تا یکپارچگی دیتابیس حفظ شود).
اما اگر واقعا این قیود در این لحظه مهم نبودند و نیاز بود تا تمام رکوردها را حذف کنیم، سریعترین راه حل موجود چیست؟

--Disable Constraints & Triggers
exec sp_MSforeachtable 'ALTER TABLE ? NOCHECK CONSTRAINT ALL'
exec sp_MSforeachtable 'ALTER TABLE ? DISABLE TRIGGER ALL'
--Perform delete operation on all table for cleanup
exec sp_MSforeachtable 'DELETE ?'
--Enable Constraints & Triggers again
exec sp_MSforeachtable 'ALTER TABLE ? CHECK CONSTRAINT ALL'
exec sp_MSforeachtable 'ALTER TABLE ? ENABLE TRIGGER ALL'
--Reset Identity on tables with identity column
exec sp_MSforeachtable 'IF OBJECTPROPERTY(OBJECT_ID(''?''), ''TableHasIdentity'') = 1 BEGIN DBCC CHECKIDENT (''?'',RESEED,0) END'

اسکریپت فوق تمامی رکوردهای دیتابیس جاری را حذف کرده و همچنین فیلدهای identity را نیز مجددا به حالت اول باز می‌گرداند.

توضیحات:
sp_Msforeachtable یکی از رویه‌های ذخیره شده‌ی سیستمی اس کیوال سرور می‌باشد که مستند نشده است. اگر نیاز داشتید کدی را بدون نوشتن یک کرسر و امثال آن، بر روی تمامی جداول اجرا کنید می‌توان از آن استفاده نمود.
امضای این رویه ذخیره شده به صورت زیر است:

exec @RETURN_VALUE=sp_MSforeachtable @command1, @replacechar, @command2,
@command3, @whereand, @precommand, @postcommand

که در آن:
RETURN_VALUE مقدار بازگشتی است.
Command1 اولین دستوری است که اجرا خواهد شد (به همین ترتیب سپس Command2 و بعد از آن Command3 اجرا خواهد گردید)
Replacechar کاراکتری است که در دستور T-SQL مورد نظر جایگزین نام جدول خواهد شد. مقدار پیش فرض آن ? است.
Precommand پیش از پردازش عملیات روی هر جدولی اجرا می‌شود.
Postcommand پس از اجرای کلیه دستورات روی تمامی جداول، اجرا خواهد شد.

چند مثال:
نمایش تمامی جداول دیتابیس جاری
EXEC sp_MSforeachtable "print '?'"
نمایش اندازه‌ی جداول یک دیتابیس
EXEC sp_msforeachtable 'sp_spaceused ''?'''

  • #
    ‫۱۵ سال و ۲ ماه قبل، شنبه ۲۴ مرداد ۱۳۸۸، ساعت ۰۱:۲۷
    ممنون، مطلب خوبی بود.
  • #
    ‫۸ سال و ۹ ماه قبل، یکشنبه ۱۳ دی ۱۳۹۴، ساعت ۰۱:۱۱
    برای تکمیل‌تر کردن بحث این نکته رو بگم که بعد از غیرفعال کردن ارتباطات و ... می‌توان از دستور TruncateTable که سریعتر از delete هم هست استفاده نمود. البته این نکته هم باید در نظر گرفته بشه که اطلاعات این حذف لاگ نخواهند شد.