SQL Join,Union,Except Nedir?

EXPECT: SQL’de EXCEPT ifadesini iki kümenin farklı elemanlarını getirmek için kullanırız. Sadece ilk sonuç setinde olup ikici sorgu sonucunda olmayan kayıtları listelememizi sağlamaktadır. Departman ve çalışanlar adında iki tablomuz olsun. Henüz bir departmana bağlı olmayan çalışanlar veya çalışanı olmayan departmanlar derken EXCEPT kullanabiliriz. Ya da sipariş ve müşteriler tablomuz olsun. Sipariş vermeyen müşterileri listelemek için de EXCEPT kullanabiliriz.

SELECT FilmStudioID FROM Studio
EXCEPT
SELECT FilmStudioID FROM film

EXCEPT’e alternatif olarak NOT IN’de kullanabiliriz. Aralarındaki fark; EXCEPT sonuçları DISTINCT getirirken, NOT IN tekrarlı/tekrarsız getirmektedir. Şimdi aynı örneği bir de NOT IN ile yazalım;

SELECT T1.StudioName, T1.FilmStudioID 
FROM Studio AS T1 
WHERE T1.FilmStudioID NOT IN
      (SELECT T2.FilmStudioID 
       FROM Film AS T2 
       WHERE T1.FilmStudioID=T2.FilmStudioID)

INTERSECT: SQL’de INTERSECT ifadesini iki kümenin ortak elemanlarını getirmek için kullanırız.

SELECT Sutun1, Sutun2...., SutunN FROM Tablo1
INTERSECT
SELECT Sutun1, Sutun2...., SutunN FROM Tablo2

UNION: 2 yada daha fazla SELECT ifadesini bağlar. JOIN ise iki ya da daha fazla tabloyu tek bir SELECT ile bağlar. Ayrıca UNION tablo satırlarını bağlar, JOIN ise tablo sütunlarını birleştirir.
SQL UNION/UNION ALL arasındaki fark nedir?
UNION: DISTINCT gibi davranır yani mükerrer(tekrar eden) kayıtlar gelmez.
UNION ALL: Mükerrer kayıt olup olmaması önemli değildir, tüm satırlar gelir.

Temelde üç tip JOIN vardır bunlar; CROSS JOIN, INNER JOIN ve OUTER JOIN (LEFT OUTER, RIGHT OUTER, FULL OUTER)‘dir.
CROSS JOIN: İki tablonun kartezyen çarpımıdır. Yani A tablosundaki her satır için B tablosundaki tüm satırlar döner.

--Önerilen syntax biçimi
SELECT Tablo1.Sütun(lar), Tablo2.Sütun(lar),
FROM Tablo1
 CROSS JOIN
     Tablo2
  
--Alternatif syntax biçimi
SELECT Tablo1.Sütun(lar), Tablo2.Sütun(lar),
FROM Tablo1, Tablo2

INNER JOIN: İki tablodaki ortak alana göre birebir eşleştirme yapar.

--Önerilen syntax biçimi
SELECT Tablo1.Sütun(lar), Tablo2.Sütun(lar),
FROM Tablo1
 INNER JOIN
     Tablo2 ON
   Tablo1.Ortak_Sütun = Tablo2.Ortak_Sütun

LEFT OUTER JOIN: İlk tablonun verileri koşulsuz gelir, ikinci tablodan ise ortak alana göre eşleşen kayıtlar gelir. Eşleşmeyen kayıtlar NULL döner.

--Önerilen syntax biçimi
SELECT Tablo1.Sütun(lar), Tablo2.Sütun(lar),
FROM Tablo1
 LEFT OUTER JOIN
     Tablo2 ON
   Tablo1.Ortak_Sütun = Tablo2.Ortak_Sütun

RIGHT OUTER JOIN: İkinci tablonun verileri koşulsuz gelir, ilk tablodan ise ortak alana göre eşleşen kayıtlar gelir. Eşleşmeyen kayıtlar NULL döner.

SELECT Tablo1.Sütun(lar), Tablo2.Sütun(lar),
FROM Tablo1
 RIGHT OUTER JOIN
     Tablo2 ON
   Tablo1.Ortak_Sütun = Tablo2.Ortak_Sütun

FULL OUTER JOIN: İki tablonun ortak alana göre eşleşen eşleşmeyen tüm kayıtları gelir. Eşleşmeyen kayıtlar NULL döner.

SELECT Tablo1.Sütun(lar), Tablo2.Sütun(lar),
FROM Tablo1
 FULL OUTER JOIN
     Tablo2 ON
   Tablo1.Ortak_Sütun = Tablo2.Ortak_Sütun
Reklamlar

sp_helptext, sp_columns, sp_tables System Prosedürünün kullanılması

sp_helptext prosedürü bizim tanımladığımız yada sistemde bulunan objelerin tanımlamalarını text formatında gösterir.
ÖR: exec sp_helptext ‘TBLREFERANSLAR’

sp_columns belirtilen tablonun kolonlarını, tiplerini vs detaylı listeler.
exec sp_columns ‘TBLREFERANSLAR’

sp_tables tüm tabloların veya belirtilen tabloyu detaylı listeler.
exec sp_tables ‘TBLREFERANSLAR’ –Sadece TBLREFERANSLAR tablosunu detaylı getirir.
exec sp_tables –Tüm tabloları listeler.

String.IsNullOrEmpty() vs. String.IsNullOrWhiteSpace() farkı

IsNullOrEmpty: içeriğin null veya boş olması kontolüdür. Fakat içerisinde boşluk(space) olması durumunda bu kontrol false değeri döner.
IsNullOrWhiteSpace: İçeriğin null veya boşluk(space) olması durumunu kontrol eder.

string testString = "";
Console.WriteLine(string.Format("IsNullOrEmpty : {0}", string.IsNullOrEmpty(testString)));
Console.WriteLine(string.Format("IsNullOrWhiteSpace : {0}", string.IsNullOrWhiteSpace(testString)));
Console.ReadKey();

Resutl :
IsNullOrEmpty : True
IsNullOrWhiteSpace : True

************************************************************
string testString = " MDS   ";

IsNullOrEmpty : False
IsNullOrWhiteSpace : False

************************************************************
string testString = "   ";

IsNullOrEmpty : False
IsNullOrWhiteSpace : True

************************************************************
string testString = string.Empty;

IsNullOrEmpty : True
IsNullOrWhiteSpace : True

************************************************************
string testString = null;

IsNullOrEmpty : True
IsNullOrWhiteSpace : True

C#’ın fazla bilinmeyen bir kaç özelliği

1. Değişken isimlerinde @ karakteri ile rezerve isimler kullanılabilir
Değişkenin önüne @ işareti koymanız yeterli:

private string @string;

2. “default” ile generic tiplerde varsayılan değerin atamasını sağlayabilirsiniz.
T referans tipiyse null, int ise 0, boolean ise false atanacaktır.

T t = default(T);

3. Dosya yollarını “System.IO.Path.Combine()” ile birleştirebilirsiniz.

string fullPath = mainPath + "\\" + fileName;
//Yerine 
string fullPath = System.IO.Path.Combine(mainPath, fileName)

4.“Environment.NewLine” yeni satıra geçmek için gereken “escape karakteri”ni döndürür.

Uygulamanın çalıştığı ortamda yeni satır karakteri neyse Environment.NewLine bu karakteri döndürür. Böylelikle ortamdaki yeni satır karakteri “\n” miydi “\r\n” miydi diye kara kara düşünmemize gerek kalmaz!

5.“Coalescing operator” ile kolay null kontrolü
Aşağıdaki örnekte, test string’ine testStr1‘in değeri null değilse atanacak, şayet null ise testStr2 atanacaktır. Eğer testStr2 de null ise boş string ataması yapılacaktır. (Deneyerek görmeniz, bu cümleleri okuyup anlamanızdan çok daha kolay olacaktır gibi geliyor bana

string test = testStr1 ?? testStr2 ?? string.Empty

6. yield iterasyon oluşturmak için kullanılır.
Compiler yield anahtar sözcüğünü gördüğü anda bu keywordün bulunduğu bloğun bir iterator bloğu olduğunu algılamaktadır. Bu adımdan sonra foreach döngüsü içerisinde ilgili koleksiyonu dönen metod çağrıldıktan sonra metod içerisindeki bir yield return ifadesine gelinince değer geriye dönülmekte ve bu işlem yapılmadan önce Compiler, iterator metodun kaldığı yeri saklamaktadır. Süreç esnasında foreach döngüsünde iterator metoduna gelen her istekte iterator metot baştan başlamak yerine kaldığı yerden işletilmektedir.
yield anahtar sözcüğünü aşağıdaki gibi iki farklı şekilde kullanabilmekteyiz.

yield return [value]
yield break

“yield return [value]” kullanımı ile yukarıdaki örneklendirmemizde olduğu gibi çalışabilmekteyiz. Lakin “yield break” ifadesi ile iterator içerisindeki iterasyonun sona erdiği bilgisi ilgili foreach döngüsüne bildirilmektedir. Aşağıdaki kod parçacığı bu durumu örneklendirmektedir.

static public IEnumerable VerileriGetir()
{
    yield return "Pazartesi";
    yield return "Salı";
    yield return "Çarşamba";
    yield return "Perşembe";
    yield return "Cuma";
    yield return "Cumartesi";
    yield break;
    yield return "Pazar";
}

static void Main(string[] args)
{
    foreach (var Gun in VerileriGetir())
        Console.WriteLine(Gun);
 
    Console.Read();
}

“yield break” ifadesinden dolayı ilgili foreach iterasyonun sona erdiğini bilecek ve “Pazar” değerini yazdırmayacaktır.
Son olarak, yield keywordü kullanılan iterator bir metot, foreach için evaluate edilmediği sürece yield komutu ilgili metodu çalıştırmayacaktır.
Yani VerileriGetir() değerlerini bir değişkene atarsak sadece methodu referans göstermiş oluruz, Method içerisine sadece döngü esnasında girecektir.

static void Main(string[] args)
{
    IEnumerable Veriler = VerileriGetir();
 
    foreach (var item in Veriler)
        Console.WriteLine(item);
}

Bu örnekte “Veriler” değişkeninin içinde foreach döngüsüne gelmeden önce hiçbirşey olmayacaktır. Ne zaman ki döngüye girilecek, o zaman VerileriGetir metodu çalıştırılacaktır. Yani istemci tarafından ne zaman foreach döngüsüyle çağrılırsa bir anlamda yield lazy loading yapmış olacaktır.

SQL Server da Temporary Tablo Kullanımı

Sql Server’da 2 temp tablo türü oluşturulabilir.
Bunlar;

  • Local Temp Tablo
  • Global Temp Tablo

Local Temp Tablo

Local Temp tablolar sadece tabloyu olusturan kullanicinin, olusturmak için kullandigi connection üzerin de geçerlidir. Kullanici baglantiyi kapattigi anda otomatik olarak silinir. Local Temp tablo tanimlamak için tablo isminin önüne # isareti koymamiz yeterlidir.

CREATE TABLE #LocalTempTablo
(
    ID int,
    Ad varchar(20), 
    Soyad varchar(20)
)
 
insert into #LocalTempTablo values ( 1, 'TEST','MEST');
 
select * from #LocalTempTablo 
 
Yukariki scriptleri çalistirdiktan baska bir sorgu penceresinde select veya insert sorgusu çalistirirsaniz asagidaki hatayi alirsiniz.
Msg 208, Level 16, State 0, Line 1
Invalid object name '#LocalTempTablo'

Global Temp Table

Global olarak temp tablo tanimlamak için ## karakterlerini tablo isminden önce eklememiz yeterlidir. Global temp tablolar bir connection içinde tanimlandigi anda, normal tablolar gibi tüm kullanicilar ve connectionlar içinde kullanilabilir hale gelirler. Global tabloyu olusturdugunuz connection kapatilana kadar bu tablo var olmaya devam eder.

CREATE TABLE ##LocalTempTablo
(
    ID int,
    Ad varchar(20), 
    Soyad varchar(20)
)
 
insert into ##LocalTempTablo values ( 1, 'TEST','MEST');
 
select * from ##LocalTempTablo 
 
Yukaridaki select ve insert sorgusunu istediginiz herhangi bir sorgu ekraninda çalistirabilirsiniz. Ilk olusturdugunuz connection açik oldugu sürece heryerden bu tablolara erisim yapilabilir. Temp tabloyu oluşturduğunuz pencereyi kapattığınızda ise yine aşağıdaki hatayı alırsınız.
Msg 208, Level 16, State 0, Line 1
Invalid object name '#LocalTempTablo'

 

Custom Configuration Section Kullanımı

Zamanla ve kullanıcı kontrollü olarak değişebilecek olan özelliklerin configte saklanması tercih edilen hızlı bir yöntemdir.

Web.config dosyamızın içerisine, configSections elementi içerisinde sectionGroup ve section tanımlamalarını yapmamız yeterli olacaktır.

Örnek tanımlama;

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
 
 <configSections>
     <sectionGroup name="serviceConnectionGroupRedis">
         <section name="Redis.ServerSettings" type="ConsoleApplication1.RedisDynamic.RedisServerSettings,ConsoleApplication1"/>
     </sectionGroup>
 </configSections>
 
 <serviceConnectionGroupRedis>
     <Redis.ServerSettings DefaultDb="0" ConnectionStringOrName="localhost:6379" PreferSlaveForRead="true" />
 </serviceConnectionGroupRedis>

 <startup>
 <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" />
 </startup>
</configuration>

C# tarafında ise section type’ta belirlenen dosya yaratılır. Bu dosya içeriğine göre config ayarlarımız yüklenmektedir.

namespace ConsoleApplication1.RedisDynamic
{
   public interface IRedisServerSettings
   {
       bool PreferSlaveForRead { get; }
       string ConnectionStringOrName { get; }
       int DefaultDb { get; }
   }


   public class RedisServerSettings : ConfigurationSection, IRedisServerSettings
   {
       public static Lazy<IRedisServerSettings> Settings = new Lazy<IRedisServerSettings>(() => ConfigurationManager.GetSection("serviceConnectionGroupRedis/Redis.ServerSettings") as RedisServerSettings);

       [ConfigurationProperty("PreferSlaveForRead", IsRequired = false, DefaultValue = false)]
       public bool PreferSlaveForRead { get { return Convert.ToBoolean(this["PreferSlaveForRead"]); } }

       [ConfigurationProperty("ConnectionStringOrName", IsRequired = true)]
       public string ConnectionStringOrName { get { return this["ConnectionStringOrName"] as string; } }
  
       [ConfigurationProperty("DefaultDb", IsRequired = false, DefaultValue = 0)]
       public int DefaultDb { get { return Convert.ToInt32(this["DefaultDb"]); } }
   }
}

Daha sonra istenilen yerde config ayarları çekilebilmektedir.

var ayarlar = ConfigurationManager.GetSection("serviceConnectionGroupRedis/Redis.ServerSettings");
//veya statik olarak type göre tanımlama yaptıysak aşağıdaki şekildede ayarlarımızı alabiliriz.
var ayar = RedisServerSettings.Settings.Value;

SQL SERVER’DA LINKED SERVER(OPENQUERY) KULLANIMI

Sql serverda tek sorgu cümlesi üzerinden birden fazla Sql server’a bağlanıp veri getirmek istediğiniz anda SQL Server Linked Server” yardımınıza koşuyor.

Linked Server bağlantısının nasıl yapıldığını google ile kolayca bulabilirsiniz. Başarıyla tanımladığınızı farz ederek devam ediyorum.
Linked Server : istediğiniz herhangi bir bağlantı ismi. Ör(192.168.0.13)

Aşağıdaki sorgu ile uzaktaki database’den KULLANICILAR tablosuna select çekilmektedir.

select * from OPENQUERY([192.168.0.13],'select * from TEST.dbo.KULLANICILAR')

Select into ile uzaktaki KULLANICILAR tablosunu databasemizde YENI_KULLANICILAR tablosu olarak oluşturmaktyız.

select AD,SOYAD into YENI_KULLANICILAR from 
openquery([192.168.0.13],'select * from LOJITEK.dbo.KULLANICILAR') 

Bu işlemler isteğe göre çoğaltılabilir.