📚 فصل ۱۶ — حذف دادهها با دستور DELETE در SQL Server
1️⃣ مقدمه — چرا گاهی باید دادهها را حذف کنیم؟
در دیتابیسها، علاوه بر افزودن و بهروزرسانی، باید بتوانیم دادههای نامعتبر، قدیمی یا زائد را حذف کنیم. برخی سناریوهای واقعی:
- سفارشهای تستی که اشتباهاً وارد شدهاند.
- کاربران غیرفعال یا جعلی.
- لاگهای قدیمی که دیگر نیازی به آنها نیست (برای آزاد کردن فضا).
- دادههایی که به دلایل قانونی باید حذف شوند (مثل قانون GDPR در اروپا).
💡 دستور اصلی برای حذف دادهها در SQL Server، دستور DELETE است.
2️⃣ ساختار پایه دستور DELETE
DELETE FROM TableName
WHERE Condition;
اجزای دستور
- DELETE FROM TableName → جدول مقصد حذف.
- WHERE Condition → شرط حذف رکوردها.
- اگر WHERE حذف شود، همه رکوردها حذف خواهند شد (خطرناک ⚠️).
3️⃣ نمونه ساده — حذف یک رکورد خاص
DELETE FROM Customers
WHERE CustomerID = 10;
📌 این دستور فقط مشتری با شناسه ۱۰ را حذف میکند.
4️⃣ حذف چند رکورد با شرط
DELETE FROM Orders
WHERE Status = N'باطل شده';
📌 همه سفارشهایی که وضعیتشان “باطل شده” باشد حذف میشوند.
5️⃣ خطر بزرگ — حذف بدون شرط WHERE
DELETE FROM Customers;
📛 همه مشتریان حذف میشوند!
این کار معمولاً غیرقابل بازگشت است مگر اینکه بکاپ داشته باشید.
6️⃣ پیشنمایش قبل از حذف — نکته طلایی
قبل از اجرای DELETE، همان شرط را با SELECT تست کنید:
SELECT *
FROM Orders
WHERE OrderDate < '2023-01-01';
اگر نتایج صحیح بود، دستور DELETE را با همان شرط اجرا کنید.
7️⃣ حذف همه دادهها — TRUNCATE vs DELETE
DELETE:
- قابل استفاده با شرط WHERE
- رکوردها یکییکی حذف میشوند (کندتر)
- قابل استفاده روی جدول با Foreign Key با محدودیتها
TRUNCATE:
- بدون WHERE → همه دادهها حذف میشوند
- بسیار سریعتر
- شمارنده IDENTITY ریست میشود
- نمیتوان روی جدول با Foreign Key اجرا کرد
📌 مثال:
TRUNCATE TABLE TempLogs;
8️⃣ حذف بر اساس داده جدول دیگر (DELETE + JOIN)
گاهی باید رکوردهایی را که در جدول دیگر وجود دارند (یا ندارند) حذف کنم.
مثلاً حذف مشتریانی که هیچ سفارشی ندارند:
DELETE c
FROM Customers c
LEFT JOIN Orders o ON c.CustomerID = o.CustomerID
WHERE o.CustomerID IS NULL;
9️⃣ حذف محدودشده با TOP
DELETE TOP (5)
FROM Orders
WHERE Status = N'در حال پردازش';
📌 فقط ۵ رکورد اولی که شرط را دارند حذف میشوند.
🔟 حذف رکوردها با در نظر گرفتن محدودیت Foreign Key
اگر رکوردی که میخواهید حذف کنید در جدول دیگری استفاده شده باشد (به عنوان کلید خارجی)، دو حالت پیش میآید:
- خطا دریافت میکنید.
- یا در طراحی دیتابیس
ON DELETE CASCADE
تعریف کردهاید که باعث حذف خودکار رکوردهای مرتبط میشود.
مثال:
-- اگر رابطه cascade فعال باشد:
DELETE FROM Customers
WHERE CustomerID = 5;
-- سفارشهای مشتری ۵ هم خودکار حذف میشوند.
⚠️ استفاده از CASCADE با احتیاط.
1️⃣1️⃣ اشتباهات رایج در DELETE
- حذف بدون WHERE.
- حذف از جدول اشتباه.
- اشتباه در شرط (حذف رکوردهای اشتباه).
- نداشتن بکاپ قبل از حذف انبوه.
1️⃣2️⃣ نکات حرفهای و ایمنسازی حذف
- همیشه با SELECT پیشنمایش کنید.
- برای عملیات بزرگ از تراکنش استفاده کنید:
BEGIN TRAN;
DELETE FROM Orders
WHERE OrderDate < '2023-01-01';
-- بررسی نتایج:
SELECT COUNT(*) FROM Orders WHERE OrderDate < '2023-01-01';
ROLLBACK TRAN; -- یا COMMIT TRAN;
- لاگکردن رکوردهای حذفشده در جدول آرشیو:
INSERT INTO ArchivedOrders (OrderID, CustomerID, OrderDate, Status)
SELECT OrderID, CustomerID, OrderDate, Status
FROM Orders
WHERE Status = N'باطل شده';
DELETE FROM Orders
WHERE Status = N'باطل شده';
1️⃣3️⃣ سناریوهای واقعی پروژهای
سناریو ۱ — حذف سفارشهای تست
DELETE FROM Orders
WHERE CustomerID IN (999, 1000);
سناریو ۲ — پاکسازی لاگ قدیمی
DELETE FROM ActivityLogs
WHERE LogDate < DATEADD(YEAR, -1, GETDATE());
سناریو ۳ — حذف کاربران غیرفعال
DELETE FROM Users
WHERE IsActive = 0
AND LastLoginDate < DATEADD(MONTH, -6, GETDATE());
1️⃣4️⃣ تمرینهای عملی
- همه سفارشهایی که در سال ۱۴۰۰ ثبت شدهاند را حذف کن.
- مشتریانی که ایمیل ندارند را حذف کن.
- جدول
TempData
را بهطور کامل خالی کن (با TRUNCATE). - سفارشهای با وضعیت “در انتظار پرداخت” که بیش از ۳۰ روز از تاریخشان گذشته را حذف کن.
- کاربرانی که هیچ پستی در سیستم ارسال نکردهاند را حذف کن (با JOIN).
1️⃣5️⃣ جمعبندی
در این فصل یاد گرفتید:
- دستور DELETE و کاربرد آن
- اهمیت شرط WHERE
- تفاوت DELETE و TRUNCATE
- حذف با شرطهای پیچیده و JOIN
- جلوگیری از اشتباهات با Preview و تراکنش
- سناریوهای واقعی و تمرینها