Post

1 - Microsoft SQL Server'e Başlarken

1 - Microsoft SQL Server’e Başlarken

Versiyon Tarihi (Release Date)

VersiyonNoKod AdıYayın TarihiSon Destek TarihiGenişletilmiş Son Tarih
SQL Server 202216Dallas16 Kas 202211 Oca 202811 Oca 2033
SQL Server 201915Aris Seattle04 Kas 201928 Şub 202508 Oca 2030
SQL Server 201714vNext29 Eyl 201711 Eki 202212 Eki 2027
SQL Server 201613 01 Haz 201613 Tem 202114 Tem 2026
SQL Server 201412 05 Haz 201409 Tem 201909 Tem 2024
SQL Server 201211Denali20 May 201211 Tem 201712 Tem 2022
SQL Server 2008 R210.5Kilimanjaro20 Tem 201008 Tem 201409 Tem 2019
SQL Server 200810Katmai06 Kas 200808 Tem 201409 Tem 2019
SQL Server 20059Yukon14 Oca 200612 Nis 201112 Nis 2016
SQL Server 20008Shiloh30 Kas 200008 Nis 200809 Nis 2013
SQL Server 7.07Sphinx27 Kas 199831 Ara 200511 Oca 2011
SQL Server 6.56.5Hydra30 Haz 199601 Oca 2002 
SQL Server 6.06SQL9513 Haz 199531 Mar 1999 

1.1 - Basit Veri İşleme Dili (DML-Data Manipulation Language)
SELECT / INSERT / UPDATE / DELETE

Veri İşleme Dili (kısaca DML), INSERT, UPDATE ve DELETE gibi işlemleri içerir:

Bir tablo oluşturalım ‘MerhabaDunya’

1
2
3
4
CREATE TABLE MerhabaDunya (
  Id INT IDENTITY,
  Description VARCHAR(1000)
)

DML işlemi INSERT, tabloya satır ekleme.

1
INSERT INTO MerhabaDunya (Description) VALUES ('Merhaba Dünya')

DML işlemi SELECT, tabloyu görüntülüyor.

1
SELECT * FROM MerhabaDunya

Tablodan belirli bir sütunu seçin.

1
SELECT Description FROM MerhabaDunya

DML işlemi UPDATE, tablodaki belirli bir satırın güncellenmesi.

1
UPDATE MerhabaDunya SET Description = 'Merhaba, Dünya!' WHERE Id = 1

Tablodan satırların seçilmesi UPDATE işeminden sonra açıklamanın değiştiğini görün.

1
SELECT * FROM MerhabaDunya

DML işlemi DELETE, tablodan satırın silinmesi.

1
DELETE FROM MerhabaDunya WHERE Id = 1

DELETE işleminden sonra tablo içeriğine bakın.

1
SELECT * FROM MerhabaDunya

Aşağıdaki örnekler tabloların nasıl sorgulanacağını göstermektedir:

1
2
3
4
USE Northwind;
GO
SELECT TOP 10 * FROM Customers
ORDER BY CompanyName

Result

Northwind veritabanından CompanyName sütununa göre sıralanan Customers tablosunun ilk 10 kaydını getirecektir.

Northwind Microsoft’un örnek veritabanlarından biridir, burada script halini bulabilirsiniz.

Not: USE Northwind; sonraki tüm sorgular için varsayılan veritabanını değiştirir.

Daha sonra [Veritabanı].[Şema].[Tablo] biçimindeki sözdizimini kullanarak da veritabanını seçebilirsiniz:

1
2
3
4
5
SELECT TOP 10 * FROM Northwind.dbo.Customers 
ORDER BY CompanyName

SELECT TOP 10 * FROM Northwind.dbo.Suppliers
ORDER BY City

Farklı veritabanlarından veri sorguluyorsanız bu kullanışlıdır. Şema ve tam sözdizimi kullanılırken belirtilmesi gerekir. Bunu, klasörünüzün içindeki bir klasör olarak düşünebilirsiniz. dbo varsayılan şemadır. Varsayılan şema atlanabilir. Diğer tüm kullanıcı tanımlı şemalar belirtilmelidir.

Veritabanı tablosu ayrılmış kelimeler (bunlara reserve keywords denir) gibi adlandırılan sütunlar içeriyorsa, örneğin Date, köşeli parantez içinde kulanılır:

1
2
3
-- DESC tersten sırala
SELECT TOP 10 [Date] FROM dbo.MyTable
ORDER BY [Date] DESC

Sütun adında boşluk bulunması durumunda da aynı durum geçerlidir. (boşluk önerilmez!). Bir alternatif sözdizimi köşeli parantez yerine çift tırnak kullanmaktır, örneğin:

1
2
3
-- DESC tersten sırala
SELECT TOP 10 "Date" FROM dbo.MyTable
ORDER BY "Date" DESC

eşdeğerdir ancak çok yaygın olarak kullanılmaz.

Çift tırnak ve tek tırnak arasındaki farka dikkat edin. Tek tırnak metin (string, dize) için kullanılır,

1
2
3
4
-- DESC tersten sırala
SELECT TOP 10 "Date" FROM dbo.MyTable
WHERE User = 'johndoe'
ORDER BY "Date" DESC

geçerli bir sözdizimidir.

T-SQL’in NChar ve NVarchar veri türleri için bir N önekine sahip olduğuna dikkat edin;

1
2
3
SELECT TOP 10 * FROM NORTHWND.dbo.Customers
WHERE CompanyName LIKE N'AL%'
ORDER BY CompanyName

AL ile başlayan şirket adına sahip tüm şirketleri döndürür. (% bir joker karakterdir, bir DOS komut satırında yıldız işaretini kullandığınız gibi, örneğin DIR AL*) LIKE için birkaç joker karakter mevcuttur, öğrenmek için buraya bakın.

Joins (birleştirmek, katılmak)

Tek bir tabloda değil de birden çok tabloda bulunan alanları sorgulamak istiyorsanız join kullanışlıdır.

Örneğin: Northwind veritabanındaki Territories tablosundaki tüm sütunları sorgulamak istiyorsunuz. Ama farklı bir tablo olan Region tablosundan RegionDescription alanına ihtiyacınız olduğunu fark ettiniz. İhtiyacınız ortak bir anahtar alan : RegionID bu bilgileri aşağıdaki gibi tek bir sorguda birleştirmek için kullanabilirsiniz. (TOP 5 yalnızca ilk 5 satırı döndürür, tüm satırları almak istiyorsanız kaldırabilirsiniz)

1
2
3
4
5
6
SELECT TOP 5 
  Territories.*,
  Region.RegionDescription
FROM Territories
  INNER JOIN Region ON Territories.RegionID = Region.RegionID
ORDER BY TerritoryDescription

Territories tablosundaki tüm sütunları ve Region tablosundaki RegionDescription sütununu gösterecektir. Sonuç TerritoryDescription alanına göre sıralanır.

Table Aliases (tablo takma adları)

Sorgunuz iki veya daha fazla tabloya referans gerektirdiğinde Tablo Takma Adını kullanabilirsiniz. Takma adlar, tam tablo adı yerine kullanılabilecek tablolara yapılan kısa isimlendirmelerdir.

Takma ad kullanmanın sözdizimi şöyledir: <TableName> [as] <alias>

AS isteğe bağlı bir anahtar kelimedir. Örneğin önceki sorgu şu şekilde yeniden yazılabilir:

1
2
3
4
5
6
SELECT TOP 5 
  T.*,
  R.RegionDescription
FROM Territories T
  INNER JOIN Region R ON T.RegionID = R.RegionID
ORDER BY TerritoryDescription

Aynı tabloyu iki kez kullanıyor olsanız bile takma adlarının sorgudaki tüm tablolar için benzersiz olması gerekir.

1
2
3
4
5
6
7
SELECT 
  S.FirstName AS SupervisorFirstName, --Kolon alanını yeniden adlandırır
  S.LastName AS SupervisorLastName, --Kolon alanını yeniden adlandırır
  E.*
FROM Employees E 
  INNER JOIN Employees S ON E.ReportsTo = S.EmployeeId
WHERE E.EmployeeId = 6

Unions (birleşim)

Daha önce gördüğümüz join farklı tablolardan sütunlar ekler. Peki farklı tablolardan satırları birleştirmek isterseniz, bu durumda UNION kullanabilirsiniz. Diyelim ki bir parti planlıyorsunuz ve sadece çalışanlar değil, aynı zamanda müşterileri de davet etmek istiyorsunuz. Bunu yapmak için bu sorguyu çalıştırabilirsiniz:

1
2
3
SELECT FirstName + ' ' + LastName as ContactName, Address, City FROM Employees
UNION
SELECT ContactName, Address, City FROM Customers

Çalışanların ve müşterilerin adlarını, adreslerini ve şehirlerini tek bir tabloda döndürecektir.

Sütun numarası, sütun adları, sıra ve veri türü, tüm select ifadelerinde eşleşmelidir.

Yinelenen satırlar (varsa) otomatik olarak ortadan kaldırılır,bunu istemiyorsanız UNION yerine UNION ALL kullanın.

Table Variables (tablo değişkenleri)

Geçici verilerle (özellikle prosedurler de) uğraşmanız gerekiyorsa tablo değişkenlerini kullanmak yararlı olabilir:

Gerçek bir tablo ile tablo değişkeni arasındaki fark, bunun yalnızca geçici işlem için bellekte bulunmasıdır.

Örnek:

1
2
3
4
DECLARE @Region TABLE (
  RegionID int,
  RegionDescription NChar(50)
)

Bellekte bir tablo oluşturur. Bu durumda @ öneki bir değişken olduğu için zorunludur. Tüm DML’leri gerçekleştirebilirsiniz.

örneğin, satır eklemek, silmek ve seçmek için,

1
2
INSERT INTO @Region values(3, 'Northern')
INSERT INTO @Region values(4, 'Southern')

Normalde, bunu gerçek bir tablodan doldurursunuz:

1
2
INSERT INTO @Region
SELECT * FROM dbo.Region WHERE RegionID > 2;

Bu, dbo.Region gerçek tablosundan filtrelenmiş değerleri okur ve bunu @Region bellek tablosuna ekler.

Daha ileri işlemler için kullanılabileceğiniz bir örnek:

1
2
SELECT * FROM Territories t
JOIN @Region r on t.RegionID = r.RegionID

Bu durumda tüm Northern(Kuzey) ve Southern(Güney) bölgeleri geri dönecektir.

NOT: Microsoft, tablo değişkenindeki veri satırlarının sayısı 100’den az ise tablo değişkenlerinin kullanılmasını önerir. Daha büyük miktarda veriyle çalışacaksanız bunun yerine temporary table (geçici bir tablo) kullanın.

1.2 - Bir tablodaki tüm satırları ve sütunları seçmek

Sözdizimi:

1
SELECT * FROM table_name

Yıldız * işareti kullanmak, tablodaki tüm sütunları seçmek için bir kısayol görevi görür.

Bu, tabloya bir takma ad eklediğinizde de aynı şekilde çalışır,

1
SELECT * FROM Employees AS e

Veya belirli bir tablodan tümünü seçmek istiyorsanız, alias + “.* “ kullanabilirsiniz:

1
2
3
4
SELECT 
  e.*, et.TerritoryID 
FROM Employees e
INNER JOIN EmployeeTerritories et ON et.EmployeeID = e.EmployeeID 

Veritabanı nesnelerine tam olarak nitelenmiş adlar kullanılarak da erişilebilir:

1
SELECT * FROM [server_name].[database_name].[schema_name].[table_name]

Sunucu ve/veya veritabanı adlarının değiştirilmesi, sorgularda sorunlara neden olacağından bu pek önerilmez.

Sorguların tek bir sunucuda yürütülmesi durumunda tablo_adı’ndan önceki alanların atlanabileceğini unutmayın, sırasıyla veritabanı ve şema. Ancak bir veritabanının birden fazla şemaya sahip olması yaygındır ve bu durumlarda şema adı mümkün olduğunca atlanmamalıdır.

SELECT *‘in yerine sütun adlarını her zaman açıkça belirtmek daha güvenlidir.

1
SELECT col1, col2, col3 FROM table_name

1.3 - Belirli satırları güncelleme

1
2
3
UPDATE HelloWorlds
SET HelloWorld = 'HELLO WORLD!!!'
WHERE Id = 5

Yukarıdaki kod HelloWorlds tablosunda “Id = 5” olan kayıt için “HelloWorld” alanının değerini “HELLO WORLD!!!” ile günceller.

Bir güncelleme ifadesinde, aşağıdaki durumlar dışında tüm tablonun güncellenmesini önlemek için “where” ifadesinin kullanılması tavsiye edilir.

1.4 - Tüm satırları silme

1
DELETE FROM HelloWorlds

Bu, tablodaki tüm verileri silecektir. Bu kodu çalıştırdıktan sonra tablo hiçbir satır içermeyecektir.

DROP TABLE’ın aksine, bu, tablonun kendisini ve yapısını korur ve bu tabloya yeni satırlar eklemeye devam edebilirsiniz.

Tablodaki tüm satırları silmenin başka bir yolu da:

1
TRUNCATE TABLE HelloWords

DELETE işleminin farklılığı:

  1. Truncate işleminde log dosyasında saklanmaz.
  2. IDENTITY(KİMLİK) alanı mevcutsa bu sıfırlanacaktır.
  3. TRUNCATE, tablonun tamamına uygulanır bir kısmına uygulanamaz. (bunun yerine DELETE komutuyla WHERE yan tümcesini ilişkilendirin)

TRUNCATE işleminin kısıtlamaları.

  1. Tabloda FOREIGN KEY referansı varsa
  2. Eğer tablo INDEXED VIEW de kullanılmışsa
  3. Eğer tablo TRANSACTIONAL REPLICATION or MERGE REPLICATION kullanılarak yayınlanıyorsa
  4. Tabloda tanımlanan herhangi bir TRIGGER tetiklenmez.

daha fazla bilgi

1.5 - Koddaki yorumlar (Comments)

Transact-SQL iki tür yorum yazmayı destekler. Yorumlar veritabanı motoru tarafından dikkate alınmaz ve insanların okuması için kullanılır.

Comments önünde – bulunur ve yeni bir satırla karşılaşılıncaya kadar dikkate alınmaz:

1
2
3
4
-- Bu bir yorum
SELECT *
FROM MyTable -- Bu başka bir yorum
WHERE Id = 1;

Eğik çizgi yıldız yorumları /* ile başlar ve */ ile biter. Bu sınırlayıcılar arasındaki tüm metinler yorum olarak kabul edilir.

1
2
3
4
5
6
7
8
9
10
/* Bu bir 
çoklu satır 
blok 
yorumudur.
*/
SELECT Id = 1, [Message] = 'First row'
UNION ALL
SELECT 2, 'Second row'
/* Bu tek satır yorum */
SELECT 'More';

Eğik çizgi yıldız yorumları iç içe yerleştirilebilir ve eğik çizgi yıldız yorumunun içindeki bir başlangıç ​​/*‘ın */ ile bitmesi gerekir.

Aşağıdaki kod hataya neden olacaktır

1
2
3
4
5
/*
SELECT *
FROM CommentTable
WHERE Comment = '/*'
*/

Alıntı içinde olsa bile eğik çizgi yıldız yorumun başlangıcı olarak kabul edilir. Bu yüzden sonlandırılması gerekiyor, doğru yol şu olurdu.

1
2
3
4
5
/*
SELECT *
FROM CommentTable
WHERE Comment = '/*'
*/ */

1.6 - PRINT (yazdır)

Çıkış konsoluna bir mesaj yazdırır. SQL Server Management Studio’yu kullanarak sonuçlar sekmesi yerine mesajlar sekmesine bakın.

1
PRINT 'Hello World!';

1.7 - Bir koşulla eşleşen satırları seçin

Genel olarak sözdizimi şöyledir:

1
2
3
SELECT <column names>
FROM <table name>
WHERE <condition>

Örnek:

1
2
3
SELECT FirstName, Age
FROM Users
WHERE LastName = 'Smith'

Koşullar karmaşık olabilir

1
2
3
SELECT FirstName, Age
FROM Users
WHERE LastName = 'Smith' AND (City = 'New York' OR City = 'Los Angeles')

1.8 - Tüm satırları güncelleme

Basit bir güncelleme şekli, tablonun belirli bir alanındaki tüm değerleri arttıralım. Bunu yapabilmek için şunları yapmamız gerekiyor:

Alanı ve artış değerini tanımlayın

Aşağıda score alanını 1 (tüm satırlarda) artıran bir örnek verilmiştir:

1
2
UPDATE Scores
SET score = score + 1

Belirli bir satır için yanlışlıkla bir GÜNCELLEME yaparsanız verilerinizi bozabileceğiniz için bu tehlikeli olabilir.

1.9 - Truncate Table

1
TRUNCATE TABLE HelloWorlds

Bu kod HelloWorlds tablosundaki tüm verileri silecektir. TRUNCATE TABLE, Delete from Table’e neredeyse benzer aradaki fark Truncate ile Where cümlelerini kullanamamanızdır. TRUNCATE TABLE de daha az işlem günlüğü tutlur.

Bir kimlik(ID) sütunu varsa, bunun ilk değerine sıfırlanacağını unutmayın (örneğin, otomatik olarak artan ID 1’den yeniden başlar). Kimlik sütunlarının başka bir tabloda yabancı anahtar olarak kullanılması durumunda bu durum tutarsızlığa yol açabilir.

1.10 - Temel Sunucu Bilgilerini Alma

Çalışan MS SQL Server sürümünü döndürür.

1
SELECT @@VERSION

MS SQL Server örneğinin adını döndürür.

1
SELECT @@SERVERNAME

MS SQL Server’ın çalıştığı Windows hizmetinin adını döndürür.

1
SELECT @@SERVICENAME

SQL Server’ın çalıştığı makinenin fiziksel adını döndürür.

1
SELECT serverproperty('ComputerNamePhysicalNetBIOS');

1.11 - Yeni tablo oluşturun ve eski tablolardan kayıtları ekleyin

Eski tablonun yapısına sahip yeni bir tablo oluşturur ve tüm satırları yeni tabloya ekler.

1
SELECT * INTO NewTable FROM OldTable

Bazı Kısıtlamalar

  1. Yeni tablo olarak bir tablo değişkeni veya tablo değerli parametre belirtemezsiniz.
  2. Kaynak tablo olsa bile bölümlenmiş bir tablo oluşturmak için SELECT…INTO komutunu kullanamazsınız.
  3. Kaynak tabloda tanımlanan indeksler, kısıtlamalar ve tetikleyiciler yeni tabloya aktarılmaz. SELECT…INTO ifadesinde de belirtilemezler.
  4. ORDER BY ifadesinin belirtilmesi, satırların belirtilen sıraya göre eklendiğini garanti etmez.
  5. Seçim listesine hesaplanan bir sütun eklendiğinde, yeni tablodaki karşılık gelen sütun hesaplanmış bir sütun değildir. Yeni sütundaki değerler, şu anda hesaplanan değerlerdir.

daha fazla bilgi

1.12 - Verileri güvenli bir şekilde değiştirmek için Transaction kullanma

Transaction, bir veya daha fazla SQL komutunu içerebilir ve bu komutlar bir arada çalışır. Transaction, verilerin bütünlüğünü korumak ve birden çok komutun başarılı bir şekilde tamamlanmasını sağlamak için kullanılır. Transaction başladığında, veritabanı değişikliklerini geçici bir alanda saklar ve işlem başarıyla tamamlandığında bu değişiklikler kalıcı hale gelir. Ancak işlem başarısız olursa, tüm değişiklikler geri alınır.

SQL Server’da işlem yönetimi için aşağıdaki komutlar kullanılır:

  • BEGIN TRANSACTION: Bir transaction başlatmak için kullanılır. Transaction başlattığınızda, veritabanı değişiklikleri transaction tarafından izlenir.
1
BEGIN TRANSACTION;
  • COMMIT TRANSACTION: Bir transaction başarıyla tamamladığınızda kullanılır. Bu komut, transaction tarafından yapılan değişiklikleri kalıcı hale getirir.
1
COMMIT TRANSACTION;
  • ROLLBACK TRANSACTION: Bir transaction iptal etmek veya geri almak için kullanılır. Transaction başarısız olursa veya geri alınması gerekiyorsa kullanılır.
1
ROLLBACK TRANSACTION;

İşte bir örnek, bir banka müşteri hesabından para çekme işlemini SQL Server işlemleriyle nasıl gerçekleştirebileceğinizi gösteren bir örnek:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
BEGIN TRANSACTION;

DECLARE @HesapBakiye DECIMAL(10, 2);
SET @HesapBakiye = (SELECT Bakiye FROM Hesaplar WHERE HesapNo = '12345');

IF @HesapBakiye >= 100.00
BEGIN
   UPDATE Hesaplar SET Bakiye = Bakiye - 100.00 WHERE HesapNo = '12345';
   INSERT INTO HesapHareketleri (HesapNo, IslemTarihi, IslemMiktari) VALUES ('12345', GETDATE(), -100.00);
   COMMIT TRANSACTION;
   PRINT 'Para çekme işlemi başarıyla tamamlandı.';
END
ELSE
BEGIN
   ROLLBACK TRANSACTION;
   PRINT 'Yetersiz bakiye, işlem iptal edildi.';
END;

Bu örnek, transaction başladığında hesap bakiyesini kontrol eder, yeterli bakiye varsa para çekme işlemini gerçekleştirir. Aksi takdirde işlemi iptal eder. İşlem başarılı olduğunda değişiklikler kalıcı hale gelir, aksi takdirde geri alınır.

SQL Server transactions, veritabanı işlemlerinin güvenli ve bütünlüğünü bir şekilde yönetmek için önemli bir araçtır.

Note: İzolasyon seviyeleri (isolation levels) veritabanı işlemlerinin birbirleriyle etkileşimini ve verilere erişimini nasıl kontrol edeceğinizi belirler. İşte bu konsepti daha fazla açıklayan birkaç önemli nokta:

  1. Veritabanı Kilidi (Locking): İşlemler, veritabanında değişiklikler yaparken veya verilere erişirken kilitleme işlemleri kullanır. Bu, diğer işlemlerin aynı verilere aynı anda erişmesini önler. İşlemler kilitlenmiş verilere yazabilir, ancak diğer işlemler aynı verilere yazamaz veya okuyamaz.

  2. İzolasyon Seviyeleri: Veritabanı yönetim sistemleri, farklı izolasyon seviyeleri sunar. Bu seviyeler işlemler arasındaki kilitleme davranışını kontrol eder. Yaygın olarak kullanılan izolasyon seviyeleri şunlardır:
    • Read Uncommitted: Bu seviyede işlem, diğer işlemler tarafından yapılan değişiklikleri görür. Bu, en düşük izolasyon seviyesidir ve veri bütünlüğünü riske atabilir.
    • Read Committed: Bu seviyede işlem, başka işlemler tarafından yapılan değişiklikleri görmez. Ancak, işlem kilitlenen verilere erişirken diğer işlemler tarafından engellenebilir.
    • Repeatable Read: Bu seviyede işlem, başka işlemler tarafından yapılan yeni satır eklemelerini görmez. Ancak, mevcut satırların değiştirilmesini görebilir.
    • Serializable: Bu seviye, işlemleri tamamen izole eder ve hiçbir işlem diğerinin üzerine yazma yapamaz. Ancak bu seviye, performans açısından maliyetli olabilir.
  3. Kilitlerin Etkisi: İşlemler ne kadar uzun süre çalışırsa, kilitlenen verilere erişim süresi o kadar uzar. Uzun süren işlemler, diğer işlemlerin beklemesine ve hatta ölümcül kilitlenmelere deadlock neden olabilir.

Sonuç olarak, veritabanı işlemlerinin mümkün olduğunca kısa ve etkili olması önemlidir. Transaction lar uzun süre çalışmamalı ve gereksiz yere fazla veriyi kilitlememelidir. Doğru izolasyon seviyesini seçmek de önemlidir, çünkü daha yüksek izolasyon seviyeleri, performans açısından daha maliyetli olabilir, ancak veri bütünlüğünü artırabilir. Bu nedenle, transaction ve izolasyon seviyelerini dikkatlice planlamak ve optimize etmek veritabanı performansını iyileştirmeye yardımcı olabilir.

1.13 - Tablo Satır Sayısını Alma

Veritabanındaki belirli bir tablonun toplam satır sayısını bulmak için kullanılabilir.

1
SELECT COUNT(*) AS [TotalRowCount] FROM table_name

Tüm tablolar için satır sayısını elde etmek de mümkündür.

1
2
3
4
5
6
SELECT [Tables].name AS [TableName],
  SUM( [Partitions].[rows] ) AS [TotalRowCount]
FROM sys.tables AS [Tables]
JOIN sys.partitions AS [Partitions] ON [Tables].[object_id] = [Partitions].[object_id] AND [Partitions].index_id IN ( 0, 1 )
--WHERE [Tables].name = N'table name' /* Belirli bir tabloyu aramak için yorumu (--) kaldırın */
GROUP BY [Tables].name;
This post is licensed under CC BY 4.0 by the author.