none
Veritabanına Decimal Veri Girişi Sorunu RRS feed

  • Soru

  • Herkeze merhaba.Öncelikle Sorunu ardından da hikayeyi yazıyorum. Çünkü biraz uzun.Sıkılmayın :)

    Soru : Sql serverda , farklı KÜLTÜR lere sahip makinalarda benim istediğim kültüre göre işlem yapmasını nasıl sağlayabilirim. Veritabanının ayarlarından böyle bişey yapmak söz konusu mu?Eğer yapabiliyorsak bu benim için en kestirme ve en garanti çözüm.

    Not:Teklifi kaydetmek için ajax ile verileri jsonresult metoduma yolluyorum.ajax ile yollamadan önce consola bastırdığımda ToplamTutar: "0,09" değerini görüyorum. Metot tarafında ise  Convert.ToDecimal(ToplamTutar); işlemi ile gelen string değeri decimala çevirip veritabanına kayıt yaptırıyorum. Belkide Convert.ToDecimal(ToplamTutar); satırında 9,00 değerine dönüştürüyor. bunu da bilemiyorum.Belkide buradaki kültür ayarlarına bakmalıyım. Ancak haliyle debug yapamıyorum.Çünkü müşterinin serverı.

    Olay örgüsü:

    Asp.net mvc ile geliştrimekte oldugum bir web yazılım var. Sql server 2014'de de veritabanını barındırıyorum.Uygulamayı publish edip müşterimin serverına kuruyorum.Kendi local imde yada denediğim 5 farklı pc de sorun olmuyor (denediğim pcler arasında windows server 2012 de var).Ancak müşterimin serverindeki sorun şu:

    Bir web sayfası düşünün. bu web sayfasında 3 adet dolma kalem için 0,09 tl teklif veriliyor.Yani tanesine 0,03 tl teklif veriliyor.

    Toplamda 0,09  olması gereken toplam fiyat 9,00  olarak veritabanına kaydoluyor. Bu normalin  100katı. Ancak bu sorun sadece müşterimin serverında.Diğer 5 farklı makineye kurduğumda gayet doğru ilerliyor.

    Bir diğer dikkat etmem gereken konu da müşterimin makinasında dil yada coğrafya ayarlarını değiştiremiyorum. Bu işleme izin vermiyorlar çünkü başka yazılımlarda var mevcut sistemde.Akla veritabanının istediği şekilde verileri yollamak gelsede bu benim için çok uzun bir işlem.bütün kodları tekrar elden geçirmek gibi birşey.Kaldı ki sorun sadece bu da değil.bazen veritabanına kayıt yapıyor bazense yapmıyor catch e düşüyor.hiç bir neden yokken???.Yani kod tarafında herhangi bişey değiştirmeden , sql serverdaki veritabanıma yukarıda kalın harflerle belirttiğim 0,09 şeklinde kayıt girebilmem şart.Düzgün çalışan veritabanımın properties bilgilerini gerekirse paylaşabilirim. Collation olarak Turkish_CI_AS ayarlı müşterimde de.Benim veritabanım ve müşterime kurduğum veritabanı arasında fark göremedim.veritabanını da sql script ile kopyalıyorum data ve şemasıyla.Sadece ilk oluştururken veritabanını ve yolunu kendim NEW DATABASE diyerek oluşturuyorum.Oluşan veritabanını kontrol ettiğimde bendeki gibi decimal(24, 6) olduğunu görüyorum

    Önerilerinizi bekliyorum :)




    • Düzenleyen carg2626 28 Haziran 2016 Salı 00:18
    27 Haziran 2016 Pazartesi 17:36

Yanıtlar

  • Tahminlerime göre sorunu %95 çözdüm.

    <configuration>
        <system.web>
            <globalization uiCulture="en-GB" culture="en-GB" />
        </system.web>
    </configuration>

    satırlarını düzenledikten sonra sorunun çözüleceğine inanıyorum.Tabii bunu müşterimin yanına gidip denediğimde öğrenmiş olacağım.Yukardaki sorumun cevabıda bu oluyor. bu kültür varsayılan kültürün anlamına geliyor.benden sonra gelenlere kaynak olsun diye yazıyorum.

    • Yanıt Olarak İşaretleyen carg2626 28 Haziran 2016 Salı 01:55
    • Yanıt İşaretini Geri Alan Önay YALÇINERModerator 28 Haziran 2016 Salı 09:40
    • Yanıt Olarak İşaretleyen carg2626 29 Haziran 2016 Çarşamba 18:54
    28 Haziran 2016 Salı 01:55

Tüm Yanıtlar

  • Olayi bastan sakat yapmasan hic sorunun olmazdi, yani bastan sadece parametre kullansan ve degerlerini string yerine normal degerleri neyse oyle kullansaydin keske (tarih icin DateTime, para icin decimal ...). Madem bir hata yapiyorsun ve yapmaya devamda israrlisin o zaman SQL server 2012 ve sonrasinda Parse ve Try_Parse var, onlarda kultur kullanabiliyorsun:

    select try_parse('0,09' as money using 'tr-TR');

    27 Haziran 2016 Pazartesi 18:36
    Yanıtlayıcı

  • Naçizane önerilerinizi bekliyorum...



    Naçizane kelimesinin anlamına bakar mısın sözlükten?...
    27 Haziran 2016 Pazartesi 18:52
  • Çok küçük anlamında da kullanıldığını biliyorum.Ben "az da olsa" anlamında kullanmıştım. Ezberimde yanlış kalmış.Haklısınız.
    28 Haziran 2016 Salı 00:20
  • Olayi bastan sakat yapmasan hic sorunun olmazdi, yani bastan sadece parametre kullansan ve degerlerini string yerine normal degerleri neyse oyle kullansaydin keske (tarih icin DateTime, para icin decimal ...). Madem bir hata yapiyorsun ve yapmaya devamda israrlisin o zaman SQL server 2012 ve sonrasinda Parse ve Try_Parse var, onlarda kultur kullanabiliyorsun:

    select try_parse('0,09' as money using 'tr-TR');

    Çetin hocam dediğinizi tam anlamadım.Entity framework kullanıyorum.ve bahsettiğiniz şekilde veritabanındaki alan decimal. Sınıfımda ise

     public decimal TUTAR { get; set; }

    şeklinde özellik var.Kodlarımda ise şöyle:

    var p = new teklifler();
    p.TUTAR = Convert.ToDecimal(item.Tutar);
    db.teklifler.Add(p);
    db.SaveChanges();

    JavaScriptSerializer ile gelen json stringini teklifler türünden serialize edip item.Tutar şeklini aldırıyor.sonra kayıt ettiriyorum.Ne yapmam gerektiğini anlamadım .

    28 Haziran 2016 Salı 00:41
  • Bu linkden de anladığımız gibi

    https://msdn.microsoft.com/tr-tr/library/9k6z9cdw(v=vs.110).aspx

     kültüre göre convert işlemlerinde farklılıklar oluyor. benim tekbir noktadan kültür belirtip:

    CultureInfo[] cultures = { new CultureInfo("en-US") };

    bu kültürü heryerde kullan deme şansım var mı acaba?

    28 Haziran 2016 Salı 01:19
  • Tahminlerime göre sorunu %95 çözdüm.

    <configuration>
        <system.web>
            <globalization uiCulture="en-GB" culture="en-GB" />
        </system.web>
    </configuration>

    satırlarını düzenledikten sonra sorunun çözüleceğine inanıyorum.Tabii bunu müşterimin yanına gidip denediğimde öğrenmiş olacağım.Yukardaki sorumun cevabıda bu oluyor. bu kültür varsayılan kültürün anlamına geliyor.benden sonra gelenlere kaynak olsun diye yazıyorum.

    • Yanıt Olarak İşaretleyen carg2626 28 Haziran 2016 Salı 01:55
    • Yanıt İşaretini Geri Alan Önay YALÇINERModerator 28 Haziran 2016 Salı 09:40
    • Yanıt Olarak İşaretleyen carg2626 29 Haziran 2016 Çarşamba 18:54
    28 Haziran 2016 Salı 01:55
  • JSON ile sana string degil normal sayisal deger gelir. Stringe cevirmekten vazgec, sorunun ortadan kalkar.

    Illa stringlerle ugrasacaksan, decimal.TryParse() kultur destekliyor.

    28 Haziran 2016 Salı 08:47
    Yanıtlayıcı
  • kültürel farklılıklardan dolayı oluşan hataları yaratmak için extra çaba göstermek gerekir. Siz MVC'yi ne hale soktuysanız artık 0,09 u 9 kaydetmişiniz. web.config ile culture belirtmekle , "aman ben kendimi kurtarayım da, kullanıcı ne halt yerse yesin" anlamında bi önlem almışsınız. Özet bu.

    e-mail: onay[nokta]yalciner[at]hotmail[nokta]com

    28 Haziran 2016 Salı 09:45
    Moderatör
  • kültürel farklılıklardan dolayı oluşan hataları yaratmak için extra çaba göstermek gerekir. Siz MVC'yi ne hale soktuysanız artık 0,09 u 9 kaydetmişiniz. web.config ile culture belirtmekle , "aman ben kendimi kurtarayım da, kullanıcı ne halt yerse yesin" anlamında bi önlem almışsınız. Özet bu.

    e-mail: onay[nokta]yalciner[at]hotmail[nokta]com

    Beyfendi siz ya beni anlamadınız.Yada ben kendimi anlatamadım.Kültürel hataları yaratmak için çaba sarfetmedim.Müşterimin bilgisayarı tr-TR kültüründe değil zaten en-EN kültüründe.MVC'yi hallere soktuğum yok.Benim yazdığım uygulama türk kültürüne göre tasarlanmış.Kullanıcıların mevcut sorununu çözüp türk kültürüne ayarlamak istemem mi "aman ben kendimi kurtarayım da, kullanıcı ne halt yerse yesin" oluyor?
    28 Haziran 2016 Salı 12:13
  • Sayisal degerlerde kulturel farklilik yoktur. Sorunu bastan yaratmamalisiniz. 
    28 Haziran 2016 Salı 12:18
    Yanıtlayıcı
  • Sayisal degerlerde kulturel farklilik yoktur. Sorunu bastan yaratmamalisiniz. 
    Dediğinizi anladım Çetin hocam.En başında string olarak yollamazsan sıkıntı olmaz diyorsunuz.Projeyi başkasından devraldığım zamanlarda böyle yapılmış bir hareket.serialize ederek hepsini string olarak jsonla yollamış arkadaş.bende mecburen sistemin üzerine devam etmek zorunda kaldım.birçok yerde serialize yapılarak gönderildiğinden değiştirilecek vakit yok.Önerileriniz için çok teşekkür ederim.
    28 Haziran 2016 Salı 14:45
  • JSON'in kendisi string, o tamam da, icerisindeki degerleri de mi hep gosterim formatlarina cevirip string yapmis? Oyleyse cok zor durumdasin. Bence, config ile oynama. Onun yerine madem yapacak birsey yok, decimal.TryParse kullan:

    decimal deger;
    if (decimal.TryParse("0,09", NumberStyles.Any, new CultureInfo("tr-TR"), out deger))
    {
       // ...	   
    }
    

    28 Haziran 2016 Salı 15:16
    Yanıtlayıcı
  • JSON'in kendisi string, o tamam da, icerisindeki degerleri de mi hep gosterim formatlarina cevirip string yapmis? Oyleyse cok zor durumdasin. Bence, config ile oynama. Onun yerine madem yapacak birsey yok, decimal.TryParse kullan:

    decimal deger;
    if (decimal.TryParse("0,09", NumberStyles.Any, new CultureInfo("tr-TR"), out deger))
    {
       // ...	   
    }

    Çetin hocam " icerisindeki degerleri de mi hep gosterim formatlarina cevirip string yapmis?" cümlesinden ne demek istediğinizi anlamadım. serialize gelen veriden bahsediyorsanız eğer evet hepsi string. daha sonra o stringi deserialize edip classımın özelliklerine aktarıyorum. sonrasında convert işlemi oluyor. Dün bahsettiğim sorunu config deki kültür ayarlamasıyla düzelttim.convert işlemini tr kültüründe olmadığı için farklı yapıyormuş.şimdi sorun ortadan kalkı zaten. Yardımlarınız için teşekkür ederim.
    29 Haziran 2016 Çarşamba 18:53
  • Serialize kısmı yanlış o zaman. Serialize herhangi bir kültüre göre yapılmaz.

    e-mail: onay[nokta]yalciner[at]hotmail[nokta]com

    29 Haziran 2016 Çarşamba 19:58
    Moderatör
  • Cozmussun de, ben ne dedigime aciklik getireyim.

    {
      "id": 1,
      "fiyat": 123.40,
      "deger2" : "123,40"
    }
    Bu bir JSON. Icinde id ve fiyat sayisal degerler ve net olarak, 1 ve 123.40. deger2 ise string. Sayi olarak dusunmeye kalkarsak, ne oldugu belirsiz. 

    29 Haziran 2016 Çarşamba 19:59
    Yanıtlayıcı
  • Önay bey serialize kısmı doğru. Çünkü formdan gönderdiğim veriyi debug kısmında baktığımda.Gelen veri doğru.Sadece kültüre bağlı konvert işleminden kaynaklanan sorun vardı onu dün hallettim.Şimdi farklı bir sorun ortaya çıktı onuda farklı konu açmakdansa bu konu üzerinden devam ettirmek istedim.bu seferki sorun resimlerle belirttiğim gibi veritabanındaki decimal değeri çekerken bana farklı getirmesi.
    • Düzenleyen carg2626 29 Haziran 2016 Çarşamba 21:24
    29 Haziran 2016 Çarşamba 21:22
  • Resim goremedim. Farkli derken, nasil farkli? 

    Not: Serialize isleminde, eger decimal string olarak serialize ediliyorsa dogru denemez. Sayisal degerler kultur bagimli degildir.

    29 Haziran 2016 Çarşamba 22:31
    Yanıtlayıcı
  • Hocam resimli olan yanıtlarımı silip yeni konuya taşıdım.Arayanlar daha rahat bulsun diye.Farklı bir sorun çünkü.Link:

    https://social.msdn.microsoft.com/Forums/tr-TR/8f81f685-5872-4730-a0f6-6529894d4c9e/sql-veritabanndan-decimal-veri-ekme-sorunu?forum=csharptr

    Not: Evet serialize işleminde decimaller de string olarak gidiyor.Önay bey de bundan bahsetmişse eğer haklıymış.Doğru olmadığı konusuna katılıyorum.Ancak sorun zaten çözüldü.proje ilk başlangıçda böyle ilerlediği için bende üzerine bu şekilde devam edip konvert işlemi uyguladım.
    • Düzenleyen carg2626 29 Haziran 2016 Çarşamba 22:42
    29 Haziran 2016 Çarşamba 22:39
  • Valla proje senin, sen bilirsin ama bir sey yanlis baslamis diye yanlisi devam ettirmek bana pek akillica gelmiyor.
    29 Haziran 2016 Çarşamba 22:56
    Yanıtlayıcı
  • Haklısınız hocam yanlışın üzerine yanlış ilerlemek doğru bi iş değil.Ancak abartılacak kadar büyük bir problem olmadığı düşüncesinde olduğum için değişiklik işlemini gözüm yemiyor :) 
    29 Haziran 2016 Çarşamba 23:18