SQL Server’da UTC Tutulan Zamanı Local Zamana Çevirme

Günümüzde bazı işletmeler yapılan işlemlerin tarih ve saatlerini SQL Server tablolarında tutarken UTC (Universal Time Coordinated) formatında tutmaktadırlar. UTC , GMT (Greenwich Mean Time) ve CET (Central European Time) ile aynı anlama gelmektedir. SQL Server veritabanlarında UTC olarak tutulan bir zaman değerinin, dünyanın farklı bölgelerinden yapılacak olan sorgularda, sorgunun yapıldığı yerel bölgedeki Local Time değerine dönüştürülmesi istenebilir. Böyle bir senaryo ile karşılaşıldığında T-SQL dilinin built-in fonksiyonları akla gelebilir. DATEADD(), DATEDIFF() ve GETUTCDATE() gibi fonksiyonları iç içe kullanarak bir noktaya kadar çözüm geliştirilebilir. Ancak dünyada neredeyse bütün ülkelerde uygulanan “Yaz Saati Uygulaması” sebebiyle bu fonksiyonlardan dönecek olan değer tutarlı olmayacaktır. Örneğin ülkemizde Yaz Saati Uygulaması başlamadan UTC ile olan saat farkı +02:00 iken, Yaz Saati Uygulaması başladığında ise bu fark +03:00 olarak uygulanmaktadır. Peki hem Yaz Saati Uygulamasını dikkate alacak, hem de UTC ile olan saat farkını doğru olarak hesaplayacak hazır bir T-SQL fonksiyonu var mıdır? Heyecanlandığınızı biliyorum, ancak henüz SQL Server 2012 ile beraber böyle bir fonksiyon ne yazık ki bulunmamaktadır.

O zaman, SQL Server’da UTC Time olarak tutulan bir tarihin Local Time değerine çevrilmesi için ne yapılması gerekiyor? Bu makalemizde adım adım bu işlemi gerçekleştireceğiz.

Öncelikle bu işlemi gerçekleştirmek için SQL Server .NET CLR Integration yöntemini kullanarak SQL Server’da olmayan bir fonksiyonu C# kodu ile geliştirip SQL Server’a entegre edeceğiz ve böylelikle SQL Server özelliklerini CLR Integration ile extend etmiş olacağız. İsterseniz adım adım başlayalım:

  • CLR Integration Aktifleştirilmeli

C# kodu ile geliştireceğimiz bir fonksiyonun SQL Server tarafından kullanılabilmesi için, SQL Server CLR Integration özelliği aktif hale getirilmelidir. Bunun için aşağıdaki kodu çalıştırmamız gerekmektedir.

USE master
GO

sp_configure 'clr enabled', 1
GO

RECONFIGURE
GO
  •  UTC Time Değrini Local Time Değerine Dönüştüren C# Kodu Yazılmalı

C# kodu ile fonksiyonumuzu oluşturacağımız için Visual Studio programını açıp yeni bir Class Library projesi açıyoruz.

DLLProjesi

Bir sonraki aşamada açılan sayfadaki kodların tamamını silip aşağıdaki kod bloğunu sayfamıza ekliyoruz:

using System;

using System.Data;

using System.Data.SqlClient;

using System.Data.SqlTypes;

using Microsoft.SqlServer.Server;

public partial class UserDefinedFunctions

{

[Microsoft.SqlServer.Server.SqlFunction]

public static SqlDateTime ConvertToLocalTime(SqlDateTime utcTime)

{

if (utcTime.IsNull)

return utcTime;

else

return new SqlDateTime(utcTime.Value.ToLocalTime());

}

};

Bu işlemden sonra ister F6 tuşuna basarak, istersek de BUILD menüsü altında bulunan “Build Solution” tıklayarak projeyi derliyoruz. Derleme işlemi tamamlandığında yazılan kodların yanında bulunan sarı renkli gösterge yeşil renge dönecektir.

DLLBuild

  • Oluşturulan DLL Dosyası SQL Server’ın Kullanımına Alınır

C# ile yazılan, UTC zamanı Local zamana dönüştüren “ConvertToLocalTime” fonksiyonunu barındıran proje build edilerek derlendiğinde arka tarafta .dll uzantılı bir assembly oluşturulur. Bu dosyayı bulup SQL Server içerisindeki Assembly’lere eklenmelidir. Visual Studio ile açtığımız Class Library projesinin dosya yoluna gidilir. Kurulumdan kuruluma ve bilgisayar adına göre farklı olabileceği göz önüne alınmalıdır. Aşağıda benim dosya yolumu bulabilirsiniz:

C:\Users\Abdullah\Documents\Visual Studio 2012\Projects\UTCTimeConversion\UTCTimeConversion\bin\Debug

Bu klasör altında bulunan UTCTimeConversion (projeyi oluştururken verilen isim) adındaki dll dosyası SQL Server’a eklenecektir. SQL Server Management Studio ile ConvertToLocalTime() adındaki fonksiyonu kullanmak istediğimiz veritabanı altında bulunan Programability sekmesindeki Assemblies klasörünün üzerinde sağ tıklayarak New Assembly seçeneğini tıklıyoruz. Açılan yeni assembly ekleme ekranında, Path To Assembly kısmında bulunan Browse butonuna tıklayarak oluşturduğumuz UTCTimeConversion.dll dosyasını ekliyoruz.

AssemblyEkleme

Oluşturulan assembly SQL Server CLR Integration metodu ile kullanıma alınmış durumdadır.

  • UTC ile Local Time Arasında Dönüşüm Yapacak Olan Fonksiyon Eklenen Assembly’den Oluşturulur

Artık oluşturulan dll dosyası SQL Server kullanımına alındığı için, içerisinde bulunan ConvertToLocalTime() ismindeki fonksiyon create edilebilir. Bunun için assembly eklenen database altında aşağıdaki kod çalıştırılabilir;

USE AdventureWorks2012
GO

CREATE FUNCTION ConvertToLocalTime
(@UTCTime datetime)
RETURNS DATETIME
AS
EXTERNAL NAME [UTCTimeConversion].[UserDefinedFunctions].[ConvertToLocalTime]

Bu işlemin ardından ilgili database altında (benim senaryom için AdventureWorks2012) ConvertToLocalTime() adında bir SQL CLR Integration Function oluşturulmuş olacaktır.

Oluşturduğumuz fonksiyon bir adet datetime veri tipinde parametre alacak ve aldığı bu değeri Yaz Saati Uygulamasını dikkate alarak yerel zamana çevirecektir.

Aşağıda oluşturulan fonksiyonun çalıştırılması test edilmiştir:

USE AdventureWorks2012
GO

SELECT dbo.ConvertToLocalTime('20140322 00:00:00')
SELECT dbo.ConvertToLocalTime('20120411 00:00:00')
SELECT dbo.ConvertToLocalTime('20091029 00:00:00')

Elde edilen sonuçlar aşağıdaki gibidir:

UTCtoLocalTest

Görüldüğü üzere ConvertToLocalTime() fonsiyonuna farklı değerler verilerek farklı yıllardaki Yaz Saati Uygulaması’nı da dikkate aldığını ve Yaz Saati Uygulamasının aktif olduğu aylarda +03:00, Yaz Saati Uygulamasının aktif olmadığı aylarda +02:00 saat eklendiği görülmektedir.

SQL Server CLR Integration kullanılarak oluşturulan C# kodundaki fonksiyonun SQL Server kullanımına alınmasını ve SQL Server’a ait bir fonksiyon gibi kullanılmasını ele almış olduk. Bu sayede UTC Time olarak tutulan zaman değerlerinin farklı ülkelerde ve Yaz Saati Uygulamasını da dikkate alarak Local Time değerinin üretilerek yerel zamanın elde edilmesini incelemiş olduk. Makale hakkında görüşlerinizi, düşüncelerinizi belirtebilirsiniz. Yorumlarınızı iletebilirsiniz. Bir sonraki makalede görüşmek üzere…

Yazar: Abdullah ALTINTAŞ

SQL Server ‘Saving changes is not permitted’ Hatası Çözümü

Microsoft SQL Server kullanılarak database imizde bulunan tablolarımız üzerinde yapısal değişikliklere gitmek istediğimizde karşımıza bazı durumlarda uyarı ekranı gelebilir ve yapmak istediğimiz değişikliklere izin verilmeyeceği bilgisi karşımıza çıkar. Bu gibi bir durumla karşılaştığımızda ne yapmamız gerektiğine hep beraber bakalım.

Öncelikle SQL Server Management Studio aracımızı açalım ve sol tarafta bulunan Object Explorer tabından AdventureWorks2012 database imize bakalım. dbo.DatabaseLog isimli tablomuz üzerinde sağ tıklayalım ve Design ı açalım.

Screenshot (23)

Karşımıza gelen Table Design ekranından dbo.DatabaseLog tablomuz üzerinde bir kaç yapısal değişiklik yapalım. Ben örnek olarak deneme isminde nchar(10) tipinde veri tutan bir kolon ekledim ve default olarak ‘aaa’ değerlerini tutmasını sağladım. Şimdi tabloda daha önce bulunan Object ismindeki kolonun Allow Nulls özelliğini aktiften pasife çevirelim. Değişiklikleri yaptıktan sonra ctrl + s ile veya üst tarafta bulunan kaydet tuşuna basarak değişiklikleri kaydetmeye çalışalım. Karşımıza yapılan değişiklikleri kayıt edemeyeceğimizi bildiren aşağıdaki gibi bir uyarı ekranı gelecektir.

Tablo Değikliği Uyarısı

Saving changes is not permitted. The changes you have made require the following tables to be dropped and re-created. You have either made changes toa table that can’t be re-created or enabled the option Prevent saving changes that require the table to be re-created.

Yapılan bu yapısal değişiklikler için var olan tablonun önce drop edilmesi ardından re-create edilmesi gerektiği şeklinde bir uyarı ile karşılaştık ve yapmak istediğimiz değişiklikler tabloya yansıtılamadı. Peki böyle bir durum ile karşılaşmamak için ne yapılması gerekiyor bakalım.

Öncelikle üst taraftaki Tools menüsü altında bulunan Options sekmesine tıklayalım.

Tools --> Options

Tools –> Options

Açılan Options penceresinde sol taraftaki tablardan Designers bölümüne tıklayalım. Sol tarafta bulunan checkbox lardan

  • Warn about difference detection
  • Warn about tables affected
  • Prevent saving changes that require table re-creation

seçenekleri seçili (aktif) bulunduğunu görebilirsiniz.

Prevent saving changes that require table re-creation

Prevent saving changes that require table re-creation

Bu seçili üç seçeneği kaldıralım (pasif) ve OK diyerek Options penceresini kapatalım.

tabloetkisecimyok

Bu değişikliği yaptıktan sonra az önce üzerinde değişiklik yapmaya çalıştığımız dbo.DatabaseLog tablosuna geri dönelim ve aynı değişiklikleri tekrar yapıp kaydetmeye çalışalım. Gördüğünüz üzere artık tablonun drop edilip tekrar re-create edilmesine gerek kalmadan yapılan değişikliklerin tabloya yansıtılması sağlanmış oldu.

Yazı hakkındaki görüş, öneri ve yorumlarınızı bana iletirseniz çok memnun olurum. Bir sonraki makalede görüşmek üzere…

Yazar: Abdullah ALTINTAŞ

SQL Server Database Attach ve Detach Etme (Veritabanı Ekleme ve Çıkarma)

Microsoft SQL Server kullanarak veritabanlarının oluşturulması ve yönetimini kolay bir şekilde yapabilmekteyiz. Pratikte SQL Server kullanılarak yeni veritabanı oluşturulması ve bu veritabanı üzerinden işlemlerin yapılması kadar, daha önceden oluşturulmuş, içerisinde nesneleri barındıran hazır bir veritabanını SQL Server yönetimine dahil etmek de büyük bir ihtiyaç olarak karşımıza çıkmaktadır. Bu makalemizde daha önceden kendi local makinemizde veya başka bir makinede oluşturulmuş, içerisinde table, stored procedure, trigger, function, view vs. gibi database nesnelerini barındırabilen hazır bir veritabanını SQL Server instance ımızın kullanımına nasıl dahil edebileceğimizi ve artık kullanımını SQL Server instance ımızdan çıkarmak istediğimiz bir database i nasıl çıkarabileceğimizi inceleyeceğiz.

Öncelikle SQL Server yönetimine dahil etmek istediğimiz veritabanına ait Data (.mdf) ve varsa Log (.ldf) dosyalarını kopyalayalım.

AdvFiles

Örneğimizde AdventureWorks2012 database ine ait AdventureWorks2012.mdf ve AdventureWorks2012.ldf dosyalarını kopyaladık ve SQL Server a iat DATA dosyalarının tutulduğu,

C:\Program Files\Microsoft SQL Server\MSSQL11.MSSQLSERVER\MSSQL\DATA klasörü altına yapıştırıyoruz.

DBPath

Bu işlemin ardından SQL Server Management Studio aracını açarak ilgili instance ımıza bağlanalım. Ardından sol tarafta bulunan Object Explorer bölümündeki Databases sekmesinin üzerinde sağ tıklayalım. Karşımıza çıkan menüden Attach bölümüne tıklayalım.

Screenshot (8)

Karşımıza gelecek olan Attach Database ekranında Add butonuna tıklayalım.

Attach1

Az önce dosyalarını yapıştırdığımız AdventureWorks2012 veritabanını seçelim ve OK diyelim.

Attach2

Bu işlemin ardından varsa log dosyasını SQL Server data dosyasına dahil edecektir, log dosyası yok ise SQL Server yeni bir log dosyası oluşturacaktır. OK diyerek ekranda işimiz bittiğinde SQL Server yönetimine AdventureWorks2012 database inin dahil edildiğini görebilirsiniz.

Screenshot (9)

Son olarak SQL Server yönetiminde olan bir database in server kontrolünden nasıl çıkartılacağına bakalım. Bu işlem için SQL Server yönetiminden ayırmak istediğimiz veritabanının üzerinde sağ tıklayarak Tasks –> Detach bölümüne tıklıyoruz.

Screenshot (10)

Karşımıza gelen Detach Database ekranında Ok diyerek veritabanını SQL Server yönetiminden çıkartabiliyoruz.

Detach

Görüldüğü gibi Database Attach ve Detach işlemleri oldukça kolay bir şekilde grafik arayüz üzerinden gerçekleştirilebiliyor. Konu ile ilgili olarak varsa görüş, öneri ve yorumlarınızı ekleyebilirseniz çok memnun olurum. Bir sonraki yazıda görüşmek üzere…

Yazar: Abdullah ALTINTAŞ

SQL Server Configuration Manager Services Hatası

Microsoft SQL Server kurulumu ile beraber gelen toollardan biri olan SQL Server Configuration Manager ile SQL Server instance larımızı ve ilgili SQL Server Service‘lerimizin yönetimini ve gerekli ayarlamaları rahatlıkla yapabilmekteyiz. SQL Server Configuration Manager instance seviyesinde ilgili servislerin durdurulmasını veya restart edilmesini rahatlıkla yapabileceğimiz ve daha birçok özelliği olan bir araç olarak karşımıza çıkıyor.

Ancak bazı durumlarda SQL Server Configuration Manager toolu açıldığında SQL Server Services sekmesi tıklandığında makinemizde kurulu olan instance larımızı ve onlara ait sql service lerimizi göremeyebiliriz. Karşımıza Sql Server Service listesi yerine bir hata mesajı (The remote procedure call failed [0x800706be]) çıkabilir. Bu hata mesajının çıkma sebeplerinden birisi makinemizde var olan bir SQL Server instance ımızdan farklı bir versiyonda (üst veya alt versiyon) yeni bir SQL Server instance ını kurmamız ve SQL Server Configuration Manager tarafından ilgili servislerin algılanamaması olabilir. Örneğin makinemizde SQL Server 2008 R2 kurulu iken SQL Server 2012 kurulumu yaptığımızda ve kurulumdan sonra SQL Server Configuration Manager‘ı çalıştırdığımızda karşımıza aşağıdaki gibi bir hata çıkabilir.

ConfigERR

Böyle bir sorun ile karşılaşmanız durumunda ilk bakmanız gereken yer SQL Server Configuration Manager aracının hangi versiyondaki sürümü default olarak kullandığı olacaktır. Bu işlemi gerçekleştirebilmek için SQL Server Configuration Manager aracı üzerinde sağ tıklayarak Open File Location (Dosya Yolunu Aç) kısmına tıklamamız gerekmektedir. Açılan dosya yolunda SQL Server Configuration Manager kısayolu üzerinde sağ tıklayıp Properties (Özellikler) bölümüne tıklamamız gerekmektedir. Açılan pencerede Shortcut sekmesinde Target (Hedef) bölümünde okunacak dosya yolu bulunmaktadır. Bu kısımda kullanmakta olduğunuz SQL Server versiyonlarına bağlı olarak SQL Server Configuration Manager sürümleri bulunmaktadır. Benim makinemde hem SQL Server 2012 hem de SQL Server 2008 R2 versiyonları kurulu olarak bulunmakta. Dolayısıyla Target kısmındaki dosya yolunda,

C:\Windows\SysWOW64\mmc.exe /32 C:\Windows\SysWOW64\SQLServerManager10.msc

gibi bir hedef bulunuyor. Bu kısımdaki dosya yolunu SQL Server 2012 için gelen SQLServerManager11.msc olarak değiştirildiğinde sorun ortadan kalkacaktır. SQL Server 2012 için Target kısmındaki dosya yolu;

C:\Windows\SysWOW64\mmc.exe /32 C:\Windows\SysWOW64\SQLServerManager11.msc

olarak değiştirilmelidir. Bu değişikliğin ardından SQL Server Configuration Manager tekrar açıldığında sorunun ortadan kalktığını göreceksiniz. Eğer hala aynı sorun ile karşılaşıyorsanız kullanmakta olduğunuz SQL Server versiyonları için güncel Service Pack paketlerini indirip kurmanız sorununuzun çözümünü sağlayabilir. Microsoft SQL Server‘a ait versiyonların ilgili service packlerini aşağıdaki linklerden indirip kurulumunu yapabilirsiniz.

  • Microsoft SQL Server 2012 Service Pack 1 (SP1)

http://www.microsoft.com/en-us/download/details.aspx?id=35575

  • Microsoft SQL Server 2008 R2 Service Pack 2 (SP2)

http://www.microsoft.com/en-us/download/details.aspx?id=30437

  • Microsoft SQL Server 2008 Service Pack 3 (SP3)

http://www.microsoft.com/en-us/download/details.aspx?displaylang=en&id=27594

  • Microsoft SQL Server 2005 Service Pack 4 (SP4 RTM)

http://www.microsoft.com/en-us/download/details.aspx?id=7218

  • Microsoft SQL Server 2000 Service Pack 4 (SP4)

http://www.microsoft.com/en-us/download/details.aspx?id=18290

Makinemizde bulunan versiyonlara ait service packlerin indirilmesinin ardından kurulum işlemine başlayabilirsiniz. Örneğimizde SQL Server 2008 R2 Service Pack 2 kurulumu yapılmaktadır. Kuruluma başlarken kurulum için gerekliliklerin kontrolü yapılmaktadır;

SPc1

Ardından lisans anlaşmasının kabul edilmesi ve hangi özelliklerin yükleneceğinin belirlenmesinin ardından kurulum için gerekli olan dosyaların kontrolü yapılacaktır;

SPC2

Bir sonraki adımda SQL Server service pack kurulumunun ardından nelerin yüklenmiş olacağı ile ilgili bir özet bilgi ekranı çıkmaktadır ve bir sonraki adımda Service Pack kurulumu yapılacaktır.

SPC4

Kurulum tamamlandığında artık SQL Server Configuration Manager aracını açıp hatanın düzelip düzelmediğini kontrol edebilirsiniz.

conf2

Ekranda gördüğünüz gibi SQL Server 2008 R2 Service Pack 2 kurulumunun ardından SQL Server Configuration Manager aracında SQL Server Services sekmesinde çıkan hatanın (The remote procedure call failed [0x800706be]) kaybolduğunu ve onun yerine artık yüklü olan service lerimizin göründüğünü görebilirsiniz.

Bu makalenin ele alınmasında bana destek veren arkadaşım Ali Batuhan Karaçoban’a da buradan teşekkürlerimi sunarım.

Konu hakkındaki düşüncelerinizi, yorum ve görüşlerinizi iletirseniz çok memnun olurum. Bir sonraki yazıda görüşmek dileğiyle.

Yazar: Abdullah ALTINTAŞ

SQL Server Database Diagram Hatası

Microsoft SQL Server üzerinde bir veritabanını attach ettiğimizde veya yeni bir veritabanını SQL Server’a dahil ettiğimizde veritabanı üzerinde database diagram açılamaması gibi bir durum ile karşı karşıya kalınabilir. Bu durumun sebebi ilgili database için henüz bir owner yani veritabanı sahibi belirtilmemiş olmasıdır. Database diagram‘ı kullanmak istediğimiz veritabanına bir owner atayarak bu sorunu çözebiliriz. Aşağıda şekiller üzerinde bu işlemin nasıl gerçekleştirileceğini adımlar halinde aktarıyor olacağım;

Öncelikle attach ettiğim AdventureWorks2008R2 veritabanı altında Database Diagrams üzerinde sağ tıklayrak New Database Diagrams sekmesine tıklıyoruz.

newddd

Bu işlemin ardından aşağıdaki gibi bir uyarı ile karşılaşıyor olacağız.

hata1

Görüldüğü gibi bu uyarı penceresinde AdventureWorks2008R2 veritabanı için bir owner atamamız gerektiği belirtiliyor. Şimdi adım adım veritabanına owner atamasını yapalım. İlk önce ilgili database (AdventureWorks2008R2) üzerinde sağ tıklayark Properties sekmesine tıklıyoruz. Burada database özelliklerini düzenleyebileceğimiz bir arayüz karşımıza çıkıyor olacaktır. Sol taraftaki ana sekmelerden Files bölümüne tıklıyoruz.

prop1

Şekilde de görüldüğü üzere database için Owner kısmı boş gözüküyor. Eğer bildiğimiz bir kullanıcı varsa Owner kısmına bu kullanıcıyı direkt olarak ekleyebilirsiniz. Eklemek istediğiniz kullanıcıların listesini görmek ve seçmek istiyorsanız Owner kısmının en sağ tarafında bulunan üç nokta (…) butonuna tıklayabilirsiniz.

browse1Bu durumda yeni açılan pencerede sağ tarafta bulunan Browse butonuna tıklayarak sistemdeki kullanıcıların (login) listesi karşımıza gelecektir.

selected1

Karşımıza çıkan loginlerden database owner yapmak istediğimiz kullanıcının başındaki checkbox ı işaretliyoruz ve OK ile işlemi bitiriyoruz.

selected2

Seçmiş olduğumuz kullanıcı database owner olarak atanmış oluyor ve artık database properties bölümünde Owner kısmının karşısında seçilen login gözüküyor olacaktır.

selected3

En son olarak OK butonuna tıklayarak ilgili veritabanının sahibini (owner) belirlemiş oluyoruz. Artık AdventureWorks2008R2 veritabanı için Database Diagram‘ı çalıştırabiliriz.

DBDiagram1

Görüldüğü gibi database diagram sorunsuz bir şekilde kullanılabilir duruma gelmiş bulunuyor. Artık diagram üzerinden tablolar eklenip çıkartılarak aralarındaki ilişkiler incelenebilir.

Soru, görüş ve önerilerinizi, yorumlarınızı eklerseniz çok memnun olurum. Bir sonraki yazıda görüşmek üzere.

Yazar: Abdullah ALTINTAŞ

DLL Oluşturulması ve DLL Kullanımı

Visual Studio kullanarak uygulama geliştirirken bazı durumlarda kaynak kodlarımıza DLL (Dynamic Link Library) dosyalarını referans olarak eklemek isteyebiliriz. Bazı durumlarda hazır oluşturulmuş kütüphaneleri (dll) eklemek gerekli olabilirken, bazı durumlarda ise kendi dll dosyamızı oluşturup daha sonra bu kütüphane dosyamızı diğer projelere referans olarak ekleyip kullanmak isteyebiliriz. Bu yazımızda sizlere basit bir dll dosyasının nasıl oluşturulacağını  ve diğer projelerimize bu dll dosyasının nasıl referans edilerek kullanıma alınacağını resimlerle görselleştirerek aktarmaya çalışacağım.

Öncelikle dll dosyası oluşturabilmek için Visual Studio ortamında yeni proje açma ekranından “Class Library” templete ini seçiyoruz ve oluşturacağımız dll dosyamıza bir isim veriyoruz. Örneğimizde OgrenciLibrary isminde bir dll oluşturuyoruz.

ProjectDll

Karşımıza gelen ekranda standart bir class yapısı mevcut durumda ve biz bu classın adını Ogrenci olarak değiştiriyoruz. Daha sonra bu sınıfa ait property (özellik) leri tanımlıyoruz. Burada tanımladığımız Ad, Soyad ve Yas isimli property ler dll oluşturulduktan sonra diğer projelerde kullanılırken karşımıza çıkacaktır. Gerekli tanımlamaları yaptıktan sonra projeyi F6 ile derliyoruz.

OgrenciBase

Class Library projesini F6 ile build ettikten sonra dll dosyasının oluşturulduğunu kontrol edelim. Bunun için projemizin oluşturulduğu dosya yolundaki Bin\Debug klasörü altına bakalım.

Ogrenci1

Gördüğünüz gibi OgrenciLibrary ismindeki dll dosyamız oluşturulmuş durumda. Şimdi bizim oluşturduğumuz bu dll dosyasını başka bir projemize nasıl ekleyeceğiz ve kullanacağız inceleyelim.

Oluşturulan dll dosyasını kullanmak için yeni bir proje açıyoruz. Biz şu an için var olan solution üzerine sağ tıklayarak add ==> new project ile yeni bir console uygulaması açıyoruz.

Screenshot (2)

Şimdi sıra açılan yeni console projesine daha önce oluşturulan dll dosyasını referans etmeye (eklemeye) geldi. Bunun için yeni açılan projede Solution Explorer penceresindeki Referance isimli sekmede sağ tıklayarak referans ekleme penceresine geliyoruz.

Screenshot (1)

Açılan referans ekleme penceresinden oluşturduğumuz dll dosyasını veya başka bir yerden temin ettiğimiz diğer dll dosyasını seçiyoruz ve OK diyerek dll dosyasını projemize ekliyoruz.

Referans1

Bu işlemin ardından References bölümünün altında eklediğimiz OgrenciLibrary ismindeki dll dosyamız gözüküyor ve projemize dahil etmiş oluyoruz. Daha sonra eklenen dll i using ile kullanıma alıyoruz.

Screenshot (3)

Artık projemize oluşturulan dll dosyası eklenmiş durumda ve yeni projemizde dll içerinde bulunan Ogrenci classını ve buna ait Ad, Soyad ve Yas isimli property leri kullanabiliriz. Bununla beraber yeni projemize ait dosya yolundaki Bin\Debug klasörüne bakarsak OgrenciLibrary ismindeki dll dosyasının buraya eklenmiş olduğunu göreceksiniz.

OgrenciKlasor

Yeni uygulamamızda dll e ait Ogrenci sınıfının property lerine değerler vererek ekrana yazdıralım. Örnek olarak Ad için Abdullah, Soyad için ALTINTAŞ ve Yas için ise 26 değerlerini atayalım ve bu değerleri ekrana yazdıralım.

DllKullanim

Son olarak projemizi derleyip çalıştıralım ve sonucu hep beraber görelim:

DLLSon

Gördüğünüz gibi kendi oluşturduğumuz dll dosyasını başka bir projeye referans ettik ve bu dosyadaki Ogrenci ismindeki sınıfı ve elemanlarını kullandık. Kendi oluşturduğumuz dll dosyaları gibi başka yerlerden temin edebileceğimiz diğer dll dosyalarını da projelerimize referans olarak ekleyip kullanabiliriz.

Konuyla ilgili soru, görüş ve önerilerinizi bana bildirirseniz çok sevinirim. Yorumlarınızı bekliyorum. Bir başka yazıda görüşmek üzere…

Yazar: Abdullah ALTINTAŞ

Crystal Report ve Report Viewer Hatası

Visual Studio kullanarak oluşturduğumuz projelerde genelde raporlama gereksinimine sıklıkla ihtiyaç duymaktayız. Bu gibi durumlarda genelde Visual Studio ile birlikte gelen Report Viewer tool u ve SAP tarafından sunulan ve projemize ekleyebileceğimiz Crsytal Report bize verilerimizi rapor haline getirmemizde yardımcı olurlar. Fakat proje ister web tabanlı bir ASP.NET projesi olsun isterse Windows Forms projesi olsun bazı durumlarda verileri rapor haline getirmek sıkıntılı olabiliyor. Bu gibi durumlarda karşımıza çıkan bir hata mesajı üzerinden ne yapmamız gerektiği konusunda biraz bilgi verelim.

The source of the report definition has not been specified

The source of the report definition has not been specified

Genelde projemiz ister C# ile ister VB.Net ile geliştirilmiş olsun Report Viewer kontrolünü Toolbox pencesinden Reporting tabı altından ekledikten sonra ReportViewer kontrolü üzerindeki smart tag kullanılarak bu raporlama aracına uygun bir şekilde veri bind etmek gerekir. Eğer verileri veritabanından uygun bir şekilde getirip bu kontrole bağlayamazsak programımız çalışma esnasında “The source of the report definition has not been specified” tarzında bir mesaj ile karşımıza çıkacaktır. Verilerin gösterilmesi gerekirken bu uyarıyı raporlama ekranında görmemizin ilk muhtemel nedeni yukarıda bahsedildiği üzere verileri doğru bir şekilde bind edememiş olmamızdır.

Peki verileri doğru bir şekilde bind etmemize rağmen projeyi local makinede çalıştırdığımızda sorun çıkmadan raporlara ulaşmamıza rağmen uygulamayı başka bir bilgisayarda çalıştırdığımızda veya server üzerinde yayınlamamıza rağmen başka bilgisayarlarda yine raporlara ulaşamamamız durumunda yine yukarıdaki gibi “The source of the report definition has not been specified” türünde bir ekran ile karşılaşabiliriz. Bu sorunun muhtemel sebeplerinden birisi lokal makinemizde CrystalReportViewer ve ReportViewer kontrollerinin çalışabilmesi için ilgili kurulumun daha önceden yapılmış olmasına rağmen serverda veya başka bir makinada raporların gösterilmesini sağlayacak CrystalReportViewer ve ReportViewer için gerekli kurulumun yapılmamış olmasıdır. Böyle bir durumda server veya uygulamanın çalıştırılacağı bilgisayara aşağıdaki linkte verilen adresten uygun olan uygulamanın indirilip kurulması gerekmektedir.

64 Bit;

http://scn.sap.com/docs/DOC-7824 linklerden MSI 64 Bit oaln seçilmeli,

http://downloads.businessobjects.com/akdlm/cr4vs2010/CRforVS_redist_install_64bit_13_0_4.zip

32 Bit;

http://scn.sap.com/docs/DOC-7824 linklerden MSI 32 Bit oaln seçilmeli,

http://downloads.businessobjects.com/akdlm/cr4vs2010/CRforVS_redist_install_32bit_13_0_4.zip

Uygulamanın çalıştırılacağı bilgisayara bu kurulumlar yapıldıktan sonra raporlarınızın sorunsuz bir şekilde ekrana geleceğini göreceksiniz. Hepinize iyi kodlamalar…

Yazar: Abdullah ALTINTAŞ

Property Kavramı ve Erişim Belirleyiciler (Access Modifiers)

Hangi programlama dilini kullanırsak kullanalım programımızda yer vereceğimiz öğelere bir erişim yetkisi ve kısıtlaması eklemek bazen kaçınılmaz oluyor. Programımızdaki bu öğeler class, interface, delegate, enum, struct, metot, değişken vs. olabilir. C# dilini kullanarak kodlama yapacak olan bir yazılımcı için de bu hususta belirli erişim belirleyici anahtar kelimeler (keywords) mevcuttur. Programımızda yer alan öğelere bu erişim belirleyicileri ön ek olarak ekleyerek erişimlerini kısıtlayabiliriz. Microsoft tarafından C# dili için bize sunulan bu erişim belirleyici (access modifiers) anahtar kelimeler şunlardır:

  • public
  • private
  • protected
  • internal
  • protected internal

Yukarıda belirttiğimiz bu erişim belirleyicileri kısaca açıklamak gerekirse; “public” programdaki öğeye heryerden erişim yetkisi verir, “private” ilgili öğeye sadece tanımlandığı yerden (örneğin class içinden) erişim yetkisi verilir, “protected” ile işaretlenmiş öğeye sadece türetilmiş (inherit edilmiş) class içerisinden erişilebilir, “internal” ile belirlenen öğeye sadece ilgili assembly (uygulama) içerisinden erişilebilir ve bu öğeye uygulama dışından erişim engellenmiş olunur ve son olarak da “protected internal” erişim belirleyicisi protected ve internal belirleyicilerinden herhangi birisinin şartları sağlanmışsa yani öğeye tanımlandığı class içerisinden veya türetilmiş classlar içerisinden ya da aynı assembly içerisinden erişilebilir.

C# ta class ve struct lar için bir erişim belirleyicisi belirtilmez ise varsayılan olarak internal tanımlıdır, aynı zamanda class seviyesinde tanımlanan öğeler de (değişken, metot gibi) yine varsayılan olarak private erişim belirleyicisi ile tanımlanırlar. Burada bir noktayı belirtmekte fayda vardır; struct lar türetmeye girmedikleri ve desteklemedikleri için struct içerisindeki öğeler protected ve protected internal erişim belirleyicilerini alamazlar.

Şimdi yukarıda bahsettiğimiz erişim belirleyicilerinden bazılarına küçük örnekler vererek konuyu pekiştirelim. Örneğin aynı assembly içerisinde tanımlanmış iki class içerisindeki öğelere erişimi inceleyeceğiz:

Programımız içerisinde bir adet Sample isimli class oluşturup içerisine “metin” isimli private değişken ile “erisilenMetin” isimli bir de public değişken tanımlandı. Ayrıca “urunID” isimli bir değişken daha oluşturulmuş olup dikkat edilirse herhangi bir erişim belirleyici verilmemiştir. Yukarıda belirtildiği gibi bu değişken varsayılan olarak zaten private tır. “urunID” isimli değişken için ayrıca “UrunID” isimli bir property (özellik) oluşturulmuştur. Property oluşturabilmek için kursor private tanımlı değişken isminin üzerinde odaklanmış iken ctrl+r+e tuş kombinasyonuna sırasıyla basarak property oluşturma ekranına gelinir. Burada oluşturulacak property için bir ayar yapılmayacaksa ilgili sayfalar enter ile geçilir ve private değişkenimiz için property oluşturulmuş olur. Tabi istenirse bu işlem kod yazarak programcı tarafından da yapılabilirdi. Burada dikkat edilmesi gereken nokta değişken private iken oluşturulan property public erişim belirleyicisini alır. Bunun nedeni bu değişken için değer atama ve ilgili değerini alma gibi işlemler için bir kriter uygulanmak isteniyorsa ilgili property nin get ve set bloklarında bu işlemler yapılmalıdır. “get” bloğu değişkene atanan değeri elde etmek için kullanılır ve return anahtar kelimesi ile bu değeri programa döndürür. “set” bloğu ise değişkene değer atamak için kullanılır. Property konusunu kısaca açıkladıktan sonra örneğimize dönelim. Sample sınıfında tanımladığımız değişkenler ve property e erişim için Program isimli classımızın Main adlı metodunda Sample classımızı new ile örnekliyoruz ve bu classa ait “deneme” isimli bir nesne oluşturuyoruz. Daha sonra oluşturduğumuz “deneme” isimli nesne üzerinden Sample classı öğelerine erişmeye çalışıyoruz. Ekranda görüldüğü gibi private tanımlanmış öğelere erişilemez iken sadece public tanımlı “erisilenMetin” isimli değişkenimiz ile beraber “UrunID” ismli public tanımlı Property e erişebilmekteyiz.

Son olarak property kavramına dönecek olursak onunla ilgili de küçük bir örnek ile konuyu tamamlayalım:

Burada “UrunID” isimli property için değer ataması yapılırken set blogu içerisinde tanımladığımız eğer sıfırdan küçük bir değer atanırsa atanan değerin sıfıra eşit olmasını yok eğer atanan değer sıfırdan büyük ise o zaman atanan değerin olduğu gibi atanmasını sağlıyoruz. İlk etapta “UrunID” ye -5 değeri atanmış ve sonuç ekrana yazdırılmıştır. Görüldüğü gibi -5 değeri atanmaya çalışılsa bile atanan değer negatif olduğu için sıfıra eşitlenmiştir. İkinci durumda ise bu sefer 3 gibi pozitif bir sayı ataması yapılmış ve yine ekrana yazdırılmıştır. Bu durumda 3 değerinin atandığı ekrandan görülmektedir.

Yazar: Abdullah ALTINTAŞ

Stored Procedure Oluşturulması ve Kullanımı

Sql Server ile veritabanı üzerinde yapılan sorgular (select), veri girişleri (insert), veriler üzerinde yapılan güncellemeler (update) ve verilerin veritabanından kaldırılması (delete) gibi işlemleri her seferinde ilgili komutu yazarak işleme koymak Sql Server üzerinde yük oluşturur. Her yazılan sorgu komutu için Sql Server komutu yazım kuralları açısından (syntax) denetler ve sonraki aşamada ilgili tabloların ve alanların var olup olmadığının kontrolü yapılır ve son olarak en kısa ve en hızlı sorgunun nasıl yapılacağı belirlendikten sonra ilgili Sql scripti derlenir ve komut çalıştırılır. İşte biz Sql Server’a bu kadar işi her seferinde tekrarlatmamak için “Stored Procedure” (saklı yordam) adını verdiğimiz yapılardan faydalanırız. Stored Procedure (kısaca sp veya procedure) kullanılarak komutun derlenmesine kadar olan aşamaları bir kez tamamlanır ve procedure her çağırıldığında sadece ilgili komutun çalıştırılması sağlanır. Böylece Sql Server üzerinde daha performanslı sorgular ve komutlar çalıştırılmış olur.

Stored Procedure’ ler hem sorgu komutlarında hem de insert, update ve delete işlemlerinde kullanılabilir. C# taki kullanılan metot (yordam) kavramına benzerler. Parametre alabilirler ve geriye değer döndürebilirler. Geriye değer döndürme işlemi “return” anahtar kelimesi ile yapılır.

Stored Procedure tanımlamasını iki şekilde göstereceğiz. İlk olarak parametresiz bir procedure yazımının şablonunu verelim:

create proc/procedure   <procedure adı>                                                                          as                                                                                                                                     begin                                                                                                                                                                                                                                                                       < yazılacak ilgili sorgu komutu>                                                                                     

end

İkinci olarak ise parametreli bir procedure yazımının şablonunu verelim:

create proc/procedure   <procedure adı>

(

@prm1,

@prm2   

as

begin                                                                                                                                                                                                                                                                       < yazılacak ilgili sorgu komutu>                                                                                       

end

Procedure’ lere isim verilirken genellikle “usp” ön takısı verilerek isimlendirilirler. Ayrıca procedure ler de metotlar gibi iç içe çağrılabilirler. Procedure oluşturulurken “with encryption” ifadesi eklenirse procedure şifrelenmiş olur. Şimdi bir adet parametre almayan bir procedure oluşturalım:

Yukarıda görüldüğü gibi AdventureWorks veritabanı kullanıma alınmış ve spUrunleriGetir adlı bir procedure oluşturulmuştur. Burada dikkat edilmesi gereken nokta oluşturulan procedure çalıştırılmak istendiğinde “exec <procedure adı>” şeklinde çağırılması gerektiğidir. Aynı şekilde “execute <procedure adı>” şeklinde veya direkt olarak “<procedure adı>” yazılarak da ilgili procedure çalıştırılablir. Son olarak bir de parametre alan ve geriye değer döndüren bir sp yazalım:

Yukarıdaki örneğimizde alınan “@ID” parametresine “3” değeri verilmiş olup geriye bu kategoriden 22 adet ürün olduğunu “return” anahtar kelimesi ile aldık ve procedure çağırıldığında dönüş değeri bir değişkende tutularak ekrana sonucunu yazdırmış olduk.

Yazar: Abdullah ALTINTAŞ

Partial Class Kavramı

C# programlarımızda bazı sınıf (class) lar çok fazla sayıda sınıf elemanına sahip olabilir. Özellikle büyük projelerde sınıfların karışık yapıda olmasını engellemek için sınıfı belirli parçalara bölmek daha mantıklı bir yol olacaktır. Böylece sınıfın ve projenin görünümü ve yönetimi daha kolay bir hal alacaktır. İşte bu yüzden büyük sınıflarımızı C# taki “partial” anahtar kelimesi yardımıyla parçalara bölebiliriz. Bunu yapabilmek için parçaya ayırdığımız class ın başına “partial” eklememiz yeterli olacaktır.

Aşağıdaki örneğimizde bir adet sınıfımızı mantıklı olacak bir şekilde özellikleri(properties) bir parçada, metotları(methods) da ayrı bir parçada tutarak class ın karışık bir yapıda olması önlenmiş olur ve yönetimi kolaylaşır.

Görsel

Burada “Sinif” adlı class ımız partial anahtar kelimesi ile bölümlenmiş ve class a ait değişkenler bu parçada tanımlanmışlardır.

Görsel

Burada ise yine aynı class a ait metotlar bu sefer farklı bir parçada tutularak özellikler ile birbirine karışması engellenmiş olur.

Partial class kavramı WindowsForms uygulamalarında da karşımıza çıkmaktadır. Formun designer bölümü bir parçada kodlama bölümü ise ayrı bir parçada tutularak programcıya kolaylık sağlanmıştır. Her ne kadar sınıfımız parçaya ayrılmış gibi görünse de program çalıştırıldığında class ımız tek class gibi hareket edecek ve parçaya ayrılmış olan kodlarımız derlenip program tarafından bir bütün olarak çalıştırılacaktır.

Yazar: Abdullah ALTINTAŞ