Bu bölümde, SQL Server’da veriler kaydedilirken kullanılan veri türlerinin çoğunu keşfedecek ve veri tipi dönüşümlerini öğreneceğiz.

Raporlarınız için sorgular yazdığınızda, ortamınızda hangi veri türlerinin kullanıldığını dikkate alın. Bu sayede daha sonra raporlarınızı ve client uygulamalarınızı, SQL Server veri türleri tarafından tutulan değer aralığını görüntüleyebilmek için yeterli kapasiteye sahip olarak planlayabilirsiniz. SQL Server verilerini başka ortamlarda görüntülemek için sorgularınızdaki veri tipi dönüşümlerini de planlamanız gerekebilir.

Eğer amacınız veri tabanı geliştirme ve yönetimi ise, veri türleri kategorilerindeki benzerlik ve farklılıkları not etmek ve stored procedure’ler için tür ve dizayn parametreleri oluştururken depolama alanınızı buna göre planlamak isteyebilirsiniz.

SQL Server Veri Türleri

SQL Server 2016’da, verileri sütunlarda saklamak, değerleri geçici olarak değişkenlerde tutmak, expression üzerinde veriler ile çalışmak ve parametreleri stored procedure’lere aktarmak için bir dizi sistem veri türü tanımlanmıştır.

Veri türleri verilerin türünü, boyutunu, kesinliğini ve ölçeğini belirtir. SQL Server’da temel veri türlerini anlamak, tablo tasarımı ve diğer nesneleri oluşturmanın yanı sıra T-SQL’de sorgu yazmak için de gereklidir.

Geliştiriciler ayrıca built-in (yerleşik)= veri türlerine takma adlar oluşturarak, hatta Microsoft® .NET Framework kullanarak yeni kullanıcı tanımlı türler üreterek sağlanan olanakları genişletebilirler. Ancak bu bölümde sadece built-in sistem veri türlerine odaklanacağız.

Daha sonra ele alacağımız karakter, tarih ve saat türleri dışında, SQL Server veri türleri aşağıdaki gibi kategorilere ayrılabilir:

  • Exact numeric: Bu veri türleri, verileri aşağıda verildiği üzere hassas bir şekilde depolar:
    • Integers: Değişen kapasitede tam sayılar.
    • Decimals: Hem toplam basamak sayısı hem de ondalık basamağın sağındaki basamak sayısı üzerinde kontrol içeren ondalık sayılar.
  • Approximate numeric: Bu veri türleri, tipik olarak bilimsel hesaplamalarda kullanılmak üzere hatalı değerlerin saklanmasına izin verir.
  • Binary strings: Bu veri türleri, özel uygulamaları desteklemek için byte stream veya hash’ler gibi binary verilerin depolanmasına izin verir.
  • Diğer veri türleri: Diğer kategorilerin dışında kalan çeşitli özel türleri içerir. Bu veri türlerinden bazıları sütun veri türleri olarak kullanılabilir (ve bu nedenle sorgulara erişilebilir). Bu kategori ayrıca depolama için kullanılmayan, daha çok cursor manipulation veya sonra kullanılacak işlemler için tablo değişkenleri oluşturma gibi özel işlemler için de veri türlerini içerir. Eğer raporcuysanız, sütunlar için kullanılan uniqueidentifier ve xml veri türleri gibi sadece bu veri türleriyle karşılaşabilirsiniz.
Sayısal Veri Türleri

Sayısal veri türleri exact numeric and approximate numeric olmak üzere iki alt kategoriden birine girer.

  • Exact numeric veri türleri:
    • Integer veri tipleri: Tamsayı veri türleri (tinyint, smallint, int, bigint) arasındaki fark, kapasiteleri ve depolama gereksinimleridir. Örneğin, tinyint veri türü 1 baytlık depolama maliyeti ile 0 ila 255 arasındaki değerleri tutabilir. Buna karşılık, bigint veri türü -2^63 (-9,223,372,036,854,775,808) ile 2^63-1 (9,223,372,036,854,775,807) arasında 8 bayt veri tutabilir.
    • Decimal veri türleri. Bu veri türleri, saklanacak toplam basamak sayısı (kesinlik) ve ondalık basamağın sağındaki basamak sayısı (ölçek) ile belirtilir. Hassasiyet ne kadar büyük olursa, depolama maliyeti de o kadar yüksek olur. Ondalık(decimal) veri türü ile sayısal(integer) veri türü arasında işlevsel bir fark olmadığını unutmayın. Ondalık, ISO standartlarına uygun bir isimdir; integer ise SQL Server’ın önceki sürümleriyle geriye dönük uyumluluk için kullanılmaktadır.
    • Parasal veri türleri: Dört ondalık basamağa kadar ölçekle parasal değerleri depolamak için veri türü. Integer veri türlerinde olduğu gibi, money ile smallmoney arasındaki fark, kapasiteleri ve depolama gereksinimleridir. Smallmoney veri tipi -214.748.3648 ile 214.748.3647 arasındaki değerleri 4 bayt depolama maliyetiyle tutar. Money veri tipi -922.337.203.685.477.5808 ile 922.337.203.685.477.5807 arasındaki değerleri 8 bayt depolama maliyetiyle tutar.
    • Boolean veri türü: Bit veri türü, SQL Server tarafından sayısal değerler olarak işlenen Boolean değerlerini (true / false) depolamak için kullanılır; true için 1 ve false için 0.
  • Approximate numeric veri türleri: Bu veri türlerinin kesinliği daha azdır, ancak exact numeric veri türlerinden daha fazla kapasiteye sahiptir. Değerleri hassasiyet eksikliği nedeniyle doğruluğu kaybeden bilimsel notasyon içerisinde saklar.
    • float: Float veri türünde float sayısının mantisini bilimsel gösterim şeklinde saklamak için kullanılan isteğe bağlı olarak bit sayısı parametre şeklinde alır. Mantis değerinin büyüklüğü float verisinin depolama boyutunu belirler. Mantis 1 ila 24 arasındaysa, şamandıra 4 bayt gerektirir. Mantis 25 ila 53 arasındaysa, 8 bayt gerektirir.
    • real veri türü, mantis değeri 24 olan float veri türüyle eşanlamlıdır (float (24)).

Not: Bu bağlamda mantis terimini floating point sayısının hane değerlerini ifade etmek için kullanıldığını unutmayın. Matematikte sayının bu kısmı yaygın olarak significand şeklinde ifade edilir, ancak bilgisayar biliminde genelde mantis şeklinde adlandırılır.

Binary String Veri Türleri

Binary string veri türleri, bir geliştiricinin serileştirilmiş dosya, imaj, byte stream’ler ve diğer özel veriler gibi binary bilgileri depolamasına izin verir. Binary veri türü, sayısal ve karakter dizisi veri türleriyle karşılaştırıldığında aralık ve depolama gereksinimlerindeki farklılıkları vardır. Sabit ve değişken uzunlukta binary string verilerinin her ikisini de kullanabilirsiniz. Bunlar arasındaki farklar ilerleyen bölümlerde yer alan karakter veri türü bölümünde açıklanacaktır.

Aşağıdaki örnekte, binary veri türüne dönüştürülmekte olan bir tam sayı değeri gösterilmektedir:

SELECT CAST(12345 AS binary(4)) AS Result; 

Aşağıdaki değerler dönecektir:

Result
----------
0x00003039 

Sonuçta bulunan önde gelen iki karakter (0x), bunun bir binary bir string olduğunu gösterir.

Not: Image veri türü de bir binary string veri türüdür ancak SQL Server’ın gelecekteki bir sürümünde kaldırılacaktır. Bunun yerine varbinary(max) kullanılmalıdır.

Diğer Veri Türleri

SQL Server, sayısal ve binary veri türlerine ek olarak, XML verilerinin depolanması ve işlenmesi gibi global olarak unique identifier’ların (GUID’lerin oluşturulması ve depolanması, hiyerarşilerin temsili) ve daha fazlası gibi özel kullanım durumları için başka veri türleri de sağlar:

  • Xml veri türü, Extensible Markup Language verilerinin (XML) depolanmasına ve değiştirilmesine izin verir. Xml veri türünün bir karakter veri türüne göre avantajı, xml veri türünün XML node  ve feature’lerinin XQuery ifadeleri kullanılarak bir T-SQL sorgusu içinde bu veri türüne sorgu atılmasına izin vermesidir. Xml veri türü isteğe bağlı olarak bir XML şemasının uygulanmasına da izin verir. Her bir xml veri türü örneği 2 GB’a kadar veri saklayabilir.
  • uniqueidentifier veri türü, 16 baytlık boyutunda depolanan genel benzersiz tanımlayıcıların (GUID’ler) oluşturulmasına ve saklanmasına izin verir. uniqueidentifier veri türünde saklanacak değerler, NEWID() sistem fonksiyonu kullanılarak SQL Server’da oluşturulabilir, harici uygulamalar tarafından da üretilebilir veya string değerlerden dönüştürülebilir.

Aşağıdaki örnekte, bir GUID oluşturmak için kullanılabilecek çeşitli yöntemleri gösterir:

SELECT NEWID() AS GUID_from_NEWID, CAST('1C0E3B5C-EA7A-41DC-8E1C-D0A302B5E58B' AS uniqueidentifier) AS GUID_cast_from_string; 

Dönen sonuç:

GUID_from_NEWID     GUID_cast_from_string
------------------------------------ ------------------------------------
DB71DBAE-460B-41DD-8CF1-FBEE3000BE0D     1C0E3B5C-EA7A-41DC-8E1C-D0A302B5E58B 
  • hierarchyid veri türü, aynı tablodaki satırlar arasındaki hiyerarşik ilişkilerin kaydedilmesini ve sorgulanmasını basitleştirmek için kullanılır. Örneğin, bir kuruluş şemasında bulunan düzeyler veya malzeme listesi. SQL Server, hierarchyid bir binary veri türünü değişken uzunlukta depolar; hiyerarşi değerinin gösterimi built-in fonksiyonlarla sağlanır.
  • rowversion veri türü, otomatik olarak oluşturulan 8 baytlık bir binary değeri, her satır eklendiğinde veya güncellendiğinde artan bir tabloda depolar. Rowversion veri değerlerinde tarih veya saat bilgileri depolanmaz, fakat bir satırın client tarafından en son okunduğundan bu yana değişip değişmediğini tespit etmek için kullanılabilir (örneğin optimistic locking uygulanken).
  • Mekansal veri türleri, geometrik ve coğrafi verilerle ilgilenmek için özel karmaşık veri tipleridir. Ayrıntıları bu bölümün kapsamı dışındadır:
    • Geometry veri türü, verileri Öklid (flat) koordinat sisteminde depolamak için kullanılır. Çizgileri, çokgenleri ve diğer basit geometrik şekilleri tanımlayan koordinat dizileri geometry veri tipinde saklanabilir. Geometri verileri üzerinde işlem yapmak için özel built-in fonksiyonlar bulunmaktadır.
    • Geography veri türü, verileri GPS enlemi ve koordinatlı boylam gibi bir yuvarlak toprak koordinat sisteminde depolamak için kullanılır. Geography veri türünde olduğu gibi, şekil tanımları geography türünde saklanabilir ve bu veriler üzerinde işlem yapmak için özel built-in fonksiyonlar bulunmaktadır .
  • sql_variant türü, örneğin tamsayı, ondalık ve karakter verilerinin aynı sütunda depolanmasını sağlayan diğer yerleşik veri türlerinin verilerini depolamak için kullanılabilen özel bir türdür. sql_variant kullanımı tipik veri tabanı tasarımları için en iyi uygulama değildir ve kullanımı tasarım sorunlarına yol açabilir. sql_variant veri türü konu bütünlüğü sağlamak için burada listelenmiştir.

Aşağıdaki veri türleri tablolarda veya view’lardaki sütunlarında kullanılamaz; stored procedure’ler içerisinde değişken veya parametre olarak kullanılırlar:

  • cursor veri türü, bir veri kümesinin satır satır işlenmesini sağlayan bir veri türüdür. Ayrıntısı bu bölümün kapsamı dışındadır.
  • table veri türü, standart veri tabanı tablosunun özelliklerinin çoğuna sahip olan, ancak yalnızca oluşturulduğu oturum bağlamında var olan bir tablo değişkeni veya bir stored procedure parametresi tanımlamak için kullanılır. table veri türleri, daha sonra işlenmek üzere T-SQL ifadelerinin sonuçlarını geçici olarak depolamak için kullanılır. Bu yazı serisinin ilerleyen bölümlerinde table veri türünün kullanımları hakkında bilgi edineceksiniz.
Veri Türü Önceliği

Sorgularınızdaki farklı veri türlerini birleştirirken veya karşılaştırırken (örneğin Where veya Join içerisinde), SQL Server’ın bir değerin veri türünü diğer değerin veri türüne dönüştürmesi gerekir. Hangi veri türünün dönüştürüleceği, ikisi arasındaki önceliğe bağlıdır.

SQL Server’da, tüm veri türlerinin sıralaması önceliğe göredir. Herhangi iki veri türü kendi aralarında biri düşük önceliğe, diğeri yüksek önceliğe sahip olacaktır. Dönüştürme sırasında SQL Server, daha düşük veri türünü daha yüksek olan veri türüne dönüştürmeye çalışır. Tipik olarak bu işlem özel koda ihtiyaç duyulmadan örtülü (implicit) olarak gerçekleşir. Ancak bu veri tipi öncelik düzenini temel olarak anlamanız önemlidir, böylece veri türlerini birleştirmek veya dönüştürmek için ne zaman manuel olarak (explicit) dönüştürmeniz gerektiğini anlarsınız.

Örneğin, veri türlerinin kısmi bir öncelik sırası listesi şu şekildedir:

  1. xml
  2. datetime2
  3. date
  4. time
  5. decimal
  6. int
  7. tinyint
  8. nvarchar
  9. char

İki ifadeyi farklı veri türleriyle birleştirirken veya karşılaştırırken, bu listede alt tarafta olan veri türü daha yüksek olan türe dönüştürülür. Mesela bu örnekte, tinyint veri türündeki bir değişken, @myInt integer türündeki değişkene eklenmeden önce dolaylı olarak integer değerine dönüştürülecektir:

DECLARE @myTinyInt AS TINYINT = 25;
DECLARE @myInt as INT = 9999;
SELECT @myTinyInt + @myInt; 

Not: Implicit dönüşümler kullanıcı için şeffaftır; bu nedenle işlem başarısız olursa (implicit dönüşümü olmayan veri türleri arasında dönüştürme işlemi gibi), veri türünü explicit olarak dönüştürmeniz gerekmektedir.

Sonraki bölümlerde bu amaç için kullandığımız CAST ve CONVERT işlevlerini öğreneceğiz. Explicit veya implicit hiçbir dönüşümün mümkün olmadığı bazı veri türü kombinasyonları bulunmaktadır.

Veri Türleri Ne Zaman Dönüştürülür?

SQL Server’ı sorgularken, verilerin veri türleri arasında dönüştürülebileceği birkaç senaryo vardır:

  • Verilerin yeri değiştirildiğinde, diğer verilerle karşılaştırıldığında veya bu verilerle birleştirildiğinde.
  • Değişken ataması sırasında.
  • Farklı türdeki terimler içeren herhangi bir operatör kullanırken.
  • T-SQL kodunda CAST veya CONVERT işlevini kullanılarak bir veri türünün açıkça diğerine dönüştürüldüğünde.

Önceki konudaki örnekte, tinyint ve int veri türleri birlikte bir sorguya eklendiğinde, tinyint veri türündeki bir değişkenin dolaylı olarak int veri türüne dönüştürüldüğünü görmüştük:

DECLARE @myTinyInt AS tinyint = 25;
DECLARE @myInt as int = 9999;
SELECT @myTinyInt + @myInt; 

Aşağıdaki örnekte örtük bir dönüşüm gerçekleşeceğini de görebilirsiniz:

DECLARE @myChar AS char(5) = '6';
DECLARE @myInt AS int = 1;
SELECT @myChar + @myInt;

Öğrenmiş olduğumuz üzere, SQL Server otomatik olarak düşük öncelikli veri türünden yüksek öncelikli veri türüne implicit bir dönüştürme işlemi gerçekleştirmeye çalışır.

Implicit veri türü dönüşümü, dönüşüm başarısız olmadıkça kullanıcı için saydamdır. Aşağıdaki örneğe bakalım:

DECLARE @myChar AS char(5) = 'six';
DECLARE @myInt AS int = 1;
SELECT @myChar + @myInt; 

Dönen sonuç:

Msg 245, Level 16, State 1, Line 3
Conversion failed when converting the varchar value 'six' to data type int. 

SQL Server’da bir int veri türünü, karakter veri türüne dönüştürebilmek için bunu explicit olarak yapmanız gerekmektedir. Sonraki bölümlerde bunun nasıl yapılacağını öğreneceğiz.

Kaynak: Microsoft Dökümanlar
Data Types (Transact-SQL),
Precision, Scale, and Length (Transact-SQL),
decimal and numeric (Transact-SQL),
float and real (Transact-SQL),
binary and varbinary (Transact-SQL),
Data Types (Transact-SQL),
Data Type Precedence (Transact-SQL),
CAST and CONVERT (Transact-SQL) – Implicit Conversions,
Data Type Conversion (Database Engine)