22 Nisan 2008 Salı

"String or binary data would be truncated."

HATA MESAJI:
"String or binary data would be truncated."

AÇIKLAMA:
Eğer bir alana kaydetmeye çalıştığınız bilginin uzunluğu, o alan için atadığınız veritipinde tanımladığınız uzunluktan daha uzunsa o zaman bu hata ile karşılaşırsınız.

Örneğin:
CREATE TABLE [dbo].[Deneme]
(
No Smallint IDENTITY(1,1) NOT NULL,
Isim Nvarchar(10),
Soyisim Nvarchar(10)
)

Yukarıda tanımını yazdığım tabloya aşağıdaki verileri girmeye çalıştığımızı varsayarsak:

INSERT INTO [dbo].[Deneme](Isim, Soyisim) VALUES('Ekrem', 'Önsoy')

bir sorun çıklamayacaktır, fakak aşağıdaki kaydı girdiğimizde:

INSERT INTO [dbo].[Deneme](Isim, Soyisim) VALUES('Abdurrezzak', 'Hayrettin')

o zaman bu hata ile karşılaşırız. Çünkü 'Abdurrezzak' ismi 11 harften oluşmaktadır, fakat "Isim" alanı 10 karakter genişliğinde tanımlanmıştır.

ÇÖZÜM:
Tablo yapınızdaki alanların tanımlarını tekrar gözden geçirebilirsiniz. İhtiyaçlarınıza göre yeniden yapılandırırsanız sorununuz çözülecektir.

"The server principal "login_adı" is not able to access the database "veritabanı_adı" under the current security context."

HATA MESAJI:
"The server principal "login_adı" is not able to access the database "veritabanı_adı" under the current security context."

AÇIKLAMA:
Erişmeye çalıştığınız veritabanında yeterli yetkilere sahip olmadığınızda bu hatayı alırsınız.

ÇÖZÜM:
SQL Server Instance' ına bağlandığınız Login' in, işlem yapmak istediğiniz veritabanında geçerli bir kullanıcıyla ilişkilendirildiğinden emin olun.

İlişkilendirme işlemi için aşağıdaki adımları izleyebilirsiniz:
- SQL Server Management Studio' yu çalıştırın.
- İlgili SQL Server Instance' ına Login' lerde değişiklik yapabilecek bir kullanıcı hesabıyla bağlanın.
- Security düğümü altındaki Logins düğümünü genişleterek ilgili Login' i bulun ve üzerinde farenin sağ tuşuna tıklayarak özelliklerine (Properties) gidin.
- User Mapping' e tıklayın ve sağ taraftaki "Users mapped to this login" listesinden, ilgili Login' i, ilgili veritabanına bağlayın.

veya aşağıdaki gibi T-SQL kodu kullanabilirsiniz:
USE [veritabanı_adı]
GO
CREATE USER [kullanıcı_adı] FOR LOGIN [login_adı]
GO

Arithmetic overflow error converting numeric to data type numeric.

HATA MESAJI:
"Arithmetic overflow error converting numeric to data type numeric."

AÇIKLAMA:
Bu hata mesajını DECIMAL, NUMERIC gibi veri tiplerini kullanarak işlemler yaptığınızda alabilirsiniz.

Hatanın nedeni ise, yapılan işlemler sonucu ortaya çıkan sayının aktarılacağı değişkenin veri tipi ayarının doğru yapılandırılmamasıdır.

Bir örnekle anlatayım. Örnekte üç adet değişken tanımlıyorum. Birinci değişken "A", herhangi bir sayı, ikinci değişken "B", bu da herhangi bir sayı, üçüncü değişken ise, "A" ve "B" değişkenlerinin toplamının aktarılacağı "Sonuc" isimli değişken. "A" ve "B" değişkenlerine birer sayı atadıktan sonra, "A" ve "B" değişkenlerine atadığım sayıların sonucunu toplama işlemiyle "Sonuc" değişkenine aktarıyorum.

DECLARE @A NUMERIC(26, 6)
DECLARE @B NUMERIC(26, 6)
DECLARE @Sonuc NUMERIC(26, 6)

SET @A = 98765432109876543210.123456
SET @B = 98765432109876543210.123456
SELECT @Sonuc = (@A + @B)

SELECT @Sonuc

Bu işlem sonucunda "Arithmetic overflow error converting numeric to data type numeric." hatası ile karşılaşırım.

Bu sorunu daha iyi anlatabilmek adına, bilmeyen arkadaşlar için "NUMERIC(26, 6)" nın ne anlama geldiğinden de çok kısaca bahsedeyim. Parantez içerisindeki 26 sayısı, Numeric veri tipiyle belirlenen değişkenin içine virgülün sağındaki ve solundaki topram rakam sayısıdır. Bu amaç için en fazla 38 sayısı kullanılabilir. Parantezin içerisinde ve virgülün sağında bulunan 6 sayısı ise, Numeric veri tipinde olan değişkenin içerisindeki sayının ondalık kısmındaki sayı uzunluğunu verir. Örnek olarak "SET @A" komutuyla "A" değişkenine atadığım ondalık kesirli sayıya bakabilirsiniz. Noktanın solunda tam 20 adet rakam vardır, sağında ise 6 adet. Toplamda 26 adet. 27 olursa, bu hata ile karşılaşırsınız.

ÇÖZÜM:
Çözüme de yukarıdaki örnekten devam ederek ulaşacağım.

Bizim bu işlem sonucunda da bu hata ile karşılaşmamızın sebebi, sonucumuzun 27 rakamdan oluşan bir sayı olarak çıkmasıdır. Yani "A" ve "B" değişkenlerinin toplamı 27 adet rakamdan oluşan bir sayıyı kapsamaktadır. Eğer örneğimizdeki "Sonuc" değişkenini DECLARE komutu ile tanımlarken NUMERIC(27,6) şeklinde tanımlarsak, o zaman sonuç hatasız şekilde alınabilecektir.

DECLARE @Sonuc NUMERIC(27, 6)

şeklinde.

"The log in this backup set begins at LSN (Bir sayı), which is too recent to apply to the database. An earlier log backup that includes LSN (Bir sayı)

HATA MESAJI:
"The log in this backup set begins at LSN (Bir sayı), which is too recent to apply to the database. An earlier log backup that includes LSN (Bir sayı) can be restored."

AÇIKLAMA:
Bu hata ile, bir Transaction Log yedeğini açmaya çalışırken alırsınız.

Veritabanı yedeklerini açacağınız zaman sıralama şöyle olmalıdır:
- İlk önce veritabanının tam yedeği (Full Backup) açılır,
- Ardından fark yedeği (Differential Backup),
- En son olarak da kayıt dosyalarının (Transaction Log Backup) yedekleri açılır.

Diyelim ki tam yedeğiniz olan dosyanın adı "Veritabanim.BAK".

Bundan sonra iki kere kayıt dosyasının yedeğini aldınız, "KayitYedek1.TRN" ve "KayitYedek2.TRN"

Yukarıdaki yedek açma sırasına göre ilk önce tam yedeği WITH NORECOVERY komutlarıyla açmanız gerekir (Örn: RESTORE DATABASE veritabanim FROM DISK = N'C:\Yedekler\Veritabanim.BAK' WITH NORECOVERY)

Ardından sırasıyla kayıt dosyasının yedekleri açılır, sıralama ise, tam veritabanı yedeğinden sonraki yedeğin ilk olmasıyla başlar. Yani senaryomuza göre "Veritabanim.BAK" dosyasından sonra açılması gereken kayıt dosyası yedeği "KayitYedek1.TRN" dir. İşte bu sırayı bozarsanız, yani eğer "KayitYedek1.TRN" dosyasından önce "KayitYedek2.TRN" dosyasını açmaya çalışırsanız bu hata mesajıyla karşılaşırsınız.

ÇÖZÜM:
Veritabanı yedek dosyalarını açarken yukarıdaki şekilde verilen sıraya göre açınız.

"Too many backup devices specified for backup or restore; only 64 are allowed. RESTORE DATABASE is terminating abnormally."

HATA MESAJI:
"Too many backup devices specified for backup or restore; only 64 are allowed. RESTORE DATABASE is terminating abnormally."

AÇIKLAMA:
Bu hatayı SQL Server 2005' te aldığınız bir yedeği, SQL Server 2000' de açmaya çalıştığınızda alırsınız.

ÇÖZÜM:
SQL Server 2005' ten alınan bir yedek SQL Server 2000' de açılamaz.

Ayrıca, SQL Server 2005 seviyesine (90) yükseltilmiş bir veritabanını da artık SQL Server 2000 seviyesinde (80) veya daha alt bir seviyede açamazsınız.

11 Nisan 2008 Cuma

"SQL Server Management Studio çok ağır açılıyor!"

Merhaba arkadaşlar,


Bu sorundan muzdarip olan çok kişi gördüm ve bu da beni bu konuda Türkçe bir makale yazmaya yöneltti.

Bu konuda sorun yaşayanlar genelde şöyle diyorlar: "SSMS' i başlatıyorum ve açılmasını beklemektense bir kahve almaya gidiyorum", "SSMS' i çalıştırıyorum ve açılması 45sn. - 1dk. arası sürüyor!"

Evet, eğer siz de böyle bir sorun yazıyorsanız bu makale işinizi görecektir. Çünkü bu yaşanan sorunların hepsinin, burada önerilen çözümlerle çözümlendiğini gördüm.

Burada size dört çözüm önereceğim, birincisi sorununuzu kesin olarak çözmese bile artı bir etkisi olacaktır. İkinci çözümün ise sorununuzu %99 çözeceğine inanıyorum. Üçüncü seçeneği bizzat kullanıyorum ve yararını görüyorum. Dördüncü seçenek de size kalmış (diğer seçeneler gibi).

1. Öneri:
- SSMS' i başlatın.
- Tools -> Options -> Environment -> Help -> Online menüsündeki "When loading Help content" bölümünden eğer SQL Server sunucunuzun internete hiç bağlantısı yoksa "Try local only, not online" seçeneğini seçin ve "OK" düğmesine tıklayarak yeni ayarı kaydedin. Böylece SQL Server yardım bölümünün içeriğini yüklerken sadece yerel diskinize bakacak, internete bağlanmaya çalışmayacak.

Eğer SQL Server sunucunuzun internete bağlantısı varsa ve SQL Server' ın yardım bölümünü kullanıyorsanız (ki bu genelde geliştiriciler ve test makineleri için geçerli bir senaryodur) o zaman "Try local first, then online" seçeneğini de seçebilirsiniz. Böylece SQL Server gene ilk önce yerel yardımı kullanacak, ondan sonra internete bağlanmaya çalışacak.

2. Öneri (ki açılışı yavaşlatan esas neden budur):
- Internet Explorer' ı açın.
- İnternet Seçenekleri -> Gelişmiş penceresindeki "Güvenlik" bölümünün altında bulunan "Check for publisher's certificate revocation" seçeneğinin işaretsiz olduğundan emin olun. Eğer seçiliyse, seçimi kaldırın ve öyle kaydedin.

Peki neden böyle yapmak gerekiyor? Çünkü SQL Server Management Studio' da (daha başka bir çok uygulamada da olduğu gibi) "Managed Code" kullanılmış. Yani yazılım yüklenirken Microsoft' un sitesine bağlanıp, bir listeden bu kodlar teyidi ediliyor. Eğer SQL Server sunucusunda internet bağlantısı varsa o zaman nispeten daha hızlı gerçekleşiyor bu işlem, ama eğer internet bağlantısı yoksa o zaman uzun bir süre SSMS' in açılmasını bekliyorsunuz.

Daha önceden bu konuda bazı güvenlik sorunları yaşadı Microsoft. Bu nedenle böyle bir doğrulama mekanizmasına başvurulmuş, yani bir bakıma haklılar.

3. Öneri:
SSMS' in normalden 1-2 sn. daha erken açılmasını ise "Splash Screen" i kaldırarak sağlayabilirsiniz. "Splash Screen" kavramı, bir uygulamanın tam olarak yüklenmeden önce bir tanıtım ekranı göstermesidir diyebiliriz.

Peki bunu nasıl sağlarsınız? Şöyle; SSMS' i açmak için kullandığınız kısayolun özelliklerine gidin ve hedef adresin sonuna "-nosplash" anahtarını ekleyin. Örnek: "C:\Program Files\Microsoft SQL Server\90\Tools\Binn\VSShell\Common7\IDE\SqlWb.exe" -nosplash

4. Öneri:
"Başlat\Programlar\Microsoft SQL Server 2005\Configuration Tools" menüsündeki "SQL Server Error and Usage Reporting" uygulamasını çalıştırıp açılan penceredeki aşağıda etiketleri yazılı iki seçeneği de boş bırakmak ve öyle kaydetmek.

"Send error reports for all components and instances of SQL Server 2005 to Microsoft or your corporate error reporting server."

"Send feature usage reports for all components and instances of SQL Server 2005 to Microsoft"


Özetle, ikinci öneri bir güvenlik seçeneği, iptal edip SSMS' in hızlı açılmasını sağlamak veya iptal etmeyip güvenliği önplana çıkarmak ise sizin seçiminiz. Bilirsiniz, her şeyin bir bedeli vardır.



Ekrem Önsoy

SQL Server 2005: Bağlı kullanıcıların IP listesini görmek

Bir SQL Server 2005 Instance' ına bağlı kullanıcıların IP adreslerini görmek için aşağıdaki kodu kullanabilirsiniz:

SELECT client_net_address FROM sys.dm_exec_connections

4 Nisan 2008 Cuma

"Kayıt Dosyaları (Transaction Logs) ve Boyut Sorunu"

Merhaba arkadaşlar,


Giriş
SQL Server' da bir veritabanı temel olarak iki dosyadan oluşur. Bunlardan birisi verileri tutulduğu veri dosyasıdır. Diğeri de veri dosyasına karşı yapılan işlemlerin kayıtlarının tutulduğu kayıt dosyası (Transaction Log). Kayıt dosyasının boyutu zaman zaman veritabanına karşı yapılan işlemlere göre çok şişebilir ve bu dosyanın boyutunu düşürmek isteyebilirsiniz. İşte bu yazımda size bu konuda bilgi vereceğim.

Veri Dosyaları (Data Files)
İlk paragrafta sizlere veritabanının iki temel dosyadan oluştuğunu ve bunlardan birisinin de veri dosyası olduğunu söylemiştim. Veri dosyalarının uzantıları varsayılan olarak "*.mdf" tir. Fakat böyle olmak gibi bir zorunluluğu da yoktur. Bu sadece bir standarttır, fakat standartlara bağlı kalmak veya kendi standartlarınızı oluşturmak da çok önemli bir işlemdir.

Kayıt Dosyaları (Transaction Files)
Diğer temel olan dosya ve esas değinmek istediğim ise kayıt dosyasıdır. Kayıt dosyalarının da varsayılan uzantısı "*.ldf" tir. Gene veri dosyaları gibi bunların da dosya uzantılarının "*.ldf" olması zorunlu değildir.

Kayıt dosyasına birçok tip işlem kaydedilmektedir, aşağıdakiler bu işlemler arasındadır:

- Tüm işlemlerin başlangıç ve bitişi,
- INSERT, UPDATE ve DELETE gibi tüm veri değişiklikleri. Yani DML (Data Manipulation Language) işlemleri ve ayrıca DDL (Data Definition Language) işlemleri,
- Tüm "extent" ve "sayfa (page)" ayırma ve kapatma işlemleri,
- Bir tablo veya indeks oluşturma ve silme işlemleri...

Meselâ şöyle sorular geliyor: "Bir tablom var ve çok büyük. Tablonun iskeleti gerekiyor, ama içindeki verileri tamamen boşaltmak istiyorum. Fakat silmeye başlayınca kayıt dosyamın şiştiğini görüyorum. Acaba grup grup mu silsem ve sonra kayıt dosyamı küçültsem sonra aynı işlemleri sırasıyla tekrarlasam olur mu? Daha kolay bir yöntem yok mu?!" Var tabii, meselâ TRUNCATE TABLE ile bir tabloyu sildiğinizde, DELETE komutundan farklı olarak yaptığınız işlem kayıt dosyasına kaydedilmez.

Bazı arkadaşlar ise gerek habergruplarında gerekse de forumlarda şöyle sorular soruyorlar: "Veritabanımda indeksleme işlemi yapıyordum ve bir süre sonra 'kayıt dosyası doldu!' gibi bir hata alıyorum" diyorlar veya "İndeksleme işlemi yaparken kayıt dosyamın boyutunun çok arttığını fark ettim, bu dosyamın boyutu neden büyüyor? Kayıt dosyamı nasıl eski haline getirebilirim?" gibi gibi... Yukarıda da sıraladığım gibi, İndeksleme işlemi de kayıt dosyasında takip edilen bir işlemdir. Bu nedenle indeksleme işlemine dair tüm bilgiler kayıt dosyasına da saklanır. Yapacağınız indeksleme ne kadar geniş çaplıysa, kayıt dosyanız da ona eşit orantılı olarak büyüyecektir. Bu nedenle "kayıt dosyası doldu" hatası almamak için hem kayıt dosyanızın "dosya boyutu sınırı" ayarının düzgün yapılandırdığından, hem de kayıt dosyanızın bulunduğu diskte yeterli alan olduğundan emin olun.

Kayıt Dosyalarının Boyutlarını Küçültme
Kayıt dosyalarınızın boyutlarını küçültmek için ilk önce yedeklerini almanız gerekiyor veya doğrudan içlerindeki Pasif Sanal Kayıtları aşağıdaki örneklerde verdiğim gibi temizleyebilirsiniz:

BACKUP LOG veritabani_adi WITH TRUNCATE_ONLY

veya

BACKUP LOG veritabani_adi WITH NO_LOG

Bu komutlardan birini kullandıktan ve dolayısıyla kayıt dosyasının içerisindeki pasif sanal kayıtları temizledikten sonra, dosyanın fiziksel boyutunu küçültmek için DBCC SHRINKFILE komutunu kullanmalısınız. Aşağıdaki örnekte, Deneme_Log isimli kayıt dosyasının boyutu 1MB' a düşürülecektir. Bu komutu ise aşağıdaki örneğe göre kullanabilirsiniz:

DBCC SHRINKFILE (Deneme_Log, 1);

Not:
Burada göz önünde bulundurmanız gereken şey, kayıt dosyasının içerisindeki sanal kayıtların, en son aktif sanal kayda kadar silinebileceğidir. En son aktif sanal kayıttan daha sonrası silinemez, ta ki o aktif kayıt pasifleşinceye kadar. Aktif ve Pasif Sanal Kayıtlardan aşağıda söz edeceğim.

Ayrıca, bu konu hakkında SQL Server 2008' de bazı değişiklikler var. Bununla ilgili olan ve aşağıda adresini verdiğim makalemi de okuyabilirsiniz:
SQL Server 2008' de 'TRUNCATE_ONLY' ve 'NO_LOG' BACKUP Seçenekleri

Bununla birlikte, "Recovery Models" konusu da doğrudan kayıt dosyasının büyümesiyle alâkalı bir konudur. Meselâ bir kayıt dosyasının içini SIMPLE RECOVERY modelini kullanarak da belli aralıklarla temizleyebilirsiniz. Bu konuda da daha fazla bilgi almak için aşağıdaki makalemi okuyabilirsiniz:
Recovery Models: FULL, BULK LOGGED, SIMPLE

Kayıt dosyalarının dosya boyutlarını sürekli düşük bir değerde tutmak da marifet değildir. Aslında Veritabanı Yöneticisi olmayıp, ama kaynak olmadığı için de bu konuda bir uzmanla çalışamayan kişilerin sürekli bu tür hatalar yaptıklarını gözlemliyorum.

Aşağıdaki paragrafa geçmeden önce hemen kısaca Aktif Sanal Kayıt ve Pasif Sanal Kayıtlardan da bahsetmek istiyorum. Kayıt dosyası içerisindeki kayıtlar Aktif ve Pasif Sanal Kayıtlar olarak sınıflandırılır. Aktif Sanal Kayıtlar, "Rollback" işlemi için açılmış ve başarıyla devam eden işlemler silsilesindeki kayıtlardır. Bu kayıtlar ne kayıt dosyasının yedeği alınarak, ne de başka bir şekilde kesinlikle temizlenemezler. Pasif Kayıt Dosyaları ise, kayıt dosyasının yedeği alınarak temizlenebilir.

Peki neden kayıt dosyalarının boyutları çok düşük olmamalı ve ortamınıza özel belli bir değerde olmalı? Çünkü yukarıda da anlattığım gibi veritabanınızda işlemler gerçekleştirildikçe, bu işlemler kayıt dosyasına işlenirler. Metin dizeleri gibidir kayıt dosyaları da yani belli bir sıraya göre düzenlenir ve yeni işlemler hep sona eklenirler. Her işlemin bir LSN (Kayıt Sırası Numarası) i vardır. Siz işlem yaptıkça dosya büyür de büyür. Ve her büyüme esnasında Veritabanı Motoru işlemleri durdurup, kayıt dosyasının boyutunu büyütür ve işlemlere devam eder.

Şöyle bir örnek vereyim: Veri dosyası boyutu 80GB olan ve her gün veri girişi yapılan ve yoğun kullanılan bir veritabanınız olsun. Bunun kayıt dosyasının boyutunu ise her gün kayıt dosyası yedeğinin alınması işleminin ardından "DBCC SHRINKFILE\SHRINKDATABASE" gibi komutlar kullanarak veya "Maintanence Task" lar kullanarak küçülttüğünüzü varsayalım. Dosya büyüme oranı da 10MB olsun. Bunun anlamı şu dur, kayıt dosyasının yedeğini alma işlemiyle kayıt dosyanızın içindeki Pasif Sanal Kayıtları temizlersiniz, DBCC SHRINK işlemi ile de dosyanın fiziksel boyutunu küçültürsünüz; yani yeni işlemler için kayıt dosyasının içerisinde boşluk kalmaz. Bu nedenle, yeni işlemler için kayıt dosyasının fiziksel boyutunun büyütülmesi gerekir. Zaten yoğun kullanılan bir veritabanı ve büyüme değeri de sadece 10MB. Veritabanı Motorunun sürekli bu dosyanın boyutunu büyütmesi gerekeceği zaman nasıl bir sorunun oluşabileceğini görüyorsunuz değil mi? İşte bu, performans sorunlarına katkıda bulunabilecek önemli bir etkendir.

Sonuç
Gerekli gereksiz kayıt dosyasının küçültülmesi işleminin yapılmamasını tavsiye ederim. Kayıt dosyanızı belli bir büyüklük değerinde bırakın, sürekli büyüyüp küçülmesi gerekmesin. SHRINK işlemlerini gerektiğinde siz yapın, otomatikleştirmeyin. Ayrıca otomatik dosya büyüme değeri için de küçük değerler kullanmayın. Eğer yeriniz varsa bırakın rahatça büyüsün. Ama 80GB' lık veritabanında da 50GB kayıt dosyası olsun demiyorum tabi, yazımın belli yerlerinde de dediğim gibi, her ortamın kendine has özellikleri ve ihtiyaçları vardır. Siz de ayarlarınızı kendi durumunuza uygun yapın.


Ekrem Önsoy