ESC را فشار دهید تا بسته شود

زمیوس آموزش، یادگیری و سرگرمی

ORA‑۰۰۰۰۱: رفع خطای مقدار تکراری (Unique Constraint Violated) در Oracle

اگر با Oracle Database کار کرده باشی، احتمالاً یکی از آشنا‌ترین پیام‌های خطا برایت این است:

				
					ORA-00001: unique constraint (SCHEMA.CONSTRAINT_NAME) violated

				
			

این خطا یکی از کلاسیک‌ترین و درعین‌حال مهم‌ترین ارورهایی‌ست که اغلب در مراحل INSERT یا UPDATE داده‌ها با آن مواجه می‌شویم. معناش ساده است:

اوراکل می‌گوید: «قراره داده‌ای ذخیره کنم که مقدار کلید آن قبلاً وجود داشته و تکراریه!»

خطای ORA‑۰۰۰۰۱ معمولاً وقتی رخ می‌دهد که ستونی با کلید اصلی (Primary Key) یا شناسه یکتا (Unique Constraint) دارای مقدار تکراری شود.

در این مقاله آموزش اوراکل از بخش آموزش رفع خطاهای اوراکلی در مورد این خطا مفصل صحبت کنیم.

اگر از برنامه‌نویسان یا DBAهای باتجربه‌ی Oracle باشید، احتمالاً حداقل یک بار با ارور کلاسیک زیر روبه‌رو شده‌اید:

ORA-۰۱۵۵۵: snapshot too old: rollback segment number with name "" too small

پیشنهاد می کنم این مقاله زیر رو حتما مطالعه کنی.

در این مقاله شما می خوانید

در اوراکل، ستون‌هایی با محدودیت PRIMARY KEY و UNIQUE فقط باید مقادیر منحصربه‌فرد دریافت کنند.

مثلاً فرض کن چنین جدولی داری:

				
					CREATE TABLE employees (
  emp_id      NUMBER PRIMARY KEY,
  national_id VARCHAR2(10) UNIQUE,
  emp_name    VARCHAR2(100)
);
				
			

در این جدول، دو محدودیت یکتا داریم:

  • PK_EMPLOYEES برای ستون emp_id
  • و SYS_C0012345 (که اوراکل خودش نام‌گذاری کرده) برای national_id

اگر حالا بخواهیم رکوردی با مقدار تکراری درج کنیم، سیستم اجازه نمی‌دهد.

مثال واقعی از خطای ORA‑۰۰۰۰۱

				
					INSERT INTO employees (emp_id, national_id, emp_name)
VALUES (1, '0012345678', 'Ali Moradi');

INSERT INTO employees (emp_id, national_id, emp_name)
VALUES (1, '0012345678', 'Ali Moradi');

				
			

نتیجه اجرا:

				
					ORA-00001: unique constraint (HR.PK_EMPLOYEES) violated
				
			

چون مقدار emp_id=1 و national_id='0012345678' قبلاً ثبت شده‌اند، اوراکل اجازه‌ی درج مجدد نمی‌دهد.

چطور بفهمیم کدام ستون باعث ارور شده؟

در پیام خطا، اسم Constraint درج می‌شود (مثلاً HR.PK_EMPLOYEES).

برای پیدا کردن اینکه کدام ستون مربوط به این Constraint است، کافیست دستور زیر را بزنیم:

				
					SELECT constraint_name, table_name, column_name
FROM user_cons_columns
WHERE constraint_name = 'PK_EMPLOYEES';

				
			

در خروجی دقیقاً مشخص می‌شود کدام ستون علت خطاست.

نمونه:

				
					OWNER | TABLE_NAME | COLUMN_NAME
HR    | EMPLOYEES  | EMP_ID
				
			

روش‌های رفع خطای ORA‑۰۰۰۰۱

۱️⃣ بررسی وجود رکورد قبل از INSERT

یکی از روش‌های پیشگیرانه:

				
					INSERT INTO employees (emp_id, emp_name)
SELECT 100, 'Sara'
FROM dual
WHERE NOT EXISTS (
  SELECT 1 FROM employees WHERE emp_id = 100
);

				
			

با این روش اگر رکورد موجود باشد، عملیات درج انجام نمی‌شود.

۲️⃣ استفاده از دستور MERGE

اگر می‌خواهی در صورت وجود رکورد، Update و در غیر این صورت Insert انجام شود:

				
					MERGE INTO employees e
USING (SELECT 100 emp_id, 'Sara' emp_name FROM dual) src
ON (e.emp_id = src.emp_id)
WHEN MATCHED THEN
  UPDATE SET e.emp_name = src.emp_name
WHEN NOT MATCHED THEN
  INSERT (emp_id, emp_name)
  VALUES (src.emp_id, src.emp_name);

				
			

۳️⃣ اصلاح Sequence برای Primary Key

گاهی خطا به‌دلیل استفاده نادرست از Sequence رخ می‌دهد.

روش اشتباه:

				
					INSERT INTO employees(emp_id, emp_name)
VALUES (seq_emp_id.CURRVAL, 'Hassan');

				
			

روش درست:

				
					INSERT INTO employees(emp_id, emp_name)
VALUES (seq_emp_id.NEXTVAL, 'Hassan');

				
			

۴️⃣ حذف یا اصلاح رکوردهای تکراری قبلی

اگر داده اشتباهی وجود دارد، اول باید آن را پاک‌سازی کنی:

				
					DELETE FROM employees WHERE emp_id = 100;

				
			

بعد مجدد رکورد صحیح را درج کن.

رفع خطا هنگام اضافه کردن Unique Constraint

گاهی می‌خواهی محدودیت یکتا بسازی ولی داده‌ی تکراری از قبل وجود دارد:

				
					ALTER TABLE employees ADD CONSTRAINT emp_nid_uk UNIQUE (national_id);

				
			

و با خطای ORA‑۰۰۰۰۱ مواجه می‌شوی.

در این حالت باید قبلش داده‌های تکراری را شناسایی و رفع کنی:

				
					SELECT national_id, COUNT(*)
FROM employees
GROUP BY national_id
HAVING COUNT(*) > ۱;

				
			

کنترل خطای ORA‑۰۰۰۰۱ در PL/SQL با DUP_VAL_ON_INDEX

در بلاک‌های PL/SQL، می‌توان خطا را به‌صورت برنامه‌نویسی‌شده کنترل کرد:

				
					BEGIN
  FOR rec IN (SELECT * FROM temp_employees) LOOP
    INSERT INTO employees VALUES rec;
  END LOOP;
EXCEPTION
  WHEN DUP_VAL_ON_INDEX THEN
    DBMS_OUTPUT.PUT_LINE('Reocrd Tekrari Peida Shod!');
END;

				
			

به این ترتیب برنامه ادامه پیدا می‌کند و درج بقیه داده‌ها متوقف نمی‌شود.

نکات حرفه‌ای در رفع خطای ORA‑۰۰۰۰۱ در Oracle

  • در سیستم‌های چندکاربره (Concurrent Systems): همیشه از Sequence برای درج کلید استفاده کن تا مقدار منحصربه‌فرد تضمین شود.
  • در اپلیکیشن با API یا Bot: قبل از INSERT حتماً داده را از سرور اعتبارسنجی کن.
  • در Migration یا ETLها: داده‌ها را با SQL GROUP BY بررسی کن تا پاک‌سازی دقیق انجام شود.

سوالات متداول درباره رفع خطای ORA‑۰۰۰۰۱ در اوراکل

خطای ORA‑۰۰۰۰۱: unique constraint violated یعنی در زمان INSERT یا UPDATE داری مقداری وارد می‌کنی که قبلاً در ستون دارای کلید اصلی (PRIMARY KEY) یا محدودیت یکتا (UNIQUE) وجود داشته.

اوراکل برای حفظ تمامیت داده (Data Integrity) اجازه تکرار نمی‌دهد.

مثلاً وقتی یک کارمند با EMP_ID = 1 از قبل ثبت شده، درج دوباره همان مقدار، خطای ORA‑۰۰۰۰۱ ایجاد می‌کند.

اگر خطا هنگام درج داده رخ می‌دهد، ساده‌ترین راه بررسی وجود رکورد قبل از درج است:

INSERT INTO employees (emp_id, emp_name)
SELECT 100, ‘Sara’
FROM dual
WHERE NOT EXISTS (SELECT 1 FROM employees WHERE emp_id = 100);

در پروژه‌های حرفه‌ای، استفاده از دستور MERGE پیشنهاد می‌شود چون همزمان عملیات درج و به‌روزرسانی را کنترل می‌کند و از تکرار جلوگیری می‌کند:

MERGE INTO employees e
USING (SELECT 100 emp_id, ‘Sara’ emp_name FROM dual) src
ON (e.emp_id = src.emp_id)
WHEN MATCHED THEN UPDATE SET e.emp_name = src.emp_name
WHEN NOT MATCHED THEN INSERT (emp_id, emp_name) VALUES (src.emp_id, src.emp_name);

در PL/SQL، خطای ORA‑۰۰۰۰۱ با نام استثناء داخلی DUP_VAL_ON_INDEX شناخته می‌شود.

می‌توان آن را به‌صورت برنامه‌نویسی شده گرفت و از توقف پردازش جلوگیری کرد:

BEGIN
INSERT INTO employees VALUES (1, ‘Ali’, ‘HR’);
EXCEPTION
WHEN DUP_VAL_ON_INDEX THEN
DBMS_OUTPUT.PUT_LINE(‘رکورد تکراری است، از درج چشم‌پوشی شد.’);
END;

این روش مخصوص زمانی است که در Batch Insert یا عملیات گروهی چند رکورد درج می‌کنی، و اگر یکی تکراری بود کل پروسه متوقف نشود.

هردو جلوی تکرار داده را می‌گیرند، اما تفاوت در منطق مدیریتی آن‌هاست:

  • Unique Constraint بیشتر در سطح قواعد داده‌ای (Data Rule) تعریف می‌شود و معمولاً بخشی از طراحی منطقی جدول است.
  • Unique Index در سطح ساختار فیزیکی ذخیره‌سازی ایجاد می‌شود و حتی بدون constraint هم می‌تواند منحصربه‌فردی را enforce کند.

گاهی حذف constraint باعث حذف خودکار index می‌شود، اما برعکس همیشه صادق نیست.

برای بررسی لیست ایندکس‌های یکتا:

SELECT index_name, uniqueness
FROM user_indexes
WHERE table_name = ‘EMPLOYEES’;

جمع‌بندی

مورد توضیح
پیام خطا ORA‑۰۰۰۰۱: unique constraint violated
علت اصلی درج یا تغییر مقدار تکراری در ستون‌های Primary Key یا Unique
استثناء در PL/SQL DUP_VAL_ON_INDEX
راه‌های پیشگیری MERGE، NOT EXISTS، Sequence
رفع داده‌های تکراری حذف یا اصلاح داده قبل از افزودن Constraint

در واقع، ORA‑۰۰۰۰۱ دشمنی نیست که از آن بترسی — بلکه نشانه‌ی این است که اوراکل با دقت از تمامیت داده (Data Integrity) محافظت می‌کند.

اگر منطق درج داده‌ها را حرفه‌ای طراحی کنی، این خطا دیگر هرگز غافلگیرت نخواهد کرد.

📥 اگر سوالی داری در مورد رفع خطای ORA‑۰۰۰۰۱ در اوراکل داری، در بخش کامنت‌ها بپرس.

میثم راد

من یه برنامه نویسم که حسابی با دیتابیس اوراکل رفیقم! از اونایی ام که تا چیزی رو کامل نفهمم،ول کن نیستم، یادگرفتن برام مثل بازیه، و نوشتن اینجا کمک می کنه تا چیزایی که یاد گرفتم رو با بقیه به شریک بشم، با هم پیشرفت کنیم.

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *