
اگر با 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‑۰۰۰۰۱ در اوراکل داری، در بخش کامنتها بپرس.

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