
خطای ORA‑۰۶۵۰۲: PL/SQL Numeric or Value Error یکی از پرتکرارترین و آزاردهندهترین خطاهای Oracle است. معمولاً زمانی ظاهر میشود که در اجرای PL/SQL، مقدار دادهای با نوع داده یا ظرفیت متغیر همخوانی ندارد.
این خطا کامپایل را خراب نمیکند، اما در زمان اجرا برنامه را متوقف میکند و معمولاً باعث سردرگمی برنامهنویس میشود.
اگر شما هم هنگام کار با اوراکل با خطاهایی مثل overflow, character string buffer too small یا invalid number روبهرو شدهاید، این مقاله آموزش Oracle در بخش خطای های اوراکلی،دقیقاً برای شماست.
در این مقاله یاد میگیرید:
- چرا ORA‑۰۶۵۰۲ اتفاق میافتد
- رایجترین علتهای Overflow و mismatch نوع داده
- مثالهای واقعی و کاربردی
- روشهای جلوگیری از وقوع این خطا
- الگوهای درست طراحی در PL/SQL
اگر هنگام کار با تاریخها در Oracle به خطای ORA‑۰۱۸۴۳: Not a Valid Month برخوردهای، کاملاً طبیعی است؛ این خطا یکی از شایعترین خطاهای پایگاهداده Oracle است.
پیشنهاد می کنم این مقاله زیر رو حتما مطالعه کنی.
در این مقاله شما می خوانید
خطای ORA‑۰۶۵۰۲ چیست و دقیقاً چه میگوید؟
وقتی Oracle خطای ORA‑۰۶۵۰۲ را میدهد، یعنی یک مشکل منطقی در مقدار داده رخ داده است، نه در ساختار یا سینتکس.
به بیان ساده:
«دادهای که وارد یک متغیر یا ستون شده، با نوع دادهٔ مقصد سازگار نیست.»
این خطا میتواند ناشی از طول زیاد رشته، مقدار عددی خارج از محدوده، تبدیل نامعتبر (conversion error) یا مشکلات NLS باشد.
علتهای اصلی خطای ORA‑۰۶۵۰۲
۱) طول رشته بیشتر از اندازه متغیر (Character String Buffer Too Small)
یکی از مهمترین علتها همین است. اگر متغیر یا ستون ظرفیت محدودی داشته باشد، Oracle اجازه ورود مقدار بزرگتر را نمیدهد.
مثال اشتباه
declare
v_name varchar2(5);
begin
v_name := 'ORACLEDB';
end;
نتیجه:
ORA‑۰۶۵۰۲: character string buffer too small
راهحل
- افزایش طول
- بریدن مقدار با substr
- استفاده از %TYPE برای هماندازه ماندن با ستونها
نسخه صحیح
declare
v_name employees.last_name%type;
begin
v_name := 'ORACLEDB';
end;
۲) Overflow در انواع عددی (NUMBER Precision/Scale Error)
نوع داده NUMBER محدودیت دارد. مثلاً:
NUMBER(5,2)
حداکثر مقدار ≈ ۹۹۹.۹۹
مثال اشتباه
declare
v_amount number(5,2);
begin
v_amount := 12345.67; -- kheili bozorg tar az damane
end;
راهحل
- افزایش precision
- گرد کردن
- استفاده از NUMBER بدون محدودیت (در صورت ضرورت)
نسخه صحیح
declare
v_amount number(9,2);
begin
v_amount := 12345.67;
end;
۳) تبدیل نادرست رشته به عدد (Invalid Number)
گاهی Oracle تلاش میکند یک رشته را ضمنی به NUMBER تبدیل کند و شکست میخورد.
مثال اشتباه
declare
v_num number;
begin
v_num := '12A';
end;
نسخه امن (در ۱۲c به بالا)
v_num := to_number(v_txt default null on conversion error);
یا با REGEXP:
if regexp_like(v_txt, '^\d+(\.\d+)?$') then
v_num := to_number(v_txt);
end if;
۴) انتخاب مقدار بزرگتر از اندازه متغیر در SELECT INTO
اگر مقدار داخل جدول بزرگتر از اندازه متغیر باشد، احتمالاً این خطا را میبینید.
نسخه اشتباه
declare
v_email varchar2(10);
begin
select email into v_email
from employees
where employee_id = 100;
end;
نسخه صحیح
declare
v_email employees.email%type;
begin
select email into v_email
from employees
where employee_id = 100;
end;
۵) مشکلات CHAR/NCHAR و فاصلههای اضافه (Padding Issues)
استفاده از نوع CHAR به دلیل پر شدن خودکار با space میتواند باعث خطاهای مقایسه یا طول نامعتبر شود. استفاده از VARCHAR2 اغلب سادهتر و ایمنتر است.
چطور بفهمیم خطا دقیقاً کجاست؟ (Debugging)
استفاده از Backtrace
این روش دقیقاً خطی از کد که باعث ORA‑۰۶۵۰۲ شده را نشان میدهد.
exception
when others then
dbms_output.put_line(sqlerrm);
dbms_output.put_line(dbms_utility.format_error_backtrace);
raise;
بهترین روشهای جلوگیری از خطای ORA‑۰۶۵۰۲
- همیشه از
%TYPEو%ROWTYPEاستفاده کنید - تبدیل رشته به عدد را ایمن انجام دهید
- محدودههای NUMBER را آگاهانه تعریف کنید
- قبل از انتساب، طول رشته را بررسی یا کنترل کنید
- در تبدیلها تنظیمات NLS را مشخص کنید
- اگر امکان دارد، از CLOB برای متنهای بزرگ استفاده کنید
سناریوی واقعی: ورودی کاربر → تبدیل → ذخیره
create or replace procedure save_price(p_price_txt varchar2) is
v_price number(12,2);
begin
v_price := to_number(p_price_txt default null on conversion error);
if v_price is null then
raise_application_error(-20001, 'list etebari nadarad!!');
end if;
insert into prices_log(price_value, created_at)
values (v_price, systimestamp);
end;
چکلیست سریع تشخیص خطای ORA‑۰۶۵۰۲
- آیا طول رشته زیاد است؟
- آیا مقدار عددی از محدوده خارج شده؟
- آیا تبدیل ضمنی انجام شده؟
- آیا متغیر SELECT INTO ظرفیت کافی دارد؟
- آیا فرمت تاریخ/عدد با NLS سازگار است؟
سوالات متداول درباره رفع خطای ORA‑۰۶۵۰۲ در اوراکل
خطای ORA‑۰۶۵۰۲ زمانی رخ میدهد که مقدار یک متغیر یا فیلد با نوع دادهای که برای آن تعریف شده سازگار نباشد. مهمترین علتها شامل طول بیش از حد رشته، overflow عددی در NUMBER(p,s)، تبدیل رشته نامعتبر به عدد یا مشکل در SELECT INTO است.
سریعترین روش تشخیص علت واقعی این است که در بخش Exception از دستور زیر استفاده شود:
dbms_output.put_line(dbms_utility.format_error_backtrace);
این دستور شمارهٔ خط دقیق بروز خطا را نشان میدهد و معمولاً در کمتر از چند ثانیه مشخص میشود که کدام متغیر یا نوع داده باعث مشکل شده است.
رایجترین اشتباه این است که کاربر مقدار '۱۲a' یا رشتهٔ مشابه را به NUMBER تبدیل میکند و برنامه با ORA‑۰۶۵۰۲ میریزد. بهترین راه جلوگیری این است که از تبدیل ایمن در Oracle 12c به بالا استفاده کنید:
v_num := to_number(p_txt default null on conversion error);
اگر ورودی نامعتبر باشد، به جای خطا مقدار NULL برمیگردد و برنامه متوقف نمیشود.
این روش بهترین نرخ موفقیت را برای جلوگیری از خطاهای conversion دارد و در سیستمهای Production نیز توصیه میشود.
اگر مقدار ستون در جدول طول بیشتری از متغیر مقصد داشته باشد، SELECT INTO باعث ORA‑۰۶۵۰۲ میشود.
برای مثال:
v_email varchar2(10);
select email into v_email from employees where employee_id = 100;
اگر مقدار email در جدول مثلاً ۲۰ کاراکتر باشد، خطا تولید میشود.
راهحل:
بهجای تعیین دستی اندازه:
v_email employees.email%type;
این روش همیشه با اندازه واقعی ستون هماهنگ است و احتمال خطا را نزدیک به صفر میکند. این راهکار یکی از بهترین ترفندهای حرفهای PL/SQL محسوب میشود.
برای تشخیص اینکه خطای ORA‑۰۶۵۰۲ از کدام متغیر ناشی شده، میتوان قبل از هر انتساب، مقدار و طول داده را چاپ کرد:
dbms_output.put_line(‘LEN=’ || length(v_txt) || ‘, VAL=’ || v_txt);
dbms_output.put_line(‘NUM=’ || to_char(v_num, ‘TM’));
اگر مقدار عددی از محدوده NUMBER(p,s) خارج باشد، یا اگر رشته طول زیادی داشته باشد، در لحظه معلوم میشود مشکل دقیقاً چیست.
نشانههای رایج Overflow:
- مقدار ۱۲۳۴۵ برای NUMBER(4)
- مقدار ۱۰.۵۵ برای NUMBER(4,1)
- مقدار رشته ۲۰ کاراکتر برای VARCHAR2(10)
این روش سادهترین و سریعترین راه برای تشخیص منشأ ORA‑۰۶۵۰۲ در پروژههای بزرگ است.
جمعبندی
خطای ORA‑۰۶۵۰۲ در Oracle یکی از خطاهای پرتکرار اما قابلپیشگیری است. با استفاده از اصول صحیح طراحی متغیرها، تبدیل امن دادهها، تعیین درست precision/scale و تحلیل خطا با Backtrace، میتوان بهطور کامل از این مشکل جلوگیری کرد.
سؤالی درباره این مقاله داری؟
اگر نکتهای در این مقاله برات مبهم بود یا خواستی بیشتر بدونی، همین حالا برام بنویس تا دقیق و صمیمی پاسخت رو بدم — مثل یه گفتوگوی واقعی 💬
برو به صفحه پرسش و پاسخ
دیدگاهتان را بنویسید