تغییر نوع ستون از NUMBER به VARCHAR2 در اوراکل

هنگام کار با دیتابیس اوراکل، گاهی متوجه می‌شویم که نوع داده‌ی یک ستون را اشتباه انتخاب کرده‌ایم. مثلاً ستون شماره موبایل را از نوع NUMBER در نظر گرفته‌ایم، در حالی که شماره موبایل ممکن است با صفر شروع شود (که در نوع عددی حذف می‌شود) یا نیاز به پیش‌شماره بین‌المللی با علامت پلاس (مانند +98) داشته باشد.

اگر جدول شما خالی باشد، تغییر نوع ستون با یک دستور ساده ALTER TABLE انجام می‌شود. اما اگر جدول حاوی داده باشد، اوراکل خطای معروف ORA-01439: column to be modified must be empty to change datatype را برمی‌گرداند. در این مقاله با یک مثال عملی یاد می‌گیریم که چطور این مشکل را بدون از دست رفتن داده‌ها حل کنیم.

مرحله ۱: ایجاد جدول تستی (همراه با اطلاعات کانال)

ابتدا یک جدول به نام customer_info می‌سازیم. در این جدول علاوه بر نام و شماره موبایل، ستونی برای آدرس کانال پیام‌رسان «بله» نیز در نظر می‌گیریم:

CREATE TABLE customer_info (
    customer_id NUMBER,
    customer_name VARCHAR2(50),
    bale_channel VARCHAR2(100),
    phone_number NUMBER
);

مرحله ۲: درج داده‌های نمونه

حالا اطلاعات نمونه را وارد جدول می‌کنیم تا جدول ما دارای داده شود:

INSERT INTO customer_info (customer_id, customer_name, bale_channel, phone_number) 
VALUES (1, 'وحید نوروزی', 'http://ble.ir/vahiddb', 09123056670);

COMMIT;

(نکته: در دیتابیس اوراکل، چون نوع ستون NUMBER است، صفر اول شماره موبایل هنگام ذخیره‌سازی نادیده گرفته می‌شود. به همین دلیل تغییر آن به VARCHAR2 ضروری است).

مرحله ۳: مواجهه با خطای ORA-01439

اگر بخواهیم مستقیماً نوع ستون را تغییر دهیم:

ALTER TABLE customer_info MODIFY phone_number VARCHAR2(20);

دلیل این خطا این است که اوراکل اجازه نمی‌دهد نوع یک ستونِ حاوی اطلاعات را مستقیماً از یک خانواده (عددی) به خانواده دیگر (رشته‌ای) تغییر دهید.

مرحله ۴: راهکار استاندارد و حرفه‌ای (در ۴ گام)

برای رفع این مشکل، باید از یک ستون موقت استفاده کنیم. این فرآیند را به ترتیب زیر اجرا می‌کنیم:

گام اول: ایجاد یک ستون موقت

ابتدا یک ستون جدید با فرمت دلخواه (VARCHAR2) می‌سازیم:

ALTER TABLE customer_info ADD phone_number_tmp VARCHAR2(20);

گام دوم: انتقال داده‌ها به ستون موقت

داده‌های عددی را به رشته تبدیل کرده و در ستون جدید کپی می‌کنیم:

UPDATE customer_info SET phone_number_tmp = TO_CHAR(phone_number);
COMMIT;
 

گام سوم: حذف ستون قدیمی

حالا که خیالتان از بابت حفظ داده‌ها راحت شد، ستون قدیمی که از نوع NUMBER بود را حذف کنید:

ALTER TABLE customer_info DROP COLUMN phone_number;

گام چهارم: تغییر نام ستون موقت به نام اصلی

در نهایت نام ستون موقت را به همان نام اصلی تغییر می‌دهیم تا ساختار جدول مثل قبل شود:

ALTER TABLE customer_info RENAME COLUMN phone_number_tmp TO phone_number;

مرحله ۵: تست نتیجه نهایی

حالا جدول ما آماده است و می‌توانیم شماره موبایل‌هایی که دارای کاراکتر هستند را بدون مشکل وارد کنیم:

INSERT INTO customer_info (customer_id, customer_name, bale_channel, phone_number) 
VALUES (2, 'کاربر جدید', 'http://ble.ir/vahiddb', '+989120000000');

COMMIT;

در صورتی که ترتیب ستونها هم برای شما اهمیت دارد، می توانید از مقاله زیر استفاده کنید:

تغییر ترتیب ستون‌ها در Oracle Database با استفاده از ویژگی INVISIBLE