SQLServer’da “aritmetic overflow” hatası


SQLServer’da decimal sayı tanımlamalarında zaman zaman bu hatayla karşılaşılır. Rahat olun suçlu microsofttur. DECIMAL(10,2) demek virgülden ÖNCE 10-2=8 hane demek oluyor. Yani cins adamlar onlarca yazılım dilinde bu iş için daha kolay tanım varken neden yazılımcıya eziyet edersin:)

Şimdi aşağıdaki koda bakalım:

declare @t table (long decimal(10,6))

insert into @t VALUES (1000.0),(999.99),(11111.99)

SQL Server burada 11111.99 değerine kadar her şeyi düzgün insert ederken yukarıda tablo kolonu t değerini etmez çünkü virgülden önce 4’ten fazla hane var. Bu kodda decimal(10,6) kısmını long decimal(11,6) olarak değiştirirseniz kodunuz çalışacaktır.

Tecrübe 3: DECLARE kısımlarında tanımladığınız tiplere dikkat.

Reklamlar

Int, Float, Double, Decimal… Yazılım’a giriş dersi neden önemlidir.


Yazılım’a giriş derslerinde her nedese ‘String’den önce hep sayısal değerler öğretilir. Hep de hızla geçilir. Integer akılda kalır, float ve decimal farkı hatırlanmaz. Ama gün gelir, parayla pulla ilgili bir uygulamayı yazar/geliştirsiniz işte orada küsüratlar kuruşlar değerli hale geldiğinde ilk derslerde duyduğunuz/okuduğunz şeyler durumu değiştirir.

Hikaye şuradan başlıyor: Daha önce C#‘da hazırlanmış ve parasal işlemlerle ilgili epey kompleks süreçler yürüten kodların veritabanıyla çok ilişkisi olması gerekçesiyle SQL Stored Procedure ile yeniden yazılmıştı.Yazılan bu kodlarda daha önce C#’da float olak tanımlanmış parasal değerler SQLServer’daki Stored Procedure’ler içinde yeni kodlarımızda Decimal(18,6) şeklinde tanımlanmıştı.

Günün birinde, Decimal(18,6)’nın float olmadığını gördük:) Saçma gelebilir ancak kodlarımızda C# tarafında diyelim ki 5.20 gelen (tabii ki 5.19 da gelecek) float değerlerin SQL Stored Procedure tarafında 5.2 olarak hesaplandığını gördük. Sonra da çözümü bulduk.

Biraz da modifiye ederek şu iki satırla öğrendik:


declare @x as float(24);

set @x = 7376.628 - 199.01 - 46.63
--set @x = @x - 199.01 - 46.63

select convert(decimal(10,6),@x)


Yukarıdaki kodları siz de deneyebilirsiniz. float değerinden 24 parametresini kaldırdığınızda ‘küsüratların intikamını’ görebilirsiniz.

Tecrübe: Sayısal değer tiplerini adam yerine koyun:)

Tecrübe 2: SQLServer’da da float var:) Hatta money tipi var.

SQL Server’da süper hızlı arama eklentisi


SQLServer’da bazen işler kolay olmaz. Çok fazla sayıda tablo,view, stored procedure ve fonksiyon olduğu zamanlarda şu kolon neredeydi diye aramak isteyebilirsiniz. Bunun için SQLServer herhangi bir araç sunmaz. Ancak bunun yerine bir ücrtesiz eklenti var. Bu eklenti ile tüm SQL veritabanınızda istediğiniz ifadeyi ‘şak’ diye blursunuz.

Eklentinin adı: SQLSearch
URL: http://www.red-gate.com/products/sql-development/sql-search/

Görüntü:

SQL’de INNER, LEFT ve OUTER JOIN farkı


Bu farkı anlamak için şu senaryo üzerinden gidelim (senaryoyu ilk yazan kişi BradC’dir, stackoverflowdan bakmak için tıklayın) .

Bu senaryoyu görselleştirerek daha kolay anlaşılabilir hale getirdim.

Senaryo şöyle:

100 öğrenci var.

50 dolap var.

70′inin dolabı var.

Dolaplardan bazılarını bir kaç öğrenci birden kullanıyor. (40 dolap müşterek)

Bazı dolapları ise kimse kullanmıyor (10 dolap komple boş)

Böyle bir durumda:

Sadece dolabı olan öğrencileri

Tüm öğrencileri (dolabı olanlar dahil)

Tüm dolapları (boşlar dahil)

nasıl listeleriz?

Cevaptaki ifadeler yerine şu çizimi yaptım:

image

Gördüğünüz gibi;

INNER JOIN: Kesişim kümesini verir sadece dolap kullanan öğrencileri döndürür 70 öğrenci gelir.

LEFTJOIN: Hem dolap kullanmayan öğrencileri hem de kullananları döndürür 100 öğrenci döner.

RIGHT JOIN ise boş dolaplar dahil tüm dolapları döndürür.

Daha kompleks JOIN komutları da var. Şurada:

image

ASP.MVC Code First Many-to-Many (Çok-Çok) Tablo ilişkisi Kurma


İki tablomuz var: Projects ve Employee (çalışan). Bir çalışan birden fazla projede yer alabilir, bir projede birden fazla çalışan yer alabilir. Dolayısıyla tablolar araası ilişki many-to-many (çok-çok) ilişkisi.

1-Bunu Code First mimarisi içinde şöyle tanımlarız:


public class Employee
{

    public int EmployeeID { get; set; }
    public string Name { get; set; }
    //Navigational Property
    public virtual ICollection Projects { get; set; }
}


public class Project
{

    public int ProjectID { get; set; }
    public string Name { get; set; }
    //Navigational Property
    public virtual ICollection Employees { get; set; }

}

2-Daha sonra scaffolding yaparı. Bu durumda veritabanında otomatik olarak bu iki tablo ve bir de many-to-many ilişkisini birbirine bağlamak için kesiştirme tablosu (junction table) oluşur.

3-Normalde one-to-many ilişkisinde scaffolding yapılınca view tarafında size iş kalmaz neredeyse. Ancak bu örnekte henüz view tarafında formda örneğin projenin ilgili olduğu çalışanları seçme işlemini yapacak multiselect dropdownu hazırlamak bize kalıyor. Nitekim en azından şimdilik bunu otomatik olarak yapabilecek bir sistem bulunmuyor. (Şu makale söyledi: https://blogs.msdn.microsoft.com/mcsuksoldev/2013/09/20/managing-entity-relationships-with-mvc-scaffolding/)

ASP.MVC Tablolar Arası İlişkiler ve Scaffolding


Bir blogumuz olsun bu blogda BlogPost’lar blogumuzdaki kayıtlar olsun. Her kayda ait sadece bir kategori olabilir.
Bu durumda bir kategoride her zaman birden fazla içerik olabilir. Bu durumda istediğimiz formda blogun başlığı yanında kategori seçmemiz için bir dropdown gerekecektir. Bunu ASP.MVC ile en hızlı şekilde nasıl yapabiliriz?

En kısa yol şudur:

1-Model Classını yaz:

public class BlogPost
{
[Key]

    public int ID { get; set; }
    public string title { get; set; }
    public string entry { get; set; }
    public int CategoryID { get; set; }
    public virtual Category Category { get; set; }

}


public class Category

    [Key]
    public int CategoryID { get; set; }
    public string CategoryName { get; set; }
   //virtual'a dikkat
    public virtual IEnumerable BlogPosts { get; set; }

}

2-Projeyi sağ tıkla Add->New Scaffolded Item de. Sonda ise 2. seçeneği (Entity Framework ifadesini içeren) seç. Scaffoldingi bekle

Dropdownu da içeren viewler hazır olacaktır.

Bu arada ViewBag üzerinden dropdown elemanı doldurulmaz diyen üstatlara selam olsun. Visual Studio bile bu iş için ViewBag kullanıyor:

View Tarafı:


@Html.DropDownList("CategoryID", null, htmlAttributes: new { @class = "form-control" })

Controller tarafı:

ViewBag.CategoryID = new SelectList(db.Categories, “CategoryID”, “CategoryName”, blogPost.CategoryID);

Bunun dışında da bazı yöntemler mevcut. Bunlardan biri ile ilgili olarak StackOverFlow’da soru sormuş ve güzel bir cevap almıştım. Okumak için burayı tıklayın

Yaptığımız şey one-to-many tablo ilişkisidir.

SQL Inner Join nedir,nasıl kullanılır?


Tablo 1:
ReferansTablo
OkulNo,Ad,Soyad
21,Suat,Atan
65,Agah,Atan

Tablo 2:
NotTablosu
OkulNo,Not
21,98
65,100

Şimdi Tablo 2’de adların görünmesini istediğimiz zaman şunu yaparız:

SELECT ReferansTablo.Ad, NotTablosu.Not

Diye sorgumuza başlarız. Burada sanki iki tablo bir gibi ayrı tablolardan alacağımız kolonları aldık.

Daha sonra:

INNER JOIN NotTablosu

Deriz bu da NotTablosu içinde referans tabloyu çağırmak için yazılmıştır. Şimdi ise Referans tablodaki okul no ile NotTablosundaki okul no’nun aynı şey olduğunu ifade etmek için şöyle deriz:

ON ReferansTablo.OkulNo=NotTablosu.OkulNo

Yani toplamda şu komutla işi hallederiz:

SELECT ReferansTablo.Ad, NotTablosu.Not
INNER JOIN NotTablosu
ON ReferansTablo.OkulNo=NotTablosu.OkulNo

image

Peki ya birden fazla tablo ilişkisi varsa ne olur. Bu durumda ne olduğunu daha sonra vakit bulursam anlatacağım.

Ancak başlangıç olarak aşağıdaki SQL koduna bakmanızda fayda var:

SELECT        dbo.YazilimTaleplerTab.*, TEB.IdariBirimAdi AS vteb, KUB.IdariBirimAdi AS vkub
FROM            dbo.YazilimTaleplerTab INNER JOIN
                        dbo.IdariBirim AS TEB ON dbo.YazilimTaleplerTab.TalepEdenBirim = TEB.idtIdariBirim INNER JOIN
                        dbo.IdariBirim AS KUB ON dbo.YazilimTaleplerTab.KullanacakBirim = KUB.idtIdariBirim

WordPress.com'da Blog Oluşturun.

Yukarı ↑