1 Ekim 2016 Cumartesi

SQL Server Ayarları İçin T-SQL Komutları

SET NO COUNT : set nocount on olarak ayarlandığında, sayım döndürülmez. set nocount off olduğunda, sayısı döner.   Yapılması gereken sorgudan önce bu komutu çalıştırmaktır.
USE [AdventureWorks2016CTP3]
GO
SET NOCOUNT OFF;
GO
-- Display the count message.
SELECT TOP(5)LastName
FROM Person.Person
WHERE LastName LIKE 'A%';
GO
-- SET NOCOUNT to ON to no longer display the count message.
SET NOCOUNT ON;
GO
SELECT TOP(5) LastName
FROM Person.Person
WHERE LastName LIKE 'A%';
GO
-- Reset SET NOCOUNT to OFF
SET NOCOUNT OFF;
GO 
SET ANSI_NULLS : SQL Server Null değerlerde where ifadesi kullanırken  nasıl bir ifadenin yazılacağı ANSI_NULLS özelliğine bağlıdır.  ANSI_NULLS özelliği ON olarak düzenlendiğinde  NULL ifadesi ile yapılan karşılaştırmalar false sonucunu döndürür yani arama listesine dahil edilmez.  Sorgu sonucunu dahil etmek için IS NULL  ve IS NOT NULL kullanılır. 
SQL Server varsayılan olarak ON modundadır.
ANSI_NULLS özelliğini OFF olarak düzenlendiğinde null kayıtlar diğer kayıtlarla karşılaştırılabilir duruma getirilir.

-- Create table t1 and insert values.
CREATE TABLE t1 (a INT NULL)
INSERT INTO t1 values (NULL)
INSERT INTO t1 values (0)
INSERT INTO t1 values (1)
GO

-- Print message and perform SELECT statements.
PRINT 'Testing default setting'
DECLARE @varname int
SELECT @varname = NULL
SELECT *
FROM t1
WHERE a = @varname
SELECT *
FROM t1
WHERE a <> @varname
SELECT *
FROM t1
WHERE a IS NULL
GO

-- SET ANSI_NULLS to ON and test.
PRINT 'Testing ANSI_NULLS ON'
SET ANSI_NULLS ON
GO
DECLARE @varname int
SELECT @varname = NULL
SELECT *
FROM t1
WHERE a = @varname
SELECT *
FROM t1
WHERE a <> @varname
SELECT *
FROM t1
WHERE a IS NULL
GO

-- SET ANSI_NULLS to OFF and test.
PRINT 'Testing SET ANSI_NULLS OFF'
SET ANSI_NULLS OFF
GO
DECLARE @varname int
SELECT @varname = NULL
SELECT *
FROM t1
WHERE a = @varname
SELECT *
FROM t1
WHERE a <> @varname
SELECT *
FROM t1
WHERE a IS NULL
GO

-- Drop table t1.
DROP TABLE t1


SET ANSI_PADDING :ANSI_PADDING açık olduğunda Varchar değerleri ile boşluklar doldurulur ve Varbinary değerler null ile doldurulur .Gelecek sürüm Microsoft SQL ServerANSI_PADDING on her zaman olacaktır ve açıkça seçeneği off için ayarlanmış tüm uygulamaları bir hata üretecektir.
PRINT 'Testing with ANSI_PADDING ON'
SET ANSI_PADDING ON;
GO
CREATE TABLE t1 (
   charcol CHAR(16) NULL,
   varcharcol VARCHAR(16) NULL,
   varbinarycol VARBINARY(8)
);
GO
INSERT INTO t1 VALUES ('No blanks', 'No blanks', 0x00ee);
INSERT INTO t1 VALUES ('Trailing blank ', 'Trailing blank ', 0x00ee00);
SELECT 'CHAR' = '>' + charcol + '<', 'VARCHAR'='>' + varcharcol + '<',
   varbinarycol
FROM t1;
GO
PRINT 'Testing with ANSI_PADDING OFF';
SET ANSI_PADDING OFF;
GO
CREATE TABLE t2 (
   charcol CHAR(16) NULL,
   varcharcol VARCHAR(16) NULL,
   varbinarycol VARBINARY(8)
);
GO
INSERT INTO t2 VALUES ('No blanks', 'No blanks', 0x00ee);
INSERT INTO t2 VALUES ('Trailing blank ', 'Trailing blank ', 0x00ee00);
SELECT 'CHAR' = '>' + charcol + '<', 'VARCHAR'='>' + varcharcol + '<',
   varbinarycol
FROM t2;
GO
DROP TABLE t1
DROP TABLE t2

SET QUOTED_IDENTIFIER :SQL Server’da QUOTED_IDENTIFIER özelliği ile SQL Server için ayrılmış özel kelimeleri kullanarak nesne oluşturmamıza imkan sağlar. “Table,Group,Alter” vb. SQL Server için rezerve edilmiş kelimeleri kullanmamıza imkan sağlayan bir özelliktir.
SQL Server QUOTED_IDENTIFIER özelliği varsayılan olarak açık (ON) durumdadır.

SET QUOTED_IDENTIFIER OFF
GO
-- An attempt to create a table with a reserved keyword as a name
-- should fail.
CREATE TABLE "select" ("identity" INT IDENTITY NOT NULL, "order" INT NOT NULL);
GO
SET QUOTED_IDENTIFIER ON;
GO
-- Will succeed.
CREATE TABLE "select" ("identity" INT IDENTITY NOT NULL, "order" INT NOT NULL);
GO
SELECT "identity","order"
FROM "select"
ORDER BY "order";
GO
DROP TABLE "SELECT";
GO
SET QUOTED_IDENTIFIER OFF;
GO


SET CONCAT_NULL_YIELDS_NULL : SQL Serverda bu ayar ON olduğunda birleştirilen değerlerde NULL değer varsa birleştirme sonucu NULL değer döndürür.  OFF ise NULL değer boş değer olarak kabul edilecektir.
Gelecek sürüm SQL ServerCONCAT_NULL_YIELDS_NULL on her zaman olacaktır ve açıkça seçeneği off için ayarlanmış tüm uygulamaları bir hata üretecektir.

PRINT 'Setting CONCAT_NULL_YIELDS_NULL ON';
GO
-- SET CONCAT_NULL_YIELDS_NULL ON and testing.
SET CONCAT_NULL_YIELDS_NULL ON;
GO
SELECT 'abc' + NULL ;
GO

-- SET CONCAT_NULL_YIELDS_NULL OFF and testing.
SET CONCAT_NULL_YIELDS_NULL OFF;
GO
SELECT 'abc' + NULL;
GO
  
SET ANSI_WARNINGS : ON olarak ayarlandığında SUM, AVG, MAX, MIN, STDSAPMA, STDSAPMAS, VAR, VARP, ya da COUNT toplama işlemleri boş değer verdiğinde bir uyarı mesajı oluşur eğer OFF olarak ayarlanmışsa bir hata verilmez.
USE AdventureWorks2012;
GO

CREATE TABLE T1 (
   a INT,
   b INT NULL,
   c VARCHAR(20)
);
GO

SET NOCOUNT ON

INSERT INTO T1
VALUES (1, NULL, '');
INSERT INTO T1
VALUES (1, 0, '');
INSERT INTO T1
VALUES (2, 1, '');
INSERT INTO T1
VALUES (2, 2, '');

SET NOCOUNT OFF;
GO
 
PRINT '**** Setting ANSI_WARNINGS ON';
GO
 
SET ANSI_WARNINGS ON;
GO
 
PRINT 'Testing NULL in aggregate';
GO
SELECT a, SUM(b)
FROM T1
GROUP BY a;
GO
 
PRINT 'Testing String Overflow in INSERT';
GO
INSERT INTO T1
VALUES (3, 3, 'Text string longer than 20 characters');
GO
 
PRINT 'Testing Divide by zero';
GO
SELECT a / b AS ab
FROM T1;
GO
 
PRINT '**** Setting ANSI_WARNINGS OFF';
GO
SET ANSI_WARNINGS OFF;
GO
 
PRINT 'Testing NULL in aggregate';
GO
SELECT a, SUM(b)
FROM T1
GROUP BY a;
GO
 
PRINT 'Testing String Overflow in INSERT';
GO
INSERT INTO T1
VALUES (4, 4, 'Text string longer than 20 characters');
GO
SELECT a, b, c
FROM T1
WHERE a = 4;
GO

PRINT 'Testing Divide by zero';
GO
SELECT a / b AS ab
FROM T1;
GO

DROP TABLE T1


SET ARITHABORT:ON olarak ayarlandığında Sorgu yürütme sırasında taşma veya tarafından sıfıra bölme hatası oluştuğunda, bir sorgu sona erer. Eğer hata işlem sırasında meydana gelirse, işlem geri alınır.
off olarak ayarlandığında yukarda bahsedilen hatalardan biri meydana geldiğinde bir uyarı mesajı görüntülenir ama sorgu ya da işlem hiç bir hata olmamış gibi sürece devam eder.
set arithabort hesaplanmış klonlardaki indeksleri ve index viewları oluştururken ya da işlerken, on olarak ayarlanmalıdır.

-- SET ARITHABORT
-------------------------------------------------------------------------------
-- Create tables t1 and t2 and insert data values.
CREATE TABLE t1 (
   a TINYINT,
   b TINYINT
);
CREATE TABLE t2 (
   a TINYINT
);
GO
INSERT INTO t1
VALUES (1, 0);
INSERT INTO t1
VALUES (255, 1);
GO

PRINT '*** SET ARITHABORT ON';
GO
-- SET ARITHABORT ON and testing.
SET ARITHABORT ON;
GO

PRINT '*** Testing divide by zero during SELECT';
GO
SELECT a / b AS ab
FROM t1;
GO

PRINT '*** Testing divide by zero during INSERT';
GO
INSERT INTO t2
SELECT a / b AS ab 
FROM t1;
GO

PRINT '*** Testing tinyint overflow';
GO
INSERT INTO t2
SELECT a + b AS ab
FROM t1;
GO

PRINT '*** Resulting data - should be no data';
GO
SELECT *
FROM t2;
GO

-- Truncate table t2.
TRUNCATE TABLE t2;
GO

-- SET ARITHABORT OFF and testing.
PRINT '*** SET ARITHABORT OFF';
GO
SET ARITHABORT OFF;
GO

-- This works properly.
PRINT '*** Testing divide by zero during SELECT';
GO
SELECT a / b AS ab 
FROM t1;
GO

-- This works as if SET ARITHABORT was ON.
PRINT '*** Testing divide by zero during INSERT';
GO
INSERT INTO t2
SELECT a / b AS ab 
FROM t1;
GO
PRINT '*** Testing tinyint overflow';
GO
INSERT INTO t2
SELECT a + b AS ab
FROM t1;
GO

PRINT '*** Resulting data - should be 0 rows';
GO
SELECT *
FROM t2;
GO

-- Drop tables t1 and t2.
DROP TABLE t1;
DROP TABLE t2;

GO

15 Mayıs 2016 Pazar

Databasede Yapılan Değişiklikleri İzlemek

DBAlerin genel problemlerinden bir tanesi databasede yapılan değişiklikleri izlemektir. Bunun için kullanılan 3  yöntem olsada ben bu makalemde sizlere DDL kullanarak değişiklikleri izlemeyi anlatacağım. Diğer iki yöntem olan Extent Events ve Service Broker yönetimini ise daha sonra anlatmayı planlıyorum

Database Tablomu kim drop etti?
Databasede bulunan Viewde kim değişiklik yaptı?
Databasede bulunan Function ve Stored Procedurde kim değişiklik yaptı?

-------CREATE table to store changes--------

CREATE TABLE [dbo].[ChangeLog]
( [LogId] [int] IDENTITY(1,1) NOT NULL,
[DatabaseName] [varchar] (256) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL,
[EventType] [varchar](50) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL,
[ObjectName] [varchar](256) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL,
[ObjectType] [varchar](25) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL,
[SqlCommand] [varchar](max) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL,
[EventDate] [datetime] NOT NULL CONSTRAINT [DF_EventsLog_EventDate] DEFAULT (getdate()),
[LoginName] [varchar](256) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL
) ON [PRIMARY]

go

---CREATE DATABASE TRIGGER TO INSERT CHANGES INTO dbo.changelog TABLE--

CREATE trigger backup_objects
on database
for create_procedure, alter_procedure, drop_procedure,
create_table, alter_table, drop_table,
create_function, alter_function, drop_function
as
set nocount on
declare @data xml
DECLARE @client_ip VARCHAR(15)
set @data = EVENTDATA()
SELECT @client_ip = client_net_address
FROM sys.dm_exec_connections
WHERE session_id =@data.value('(/EVENT_INSTANCE/SPID)[1]', 'varchar(256)')
insert into YOURDATABASE.dbo.changelog(databasename, eventtype,
objectname, objecttype, sqlcommand, loginname)
values(
@data.value('(/EVENT_INSTANCE/DatabaseName)[1]', 'varchar(256)'),
@data.value('(/EVENT_INSTANCE/EventType)[1]', 'varchar(50)'),
@data.value('(/EVENT_INSTANCE/SchemaName)[1]', 'varchar(256)') +'.'+
@data.value('(/EVENT_INSTANCE/ObjectName)[1]', 'varchar(256)'),
@data.value('(/EVENT_INSTANCE/ObjectType)[1]', 'varchar(25)'),
@data.value('(/EVENT_INSTANCE/TSQLCommand)[1]', 'varchar(max)'),
@data.value('(/EVENT_INSTANCE/LoginName)[1]', 'varchar(256)')+'('+@client_ip+')' )

8 Mart 2016 Salı

SQL Server Linux Üzerinde Çalışabilecek.

SQL Server’ın bundan sonra Linux platformunda da kullanılabileceğini duyurdu Linux için ön inceleme(preview) versiyonu yayınlanan SQL Server’ın tam versiyonun 2017 yılı ortalarında yayınlanması planlanıyor.
SQL Server ile birlikte Linux kullanıcıları açık kaynaklı ücretsiz yazılımların yanında daha çok kurumsal kullanıma hitap eden bir veritabanı yönetim aracına daha sahip olmuş olacaklar. Microsoft‘un Linux platformunda özellikle kurumsal müşterilere karşı Oracle ile rekabette ne kadar başarılı olacağını zamanla göreceğiz ancak Microsoft için artık işletim sistemi değil geliştirdiği servislerin bir numaralı öncelik olduğunu rahatlıkla söyleyebiliriz.
 
IDC‘de kurumsal altyapılar bölümünden sorumlu başkan yardımcısı olan Al Gillen’da Microsoft’un yaptığı bu hamle ile SQL Server’ın adaptasyon oranında yükselmeye geçebileceğini altını çizmiş. Satya Nadella‘da Microsoft’un ”servis, ürün” öncelikli bir şirket olduğunu şu anda ”Veri”nin şirketin temel varlıklarından biri olduğunu ancak Microsoft SQL Server’ın şirketin en fazla öneme sahip stratejik varlığı olmadığının altını çizmiş.
 
 

26 Şubat 2016 Cuma

Primary Key Olmayan Tabloları Bulmak

Bu yazımda sizlere bir databasede Primary Keyi olmayan tabloları bulmanın kolay yolunu anlatmaya çalışacağım. Primary Key olmayan tabloları bulmanın bir çok yolu var. Ben üç tanesini yazmak istiyorum.

1.Yöntem
Bu yöntemde OBJECTPROPERTY  fonksiyonun TableHasPrimaryKey kullanarak tüm tabloları kontrol edilir ve Primary Key olmayan tespit edilir.

use [AdventureWorks2016CTP3]
go
SELECT
SCHEMA_NAME(schema_id) AS [Schema name] ,
name AS [Table name] FROM sys.tables
WHERE
OBJECTPROPERTY(object_id,'TableHasPrimaryKey') = 0



2.Yöntem
En kolay yöntem sys.object adlı viewin kontrol edilmesidir. En kolay yöntem budur.

use [AdventureWorks2016CTP3]
GO
SELECT
  SCHEMA_NAME(schema_id) AS [Schema name]
, name AS [Table name] FROM sys.objects
WHERE
[type]='U' AND object_id
NOT IN (
SELECT parent_object_id FROM sys.objects
WHERE [type]='PK' )




3.Yöntem
Bu yöntem ise sys.tables & sys.key_constraints adlı system viewlerini kullanmaktadır.

use [AdventureWorks2016CTP3]
GO
SELECT
SCHEMA_NAME(schema_id) AS [Schema name]
, name AS [Table name]
FROM sys.tables
WHERE object_id NOT IN
(
SELECT parent_object_id
FROM sys.key_constraints
WHERE type = 'PK'
);

16 Şubat 2016 Salı

SQL Server 2016 Instant File Initialization

Instant File Initialization (Anında Dosya Oluşturulması) 2005 versiyonu ile karşımıza gelen bir özelliktir. Çok hızlı büyüyen veritabanlarında bu özelliğin aktif edilmesi önerilmektedir. Bu özellik sayesinde allocate edilen data dosyaları sıfır ile doldurulmadan anında allocate edilmesidir.

Eğer bu ayar aktif edilmezse allocate işlemi sırasında datafile sıfır ile doldurulmaktadır.

Bu sayede aşağıdaki işlemler çok hızlı bir şekilde yapılabilmektedir.
1-Database Oluşturulması
2-Mevcut veritabanına data file ekleme
3-Mevcut veritabanında datafile boyutunu manuel olarak büyütülmesi
4-Restore İşlemleri

2016 versiyonuna kadar bu işlemleri kurulum sonrasında yaptığımız bir çok ayar gibi kurulum sonrasında yapıyorduk. 2016 versiyonu ile birlikte“Grant Perform Volume Maintenance Task privilege to SQL Server Database engine Service” kutucuğunu işaretleyerek hızlıca yapılabilmektedir.

14 Şubat 2016 Pazar

Bütün Databaselerin AUTO_SHRINK Özelliğinin Açılması veya Kapatılması

Aşağıdaki T-SQL kodunu kullanarak AUTOSHRINK açabilir veya kapatabiliriz.

Kapatılması

DECLARE @name varchar(500)
DECLARE @sql varchar(8000)
SET @sql = ''
DECLARE Database_Cursor CURSOR READ_ONLY FOR
SELECT Name
FROM sysdatabases
WHERE DBID > 4
OPEN Database_Cursor
FETCH NEXT FROM Database_Cursor INTO @name
WHILE @@FETCH_STATUS = 0
BEGINSET @sql = @sql + 'ALTER DATABASE [' + @name + '] SET AUTO_SHRINK OFF' + CHAR(10)
FETCH NEXT FROM Database_Cursor INTO @name
ENDCLOSE Database_Cursor
DEALLOCATE Database_Cursor
print @sql
EXEC(@sql)

29 Aralık 2015 Salı

Sql Server Restart Edilmeden SQL Server Error Log dosyası nasıl yeniden oluşturulur.

Sql Server hata logları DBAlerin bilgilendirme mesajları,uyarılar, kritik olaylar, database recovery bilgileri, kimlik denetim bilgileri ve bunun gibi SQL Server hakkında bir çok bilgiye ulaştığı yerdir.
SQL Server log dosyası Sql Server Database Engine service her başlatıldığında yeniden oluşturulur. Bu makalede sizlere SQL Server Database Engine Servisi başlatılmadan log dosyasının yeniden nasıl oluşturulacağını anlatacağım.
Bir DBA DBCC ERRORLOG komutunu çalıştırarak veya SP_CYCLE_ERRORLOG  sistem stored prosedürünü çalıştırarak, SQL Server hizmeti yeniden başlatmadan SQL Server hata günlük dosyasını yeniden oluşturabilir.
2012 ve sonrası versiyonlarda  log dosyalarının boyutunu 10 MB olarak ayarlamak için  aşağıdaki T-SQL kodu çalıştırılır. Geçerli log dosyasının boyutu 10MB ulaştığında yenisi oluşturulur. Buda dosya boyutunun fazla olmasını engeller.
USE [master];
GO
DBCC ERRORLOG
GO


Aşağıdaki Stored Prosedür ise Sql Server Log dosyasını yeniden oluşturur.
Use [master];
GO
SP_CYCLE_ERRORLOG
GO




6 Ağustos 2015 Perşembe

SQL Server 2014 Yenilikleri-1 (In-Memory OLTP)

Bu yazımda sizlere SQL Server 2014 ile birlikte hayatımıza girmiş olan In Memory OLTP'den bahsetmek istiyorum. SQL Server 2016'nın hayatımıza gireceği bu günlerde SQL Server 2014 ile birlikte Gelen yeniklikler adında uzun zaman önce yazdığım ancak yayınlama fırsatı bulamadığım bu yazı dizimi yayınlama fırsatını ancak bulabildim.

SQL Server 2014 versiyonunu uzun zamandan bu yana kullanmaktayız. Ancak çoğumuz yeni gelen özellikleri ve hayatımıza kattığı kolaylık gözden kaçırabiliyoruz. Aynı şeyler eski versiyonlar içinde geçerli. Bu nedenle yeni bir ürün çıktığında o ürünle birlikte gelen yeni özellikleri çok önemsiyorum.

Yenilikler konusunda ilk yazım SQL Server 2014 ile birlikte gelen In-Memory OLTP adlı yazım olacak.














SQL Server ilk dizayn edildiği yıllarda RAM maliyetleri çok yüksekti. Bu nedenler verilerin diskte tutulup process görmesi gerekiyordu. Teknoloji ilerledikçe bu yapının değiştirilmesi kaçınılmaz bir hal aldı. Ram fiyatları ve işlemci fiyatları inanılmaz derecede düştü. Bu nedenle SQL Server engine modeli üzerinde yeniden yapılandırmaya gidildi ve SQL Server In-Memory OLTP teknolojisi geldi.

SQL Server 2014'teki In-Memory teknolojiyle, işlem uygulamalarını 30 kata kadar hızlandırabilir, 100 kattan daha yüksek hızdaki sorgular ve raporlar sayesinde işletmenizle ilgili bilgileri daha hızlı elde edebilir ve hızlı çözümleme için milyonlarca satırı işleyebilirsiniz.

Memory Optimized Tables and Indexes
İlk önce In-Memory tabloları tutacağımız veritabanında Memory  Optimized Data File Group ve içerisinde File oluşturmanız gerekiyor.

ALTER DATABASE [HekatonDB]
ADD FILEGROUP [InMemFileGroup] CONTAINS MEMORY_OPTIMIZED_DATA
GO
ALTER DATABASE[HekatonDB]
ADD FILE(
NAME=N'InMemFile',
FILENAME=N'C:\SQLData\InMemFile'
) TO FILEGROUP [InMemFileGroup]


Daha sonra Memory-Optimized Tabloyu aşağıdaki gibi oluşturabiliriz.

CREATE TABLE  dbo.sample_memoryoptimizedtable
(
s1 int NOT NULL
PRIMARY KEY NONCLUSTERED HASH (s1)  WITH  (BUCKET_COUNT =1024),
s2 decimal(10,2) NOT NULL
INDEX IDX_s2  HASH (s2) WITH  (BUCKET_COUNT =1024)
) WITH (MEMORY_OPTIMIZED=ON,DURABILITY=SCHEMA_AND_DATA)

Buradaki keywordlerden MEMORY_OPTIMIZED tablonunun memory optimized olup olmadığını belirtmek için kullanılır.  DURABILITY Keywordu ise opsiyenel bir Keyworddur. Belirtilmezse default olarak SCHEMA_AND_DATA olarak belirtilir. Serverın crash olması durumunda hem schema hemde data geri getirilebilir.

NONCLUSTERED HASH Index yeni bir Index türüdür. İleriki makalelerde ayrıntılı olarak bahsetmeyi planlıyorum. NONCLUSTERED HASH Index Memory Optimized tablolara özgü bir index türüdür. Mutlaka eklenmelidir. Tablo DLL olarak compile edildiği için sonradan eklenemez.


Memory Optimized Tablolarda kullanmadıklarımız
*Lob Typelerı Memory Optimized Tablolarda kullanamayız.
*Identity Kullanmayız.
*Tabloyu ALTER TABLE edemeyiz.
*DML Trigger kullanamıyız.
*XML kullanamayız.
*CLR Kullanamayız.
*Foreing Key Kullanamayız.


HASH INDEX
Memory Optimized tablolarda 8 adet Hash Index tanımlanabilir. Index tanımlanırken tabloyu oluştururken bucket_count ile belirttiğimiz hücrelere veriler hash algoritmasından geçerek yerleşir.


RANGE INDEX
Bucket_Count belirtilmek istenmediği durumlarda ve aralık sorgulamalarının sıkça yapılacağı durumlarda bu index türü tercih edilmelidir. Çünkü daha performanslı çalışır.


MEMORY OPTIMIZED TABLOLARA NASIL ERİŞEBİLİRİZ.
1-T-SQL kullanarak erişebiliriz.
2-Native Compiled Stored Procedures kullanarak erişebiliriz.

Erişimi T-SQL ile kullandığımızda performans artışı sağlayabiliriz ancak Native Compiled Stored Procedures kullandığımızda gerçek performansı elde etmiş oluruz.


Native Compiled Stored Procedures normal bir stored procedure yazım şeklindedir.
CREATE PROCEDURE usp_Insert500000Rows
WITH NATIVE_COMPILATION, EXECUTE AS OWNER, SCHEMABINDING
AS
BEGIN ATOMIC WITH (TRANSACTION ISOLATION LEVEL = SNAPSHOT, LANGUAGE = N'English')
DECLARE @i INT = 0
 WHILE @i < 500000
  BEGIN
   INSERT INTO dbo.T1_inmem VALUES (@i, @i/2, GETDATE(), N'my string')
  SET @i += 1
 END
END


DEMO(Yiğit AKTAN'ın Demosunda Alınmıştır.)

-----Memory Optimized Data File Group içeren Bir Database oluşturuyoruz------
CREATE DATABASE [HekatonDB1]
 CONTAINMENT = NONE
 ON  PRIMARY
( NAME = N'HekatonDB1', FILENAME = N'D:\Workload\Databases\SQL2014\HekatonDB1.mdf' , SIZE = 5120KB , FILEGROWTH = 1024KB )
 LOG ON
( NAME = N'HekatonDB1_log', FILENAME = N'D:\Workload\Databases\SQL2014\HekatonDB1_log.ldf' , SIZE = 2048KB , FILEGROWTH = 10%)
GO
ALTER DATABASE [HekatonDB1] ADD FILEGROUP [HekatonDB1_MOD] CONTAINS MEMORY_OPTIMIZED_DATA
GO
ALTER DATABASE [HekatonDB1] SET COMPATIBILITY_LEVEL = 120
GO

USE [HekatonDB1]
GO
IF NOT EXISTS (SELECT name FROM sys.filegroups WHERE is_default=1 AND name = N'PRIMARY')
  ALTER DATABASE [HekatonDB1] MODIFY FILEGROUP [PRIMARY] DEFAULT
GO

------FileGroup'a Bir Tane File Ekliyoruz-----------------------------

USE [master]
GO
ALTER DATABASE [HekatonDB1]
ADD FILE (NAME = N'HekatonDB1_MOD', FILENAME = N'D:\Workload\Databases\SQL2014\HekatonDB1_MOD')
TO FILEGROUP [HekatonDB1_MOD]
GO



-----Disk Bazlı Tablomuzu Oluşturuyoruz.--------------------------------------------------
USE [HekatonDB1]
GO

CREATE TABLE dbo.T1_ondisk
(
c1 int NOT NULL PRIMARY KEY,
c2 int NOT NULL INDEX IDX_C2 NONCLUSTERED,
c3 DATETIME2 NOT NULL,
c4 NCHAR(400)
)
GO


-----Memory Optimized Table oluşturuyoruz--------------------------------------------
USE HekatonDB1
GO

CREATE TABLE dbo.T1_inmem
(
c1 int NOT NULL PRIMARY KEY NONCLUSTERED HASH WITH (BUCKET_COUNT = 20000000),
c2 int NOT NULL INDEX IDX2 NONCLUSTERED HASH WITH (BUCKET_COUNT = 20000000),
c3 DATETIME2 NOT NULL,
c4 NCHAR(400)
) WITH (MEMORY_OPTIMIZED = ON)
GO


-----İkinci Memory Optimized Table Oluşturuyoruz--------------------------------------
USE HekatonDB1
GO
CREATE TABLE dbo.T2_inmem
(
c1 int NOT NULL PRIMARY KEY NONCLUSTERED HASH WITH (BUCKET_COUNT = 20000000),
c2 int NOT NULL INDEX IDX3 NONCLUSTERED HASH WITH (BUCKET_COUNT = 20000000),
c3 DATETIME2 NOT NULL,
c4 NCHAR(400)
) WITH (MEMORY_OPTIMIZED = ON)
GO


-----Diskte Tutulan Tableımıza  500000 kayıt ekliyoruz----------------------------------------
USE [HekatonDB1]
GO
DECLARE @i INT = 0
 WHILE @i < 500000
  BEGIN
   INSERT INTO dbo.T1_ondisk VALUES (@i, @i/2, GETDATE(), N'my string')
  SET @i += 1
 END


-----Memory Optimized Table Native SP Kullanmadan 500000 kayıt ekliyoruz---
USE [HekatonDB1]
GO
DECLARE @i INT = 0
 WHILE @i < 500000
  BEGIN
   INSERT INTO dbo.T2_inmem VALUES (@i, @i/2, GETDATE(), N'my string')
  SET @i += 1
 END

-----Natively Compiled Stored Procedure Oluşturuyoruz----------------------------------
USE [HekatonDB1]
GO
CREATE PROCEDURE usp_Insert500000Rows
WITH NATIVE_COMPILATION, EXECUTE AS OWNER, SCHEMABINDING
AS
BEGIN ATOMIC WITH (TRANSACTION ISOLATION LEVEL = SNAPSHOT, LANGUAGE = N'English')
DECLARE @i INT = 0
 WHILE @i < 500000
  BEGIN
   INSERT INTO dbo.T1_inmem VALUES (@i, @i/2, GETDATE(), N'my string')
  SET @i += 1
 END
END
GO

----Natively Compiled Stored Procedure Çalıştırarak 500000 kayıt ekliyoruz---
EXEC [HekatonDB1].[dbo].[usp_Insert500000Rows]

INSERT, UPDATE, DELETE performansını 30 kat arttırmak konusunda iddialı olan bu teknolojiyi SQL Server 2014 versiyonu ile sizde kullanmaya başlayabilirsiniz.


20 Şubat 2015 Cuma

SQL Server 2012 Yenilikler-Contained Database


Bugün sizlere SQL Server 2012 ile yeni gelen bir özellik olan Contained Database özelliğinden bahsetmek istiyorum. Veritabanı yöneticileri için en önemli problemlerden biriside veritabanlarını bir sistemden diğer sisteme taşınmasıdır. Bulut bilişimin son derece revaçta olduğu bu dönemde bu taşıma  işlemi gerçekten DBAler için problem olmaktadır.  Bu taşıma işlemi backup-restore veya attach-detach kullanılarak gerçekleştirilir.

Bu taşıma işlemi sırasında veriler taşınırken sistem seviyesindeki yapılandırmalar aktarılamamaktadır. Contained database yeniliği ile sistem seviyesindeki yapılandırmalarda taşınabilmektedir.

Bulut bilişimin giderek revaçta olduğu günümüzde SQL Server taşıma işlemlerini kolaylaştırmak için Contained Database özellliğini çıkartırken Oracle ise 12c ile birlikte Multitenant teknolojisi çıkarmıştır.

Biz bu makalede Oracle teknolojisi üzerine girmeyeceğiz sadece Sql Server 2012 ile gelen bir özellik olan Contained Database teknolojisinden bahsedeceğiz.

Contained Database, veritabanında sistemde tutulması gereken tüm yapılandırmanın veritabanı üzerinde tutulduğu veritabanı modelidir.  Bütün metadata, yapılandırma ve security ayarları database üzerinde tutulduğu için sunucu bağımlılığı yoktur. Bu sebeble Contained Veritabanları bir sunucudan başka bir sunucuya kolaylıkla ve problemsiz olarak taşınabilir.

Contained Database özelliğini kullanabilmemiz için bu özelliğin aktif hale getirilmesi gerekmektedir. Bu işlem için T-SQL kodlarını kullandığımız gibi Sql Server Management Studio  kullanabiliriz.


 
Yukarıdaki ekranda Contained Database nasıl aktif hale getirildiği T-SQL kodu kullanılarak yaptık. Burada öncelikle Contained Database özelliği advanced bir özellik olduğu için advanced options özelliğini aktif hale getiriyoruz. Daha sonra Contained Database Authentication True hale getiriyoruz. Ve son olarak show advanced options seçeneği pasif hale getiriyoruz.






Bu işlemi yukarıdaki ekranda gösterildiği gibi SSMS ile de yapabilmekteyiz. Properties ekranını kullanarak  Enable Contained Database özelliğini TRUE yapabiliyoruz.

Yukarıdaki işlemler sayesinde Server seviyesinde Contained Database özelliğini aktif ettik. Contained bir veritabanı oluşturmak için 2 yöntem kullanmaktayız. Birinci yöntem T-SQL komutu kullanarak oluşturmak ikinci yöntem ise SSMS kullanılarak.

T-SQL Kullanarak Contained Database oluşturma işlemi aşağıdaki gibidir.



SSMS kullanılarak  oluşturmak için ise Database oluşturulduktan sonra Containment Type özelliği None'dan Partial olarak değişitirilerek yapılabilir. Bunun için Database Properties -Options kısmında Containment Type seçerek yapabiliriz.

Mevcut bir veritabanını ise aşağıdaki T-SQL komutu kullanarak Contained veri tabanı durumuna getirebiliriz.

 
Contained Databaselerde veritabanlarına ait özellikler ve metadata bilgileri Database Engine seviyesinde tutulmazlar. Database üzerinde bulunurlar. Bu nedenle oluşturacağımız kullanıcıları veritabanı seviyesinde oluşturmamız gerekir.

31 Ocak 2015 Cumartesi

Bir Database'in Kimin Tarafından Silindiğini Bulmak

Bir database'in kimin tarafından ve ne zaman drop edildiğini bulmak için aşağıdaki komut kullanılabilir.

SELECT Operation, 
SUSER_SNAME([Transaction SID])
As UserName,  [Transaction Name], [Begin Time], 
[SPID], Description
FROM fn_dblog (NULL, NULL)  WHERE [Transaction Name] = ‘dbdestroy’

25 Ocak 2015 Pazar

Database'de Indexler ve Lokasyonları Hakkında Bilgi Alma

Aşağıda bulunan DMV sayesinde database'de bulunan indexlerin tablo isimlerini, host edildikleri File Groupları ve indexin cluster, non-cluster veya heap-table olup olmadığını çok kolay bir şekilde görebiliriz.
WITH C AS
(
SELECT ps.data_space_id
, f.name
, d.physical_name
FROM sys.filegroups f
JOIN sys.database_files d ON d.data_space_id = f.data_space_id
JOIN sys.destination_data_spaces dds ON dds.data_space_id = f.data_space_id
JOIN sys.partition_schemes ps ON ps.data_space_id = dds.partition_scheme_id
UNION
 SELECT f.data_space_id
, f.name
, d.physical_name
FROM sys.filegroups f
JOIN sys.database_files d ON d.data_space_id = f.data_space_id
)
SELECT [ObjectName] = OBJECT_NAME(i.[object_id])
, [IndexID] = i.[index_id]
, [IndexName] = i.[name]
, [IndexType] = i.[type_desc]
, [Partitioned] = CASE WHEN ps.data_space_id IS NULL THEN 'No'
ELSE 'Yes'
END
, [StorageName] = ISNULL(ps.name, f.name)
, [FileGroupPaths] = CAST(( SELECT name AS "FileGroup"
, physical_name AS "DatabaseFile"
FROM C
WHERE i.data_space_id = c.data_space_id
FOR
XML PATH('')
) AS XML)
FROM [sys].[indexes] i
LEFT JOIN sys.partition_schemes ps ON ps.data_space_id = i.data_space_id
LEFT JOIN sys.filegroups f ON f.data_space_id = i.data_space_id
WHERE OBJECTPROPERTY(i.[object_id], 'IsUserTable') = 1
ORDER BY [ObjectName], [IndexName]

 

Sql Server DateTime Veri Tipindeki Datayı Türkçe Formatında Göstermek

  SQL'de tarihleri farklı formatlarda göstermek için FORMAT fonksiyonunu kullanabilirsiniz. Türkçe kısa tarih formatı genellikle "...