PostgreSQL 'numeric field overflow' Hatası ve ERP Verisi Çözümü
Mikro ERP satış verilerini aktarırken 'numeric field overflow' hatası mı alıyorsunuz? Neden olur, nasıl çözülür, bir daha yaşamamak için ne yapmalı — basitçe anlattık.
Bu Hatayı Alıyorsanız
ERROR: numeric field overflow
DETAIL: A field with precision 10, scale 2 cannot hold a value >= 10^8
Doğru yere geldiniz. Bu hatayı gerçek bir üretim ortamında yaşadık ve çözdük.
Neden Oluşuyor?
Veritabanındaki sayı sütunları sınırlı yer tutar. NUMERIC(10,2) demek “toplam 10 basamak, 2’si virgülden sonra” demek. Yani en fazla 99.999.999,99 değerini tutabilir.
ERP verilerinde bu limit neden aşılır?
| Veri | Tutar | Sığar mı? |
|---|---|---|
| Normal satış | 15.000 TL | ✅ |
| Toptan satış | 500.000 TL | ✅ |
| Aylık ciro | 2.500.000 TL | ✅ |
| Büyük şube yıllık | 150.000.000 TL | ❌ Taşma! |
Dikkat: 7 şube sorunsuz aktarılır, ama en büyük şubede bu hata patlar. Çünkü onun yıllık cirosu limiti aşar.
Çözüm: 3 Adım
1. Sütunları Genişletin (Kalıcı Çözüm)
-- NUMERIC(10,2) → NUMERIC(18,2)
-- Artık 9.999.999.999.999.999,99'a kadar tutar
ALTER TABLE sales ALTER COLUMN amount TYPE NUMERIC(18, 2);
ALTER TABLE sales ALTER COLUMN tax_amount TYPE NUMERIC(18, 2);
ALTER TABLE sales ALTER COLUMN net_amount TYPE NUMERIC(18, 2);
Bu komut veri kaybına yol açmaz. Mevcut veriler korunur.
💡 İpucu: Tüm sayısal sütunları topluca genişletmek için:
-- Tüm NUMERIC(10,2) sütunları otomatik bul ve genişlet DO $$ DECLARE rec RECORD; BEGIN FOR rec IN SELECT table_name, column_name FROM information_schema.columns WHERE table_schema = 'public' AND data_type = 'numeric' AND numeric_precision = 10 LOOP EXECUTE format('ALTER TABLE %I ALTER COLUMN %I TYPE NUMERIC(18,2)', rec.table_name, rec.column_name); END LOOP; END $$;
2. Aktarım Koduna Güvenlik Ekleyin
Sütun genişletilse bile, aktarım kodunda değerleri kontrol etmek iyi pratiktir:
function guvenliSayi(deger, maxBasamak = 18, ondalik = 2) {
if (deger === null || deger === undefined) return null;
const sayi = parseFloat(deger);
if (isNaN(sayi)) return null;
const maxDeger = Math.pow(10, maxBasamak - ondalik) - 1;
if (Math.abs(sayi) > maxDeger) {
console.warn(`⚠️ Değer sınırlandı: ${sayi}`);
return sayi > 0 ? maxDeger : -maxDeger;
}
return parseFloat(sayi.toFixed(ondalik));
}
3. Hangi Sütunun Sorun Çıkardığını Bulun
Hata hangi sütunda olduğunu söylemiyor. Bu sorguyla kontrol edin:
SELECT column_name, numeric_precision, numeric_scale,
POWER(10, numeric_precision - numeric_scale) - 1 AS max_deger
FROM information_schema.columns
WHERE table_name = 'sales' AND data_type = 'numeric';
Hangi Precision Kullanmalı?
| Precision | Maks Değer | Ne Zaman? |
|---|---|---|
(10,2) | ~100 milyon | ❌ Çoğu ERP için yetersiz |
(15,2) | ~10 trilyon | Orta ölçek |
(18,2) | ~10 katrilyon | ✅ Önerilen |
Baştan NUMERIC(18,2) kullanın. Disk maliyeti neredeyse aynı, ama gelecekte taşma riski sıfır.
Biz Ne Yaşadık?
8 şubeli yapımızda 7 şube sorunsuz senkronize oluyordu. Sadece İzmir (en büyük şube) yıllık kümülatif tutarlarda overflow verdi. Tek şubede test etmek yeterli değil — uç değerleri hesaba katmalısınız.
Bu yazı AstaFlow Case Study serisinin bir parçasıdır.