SQL tabloda sayısal değer alanı update edildiğinde ondalık basamak problemi

Delphi'de kod yazma ile ilgili sorularınızı bu foruma yazabilirsiniz.
Cevapla
mmg
Üye
Mesajlar: 120
Kayıt: 20 Haz 2014 12:47

SQL tabloda sayısal değer alanı update edildiğinde ondalık basamak problemi

Mesaj gönderen mmg »

Merhabalar,
Öncelikle herkese kolay gelsin. Yine saçma sapan aynı zamanda çok anlamsız ve bazı değerlerde problem yapan bazı değerlerde yapmayan istikrarsız bir problem ile karşı karşıyayım. Delphi 10.2 ve SQLExpress kullanıyorum. Aşağıda görülen kod bloğu le "StokHareket" tablosundan stok kartlarına ait depo giriş ve çıkış hareketlerini okuyup stok ve depo bazında "StokMizan" tablosuna update sql ile "CIKANMIK" alanına mevcut değerin üzerine toplayarak yazıyorum. Aşağıda koda baktığınızda bu dediğimi zaten hemen göreceksiniz. "CIKANMIK" alanının başlangıç değeri 0 (Sıfır) ve alan tipi "Float".

StokHareket tablosudan gelen değerler ve "CIKANMIK" alanının aldığı değerler :
1. Değer 18 --> CIKANMIK değeri = 18 Oluyor, doğru.
2. Değer 15.56 --> CIKANMIK değeri = 33.56 Oluyor, doğru.
3. Değer 6.2 --> CIKANMIK değeri = 39.760000000000005 Oluyor, işte burada çıkamıyorum işin içinden.
4. Değer 13.1 --> CIKANMIK değeri = 52.860000000000007 şeklide devam ediyor.

Yukarıda tabloda anlatmaya çalıştığım gibi 6.2 değeri gelene kadar "StokMizan" tablosunda "CIKANMIK" değeri doğru toplanıyor fakat 6.2 geldikten sonra saçmalıyor. "StokMizan" tablosunda "CIKANMIK" alanının değeri 39.76 olması gerekirken, 39.760000000000005 gibi bir değer oluyor. "StokMizan" tablosuna "StokHareket" tablosundan okuduğum değerleri "FormatFloat('0.00',StokHareketMIKTAR.Value)" fonksiyonu ile yuvarlayarak yazıyorum. Ayrıca 15.56 yı 18'in üzerine doğru topluyor ama neden 6.2'ye gelince saçmalıyor ? Bunu başka değerlerde başka stoklarda da yapıyor. Bu benim sizinle paylaştığım sadece 1 örnek. İşin içinden bir türlü çıkamadım. Acil yardımlarınızı rica ediyorum.

Kod: Tümünü seç

StokHareket.Open;
while Not StokHareket.Eof do
begin
   StokMizan.Close;
   StokMizan.SQL.Clear;
   StokMizan.SQL.Add('UPDATE STOKMIZAN SET CIKANMIK= (CIKANMIK + :vCIKANMIK)');
   StokMizan.SQL.Add('WHERE STOK_NO=:vSTOK_NO AND DEPO=:vDEPO');
   StokMizan.Parameters.ParamByName('vSTOK_NO').value:= StokHareketSTOK_NO.Value;
   StokMizan.Parameters.ParamByName('vDEPO').value:= StokHareketDEPO.Value;
   StokMizan.Parameters.ParamByName('vCIKANMIK').Value:= StrToFloat(FormatFloat('0.00',StokHareketMIKTAR.Value));
   StokMizan.ExecSQL;
   StokMizan.Close;

   StokHareket.Next;
end;
En son mmg tarafından 09 Tem 2020 12:51 tarihinde düzenlendi, toplamda 1 kere düzenlendi.
Kullanıcı avatarı
freeman35
Admin
Mesajlar: 2357
Kayıt: 12 Haz 2003 04:05
Konum: merkez camii yanı

Re: SQL tabloda sayısal değer alanı update edildiğinde ondalık basamak problemi

Mesaj gönderen freeman35 »

Bunu neden triger yapmıyorsun?
ParamByName('vCIKANMIK').Value:= FormatFloat('0.00',StokHareketMIKTAR.Value);
zaten variant olana değere başka bir variant ı hemde formatlattırıp göndermek bana son derece manasız geldi.
ZAGOR TENAY TÜRK'tür... TÜRK kalacak...
Zoru başarırım, İmkansız zaman alır
FreeMan 35.5

Soru sormaya üşenmiyorsan, sorunun çözümünü yazmaya da üşenme !!!
mmg
Üye
Mesajlar: 120
Kayıt: 20 Haz 2014 12:47

Re: SQL tabloda sayısal değer alanı update edildiğinde ondalık basamak problemi

Mesaj gönderen mmg »

Miktarsal alanları ondalık basamak olarak 2 digit tutulması gerekiyor database'de. Yani şöyle düşün derim, "miktar * fiyat" işleminden çıkan değerin ondalık basamak sayısı 8 digit olabilir ama ben sadece 2 digitini alıp yuvarlayıp table'da saklamak istiyorum. Bu durumda table'a veriyi serbest gönderemem sanırım. Benim bildiğim başka bir yöntemi yok. Varsa paylaşırsanız sevinirim.
Kullanıcı avatarı
mussimsek
Admin
Mesajlar: 7588
Kayıt: 10 Haz 2003 12:26
Konum: İstanbul
İletişim:

Re: SQL tabloda sayısal değer alanı update edildiğinde ondalık basamak problemi

Mesaj gönderen mussimsek »

SQL Server tarafında bu işi Round ile yapabilirsiniz.

Round(CIKANMIK, 2)

şeklinde değer ataması yaparsanız veya raporda bu şekilde çekerseniz, küsuratı 2 hane olarak getirir. Float değerlerde SQL Server bazen böyle yapıyor ama tabloda bilmem kaçıncı basamakta ufak bir fark olması sıkıntı değil. Siz, kullanıcıya 2 hane gösterseniz yeterli.

Kolay gelsin.
mmg
Üye
Mesajlar: 120
Kayıt: 20 Haz 2014 12:47

Re: SQL tabloda sayısal değer alanı update edildiğinde ondalık basamak problemi

Mesaj gönderen mmg »

Anladım mussimsek hocam, teşekkürler, iyi çalışmalar.
mmg
Üye
Mesajlar: 120
Kayıt: 20 Haz 2014 12:47

Re: SQL tabloda sayısal değer alanı update edildiğinde ondalık basamak problemi

Mesaj gönderen mmg »

Mustafa hocam, sanırım Round fonksiyonunu Round(CIKANMIK,2) Olarak kullanamıyoruz, Round(CIKANMIK) kullanabiliyoruz. RoundTo(CIKANMIK,2) Şeklinde kullanabiliyoruz. Fakat RoundTo() fonksiyonu da sanırım bizim istediğimiz gibi çalışmıyor. Bu nedenle ben table'a kaydederken yuvarlama işlemi için FormatFloat('0.00',DEGER) fonksiyonunu kullanmışım. Küçük küsuratlar muhasebe mizanında veya farklı yerlerde sorun olabiliyor. Örneğin muhasebe mizanı alıyorsunuz borç alacak arasında 0.08 krş luk fark çıkıyor. Ben sayısal değerleri istediğim ondalık basamak sayısı ile yuvarlama yaparak kaydetmek istiyorum. Örneğin muhasebe fişi borç tutarı 1000.58 TL ise table'da da aynı şekilde olmasını istiyorum, 1000.58000006 olmasın. Bunu nasıl sağlayabilirim ? Herkes bunu nasıl yapıyor ?
Kullanıcı avatarı
sabanakman
Kıdemli Üye
Mesajlar: 3077
Kayıt: 17 Nis 2006 08:11
Konum: Ah bi Antalya olaydı keşke (Ankara)

Re: SQL tabloda sayısal değer alanı update edildiğinde ondalık basamak problemi

Mesaj gönderen sabanakman »

SQL fonksiyonu "UPDATE STOKMIZAN SET CIKANMIK= Round(CIKANMIK + :vCIKANMIK, 2)" şeklinde kullanabilirsiniz. Yalnız alan tipiniz float galiba. Bu arada derinlerde kalan küçük farklara çok takılmayın, tavsiyem yuvarlamaları özel ince ayar çekmek dışında kullanılmaması gerektiğidir.
Şaban Şahin AKMAN
_________________
Derin olan kuyu değil kısa olan iptir. - .
mmg
Üye
Mesajlar: 120
Kayıt: 20 Haz 2014 12:47

Re: SQL tabloda sayısal değer alanı update edildiğinde ondalık basamak problemi

Mesaj gönderen mmg »

sabanakman yazdı: 09 Tem 2020 06:25 SQL fonksiyonu "UPDATE STOKMIZAN SET CIKANMIK= Round(CIKANMIK + :vCIKANMIK, 2)" şeklinde kullanabilirsiniz. Yalnız alan tipiniz float galiba. Bu arada derinlerde kalan küçük farklara çok takılmayın, tavsiyem yuvarlamaları özel ince ayar çekmek dışında kullanılmaması gerektiğidir.
Şaban Hocam, update sql'i dediğiniz gibi düzenleyince doğru olarak round etti. Teşekkür ederim yardımınız için. Fakat sormak istediğim bir kaç husus var bu konu ile alakalı olarak.
sabanakman yazdı: 09 Tem 2020 06:25 "Yalnız alan tipiniz float galiba" demişsiniz, burada bir öneriniz veya görüşünüz mü olacak acaba ?
Float yerine başka bir tip mi kullanmalıydım ?
sabanakman yazdı: 09 Tem 2020 06:25 "Bu arada derinlerde kalan küçük farklara çok takılmayın, tavsiyem yuvarlamaları özel ince ayar çekmek dışında kullanılmaması gerektiğidir."
Demişsiniz, değerleri table'a olduğu gibi mi göndermeliyim ? örneğin fatura dip tutarı ondalık basamak sayısı 2 digit olmalı, 10.2547*10= 102.547 yapar fakat table'da 102.55 kaydedilmesi gerekiyor. Bunu size göre table'a 102.547 olarak kaydedip programda ilgili ekranlarda ve raporlarda 102.55 olarak mı görüntülemeliyim ?

Ayrıca bu round(değer,2) şeklinde update sql de kullanabildim fakat diğer işlemlerde kullanamıyorum, hata veriyor.

Örneğin şunu dahi diyemiyorum;
deger1,deger2: double;

deger1:= 124.245
deger2:= round(deger1,2)

şeklinde kullanamıyorum,

Kod: Tümünü seç

[dcc32 Error] kod.pas(3954): E2029 ')' expected but ',' found
hatasını veriyor. Bunun sebebi ne olabilir ?
Kullanıcı avatarı
mussimsek
Admin
Mesajlar: 7588
Kayıt: 10 Haz 2003 12:26
Konum: İstanbul
İletişim:

Re: SQL tabloda sayısal değer alanı update edildiğinde ondalık basamak problemi

Mesaj gönderen mussimsek »

Hocam her programda bu tarz farklılıklar olabiliyor. Muhasebe tarafı bunu "YUVARLAMA FARKLARI" diye bir hesaba atıyor.

Kolay gelsin.
Kullanıcı avatarı
freeman35
Admin
Mesajlar: 2357
Kayıt: 12 Haz 2003 04:05
Konum: merkez camii yanı

Re: SQL tabloda sayısal değer alanı update edildiğinde ondalık basamak problemi

Mesaj gönderen freeman35 »

benim tavsiyem db deki veri ham veri olarak kaydedilmeli. Rapor alınacağında, ekrana TField üzerinde format verilerek basım aşamasında formatlamak hassasiyet açısından en mantıklı çözümdür. İaşe programımda, ondalık kısım iki hane iken yıl ortasında hassasiyet için 4 dört hane istediler. sadece formatları değiştirdim, hiç bir değer kaybı olmadı.
ZAGOR TENAY TÜRK'tür... TÜRK kalacak...
Zoru başarırım, İmkansız zaman alır
FreeMan 35.5

Soru sormaya üşenmiyorsan, sorunun çözümünü yazmaya da üşenme !!!
ertank
Kıdemli Üye
Mesajlar: 1657
Kayıt: 12 Eyl 2015 12:45

Re: SQL tabloda sayısal değer alanı update edildiğinde ondalık basamak problemi

Mesaj gönderen ertank »

mmg yazdı: 09 Tem 2020 11:05 Float yerine başka bir tip mi kullanmalıydım ?
Özellikle parasal işlemlerde sistemler arası, işlemciler arası, uygulamalar arası yuvarlama farklılıkları oluşmasını engellemek amacı ile sabit ondalık sayısına sahip birkaç veri türü üretildi.

Yeni nesil ÖKC gibi mali yazarkasalardan bazıları ondalık kaybını engellemek için tüm işlemlerin 100 ile çarpılarak (ondalık değer olmadan tamsayı şeklide kullanılarak) yapılmasını şart koşar.

Veritabanlarında yuvarlama farklarını engellemek için veya sabit ondalık değere sahip veriler saklamak için aşağıdaki veri türleri kullanılabilir. Ancak bu veri türleri her veritabanı tarafından desteklenmiyor olabilir. Bazı veritabanları aynı işi yapan veri türünün adını farklı tanımlamış olabilir. Aşağıdaki bilgiler SQL Server için geçerlidir.

DECIMAL:
DECIMAL(UZUNLUK, ONDALIK_UZUNLUGU): parantez içinde maksimum hane sayısı ve bu hane içindeki ondalık sayısını belirtirsiniz. Örneğin;
DECIMAL(5,2) şeklindeki bir ifade 123.45 şeklinde verileri kayıt edecektir. Maksimum saklanabilecek değer 999.99 olacaktır. Gerekli hallerde yuvarlamaları sistem yapacaktır. Yani siz 123.345 şeklindeki bir veriyi yukarıdaki gibi tanımlanmış bir alana kayıt etmek istediğinizde 123.35 şeklinde kayıt edilecektir (SQL Server 2012 sürümü test sonucudur). Sorgulama sonuçları herhangi bir dönüşüme ve yuvarlamaya gerek kalmadan 123.35 şeklinde gelecektir.

Diğer taraftan 100 tamsayı kayıt edildiğinde sorgu sonucu 100.00 şeklinde gelecektir. Yani ondalık hane sayısı mutlaka sorgu sonucunda gösterilecektir. Eğer ondalık hane sayısı 5 olarak belirlenmiş ise bu defa 100.00000 şeklinde bir sorgu sonucu görürsünüz.
Detaylı bilgi için: https://docs.microsoft.com/en-us/sql/t- ... rver-ver15

NUMERIC:
Adının farklı olması dışında tamamen DECIMAL ile aynıdır. NUMERIC ve DECIMAL ifadeleri birbirinin yerine kullanılabilir.

MONEY:
MONEY: Sabit olarak ondalıktan sonra 4 hane şeklinde kayıt eder. Sizin kullanımınıza uygun olmamakla birlikte farklı kullanım alanı olabileceği için ekledim.
Detaylı bilgi için: https://docs.microsoft.com/en-us/sql/t- ... rver-ver15
mmg
Üye
Mesajlar: 120
Kayıt: 20 Haz 2014 12:47

Re: SQL tabloda sayısal değer alanı update edildiğinde ondalık basamak problemi

Mesaj gönderen mmg »

ertank hocam, bu güzel ve değerli bilgilendirme için çok teşekkür ediyorum. Havada kalan çok şey yerine oturdu.
Cevapla