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?

VeriTutarSığar mı?
Normal satış15.000 TL
Toptan satış500.000 TL
Aylık ciro2.500.000 TL
Büyük şube yıllık150.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ı?

PrecisionMaks DeğerNe Zaman?
(10,2)~100 milyon❌ Çoğu ERP için yetersiz
(15,2)~10 trilyonOrta ö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.