16 Nisan 2010 Cuma

T-SQL ile Fibonacci Serisi

İşte  Fibonacci Serisinin ilk 30 sayısını getiren kod.  @CountOfNumbers'ı değiştirerek daha fazla sayıya da ulaşabilirsiniz. Tabii ki, bigint veri tipinin izin verdiği aralık içinde kalıyorsa.

DECLARE @CountOfNumbers int = 30

DECLARE @Fibonacci TABLE(OrderNo int, FibonacciNumber bigint)
INSERT INTO @Fibonacci(OrderNo,FibonacciNumber)
  VALUES
   (1,0), -- 1. sayı = 0
   (2,1)  -- 2. sayı = 1

DECLARE @i  int = 3, -- 3 den başlatalım, 1. ve 2. yi sayıları tabloya ekledi
        @F1 bigint = 0,
        @F2 bigint = 1,
        @F  bigint



WHILE @i<=@CountOfNumbers BEGIN
  SET @F = @F1 + @F2
  INSERT INTO @Fibonacci(OrderNo,FibonacciNumber) VALUES(@i,@F)
  SET @F1 = @F2
  SET @F2 = @F
  SET @i+=1
END

SELECT * FROM @Fibonacci

Bir Tablodan Rastgele 5 Kayıt Getirmek

-- Önce test etmek için geçici bir tablo tanımlayalım.  
DECLARE @Dummy TABLE(ID int identity(1,1),Number int)

-- Bu tabloya 100 tane kayıt atalım.

-- SQL Server 2008 de değişkeni tanımlarken başlangıç değeri de verebilirsiniz. SQL Server 2008 öncesinde tanımlamayı ve başlangıç değeri vermeyi ayrı satırlarda yapmalısınız.
DECLARE @i int = 1
WHILE @i<=100 BEGIN
  INSERT INTO @Dummy(Number) VALUES(@i*@i)
  SELECT @i+=1 -- Bu da SQL Server 2008 e ait bir özellik. SELECT @i=@i+1 ifadesine karşılık gelir.
END

-- Dataları çekeceğimiz tablomuzu oluşturduk. Bakalım nasıl kayıtlar var.
SELECT * FROM @Dummy


    ID    Number
    1    1
    2    4
    3    9
    4    16
    5    25
    6    36
    ..    ..
    99    9801
    100    10000


Şimdi bu tablodan rastgele 5 tanesini seçelim. 

SELECT TOP 5  *
FROM @Dummy
ORDER BY NewID()

ID    Number
99    9801
25    625
65    4225
51    2601
15    225


NewID fonksiyonu  uniqueidentifier tipinde bir veri oluşturur ve her çektiğinizde de farklı bir değer oluşturur. Her seferinde farklı değerler üreten bu fonksiyonu ORDER BY a ekledim, böylece bizim tablomuzun kayıt yaratılma sırasına göre değil, anlık üretilen NewID ye göre sıralayacak kayıtları. "TOP 5" ifadesi de ilk 5 kaydın gelmesini sağlayacak.

DECLARE @Guid uniqueidentifier = NewID()
SELECT @Guid as Guid

Guid
7facc454-b048-4e44-8d72-b7a9b97fb370




Akla hemen neden random sayı üreten RAND() fonksiyonunu kullanmadık diye bir soru da gelebilir.
RAND() fonksiyonu  bir transaction içinde aynı sayıyı üretir.

SELECT RAND() as Random, * FROM @Dummy

kodunu çalıştırırsak Random kolonunda hep aynı sayının geldiğini görebilirsiniz.

15 Nisan 2010 Perşembe

SQL Server 2008 de kullanıcının yetkili olduğu rolleri öğrenmek.

SQL Server 2008' de kullanıcıların hangi veritabanı ve server rollerinde olduğunu anlamak için kullanılabilecek bir fonksiyon. 

CREATE FUNCTION dbo.fnSecurity_UserRoles(@UserName nvarchar(80))
RETURNS @Result TABLE (Role nvarchar(80),isDBRole bit)
AS BEGIN
  IF @UserName IS NULL
    SET @UserName = system_user

   DECLARE @member_principle_id int
   SELECT @member_principle_id  = principal_id
   FROM sys.database_principals
   WHERE name = @UserName

   INSERT INTO @Result(Role,isDBRole)
   SELECT p.name,1 FROM sys.database_role_members r
   JOIN sys.database_principals  p on p.principal_id = r.role_principal_id 
   WHERE member_principal_id= @member_principle_id

   SELECT @member_principle_id  = principal_id
   FROM sys.server_principals
   WHERE name = @UserName

   INSERT INTO @Result(Role,isDBRole)
   SELECT p.name,0
   FROM sys.server_role_members m
   join sys.server_principals p on m.role_principal_id = p.principal_id
   WHERE m.member_principal_id = @member_principle_id


   RETURN
END 

GO


-- Kullanıcının 'user name' ile listeleyebilir
SELECT * FROM dbo.fnSecurity_UserRoles('birsen')
-- Ya da aktif kullanıcının rollerini getirebiliriz
SELECT system_user, * FROM dbo.fnSecurity_UserRoles(system_user)

SQL Server Business Intelligence İçin Kitap Önerileri

Data Warehouse ve SQL Server Business Intelligence ile ilgili beğendiğim kitaplar.

The Data Warehouse Toolkit: The Complete Guide to Dimensional Modeling (Second Edition)
Ralph Kimball , Margy Ross

Data Warehouse ile ilgilenen herkesin mutlaka okuması gereken bir kitap



Product Details :
  • Paperback: 464 pages
  • Publisher: Wiley; 2 edition (April 26, 2002)
  • Language: English
  • ISBN-10: 0471200247
  • ISBN-13: 978-0471200246
  • Product Dimensions: 9.2 x 7.2 x 1 inches
  • Shipping Weight: 1.5 pounds (View shipping rates and policies)
  • Average Customer Review: 4.5 out of 5 stars See all reviews (33 customer reviews)



Practical Business Intelligence with SQL Server 2005
John C. Hancock (Author), Roger Toren (Author)

Product Details :

  • Paperback: 432 pages
  • Publisher: Addison-Wesley Professional; 1 edition (September 7, 2006)
  • Language: English
  • ISBN-10: 0321356985
  • ISBN-13: 978-0321356987
  • Product Dimensions: 9 x 7 x 1 inches
  • Shipping Weight: 1.2 pounds (View shipping rates and policies)
  • Average Customer Review: 4.3 out of 5 stars See all reviews (6 customer reviews)




Delivering Business Intelligence with Microsoft SQL Server 2008 (Paperback) Brian Larson (Author)


Product Details

  • Paperback: 792 pages
  • Publisher: McGraw-Hill Osborne Media; 2 edition (November 19, 2008)
  • Language: English
  • ISBN-10: 0071549447
  • ISBN-13: 978-0071549448
  • Product Dimensions: 9 x 7.3 x 1.6 inches
  • Shipping Weight: 2.8 pounds (View shipping rates and policies)
  • Average Customer Review: 4.9 out of 5 stars See all reviews (8 customer reviews)



Microsoft SQL Server 2008 Analysis Services Step by Step (Step By Step (Microsoft)) ~ Scott Cameron


Product Details

  • Paperback: 448 pages
  • Publisher: Microsoft Press; 1 edition (April 15, 2009)
  • Language: English
  • ISBN-10: 0735626200
  • ISBN-13: 978-0735626201
  • Product Dimensions: 8.9 x 7.3 x 1.4 inches
  • Shipping Weight: 2 pounds (View shipping rates and policies)
  • Average Customer Review: 5.0 out of 5 stars See all reviews (3 customer reviews)

14 Nisan 2010 Çarşamba

SQL Server da stored procedure daki işlemler ne kadar sürede çalışıyor?

SQL Server'da bir stored procedure yazdınız ve işinde birçok iş yapıyorsunuz. Ancak prosedür yavaş çalışıyor. Ne yaparsınız ?

Ya execution plan'i çalıştırır ve hangi kodun yavaş çalıştığını anlamaya çalışırız veya teker teker kod parçalarını çalıştırız.

Bunun için kullandığım yöntem, stored procedure'a @Timer diye bir parametre eklemek ve bu parametreye 1 geçilirse her işlem için bu zamanları milisaniye cinsinden hesaplamak.

Örnek prosedür :




1 CREATE PROCEDURE dbo.sp_SampleProcedure


2 @Timer smallint = 0


3 AS BEGIN


4


5 IF @Timer = 1 BEGIN


6 DECLARE @Tm TABLE(dt datetime,com varchar(255), tm int NULL)


7 DECLARE @BeginDate datetime,@EndDate datetime,@OldDate datetime


8 SELECT @BeginDate = GETDATE()


9 INSERT INTO @Tm(dt,com) VALUES(GETDATE(),'***BEGIN***')


10 SELECT @OldDate = GETDATE()


11 END


12


13


14 -- Do something


15 SELECT 'This is a sample operation 1 '


16


17 IF @Timer = 1 BEGIN


18 INSERT INTO @Tm(dt,com,tm)

VALUES(GETDATE(),'10.Sample Operation 1',DATEDIFF(ms,@OldDate,GETDATE()))


19 SELECT @OldDate = GETDATE()


20 END


21


22


23 -- Do another thing


24 DECLARE @Result TABLE (OrderNo int, Number int )


25


26 DECLARE @i int = 1,@OrderNo int = 0 , @Step int = 1


27


28 WHILE @i<= 200 BEGIN


29 INSERT INTO @Result


30 VALUES(@OrderNo,@i)


31 SELECT @i = @i + @Step, @OrderNo = @OrderNo + 1


32 END


33


34 SELECT * FROM @Result


35


36 IF @Timer = 1 BEGIN


37 INSERT INTO @Tm(dt,com,tm) VALUES(GETDATE(),'20.Sample Operation 2',DATEDIFF(ms,@OldDate,GETDATE()))


38 SELECT @OldDate = GETDATE()


39 END


40


41


42 -- Do one more operation and get the size of all tables. This will take a time


43


44 CREATE TABLE #TableSize


45 (


46 [name] nvarchar(255),


47 [rows] int,


48 [reserved] varchar(20),


49 [data] varchar(20),


50 [index_size] varchar(20),


51 [unused] varchar(20)


52 )


53 -- Mevcut database deki tüm tablolar için sp_spaceused proc. ü çağırılıp, dönen recordset #TableSize tablosu eklenir


54 EXEC sp_MSforeachtable @command1='INSERT INTO #TableSize EXEC sp_spaceused ''?'' '


55


56 SELECT * FROM #TableSize


57


58


59 IF @Timer = 1 BEGIN


60 INSERT INTO @Tm(dt,com,tm) VALUES(GETDATE(),'30.Get Table sizes',DATEDIFF(ms,@OldDate,GETDATE()))


61 SELECT @OldDate = GETDATE()


62 END


63


64 ---------------------------------------------


65 -- Get the execution time


66 IF @Timer = 1 BEGIN


67 INSERT INTO @Tm(dt,com) VALUES(GETDATE(),'***END***')


68 SELECT @EndDate = GETDATE()


69 INSERT INTO @Tm(dt,com,tm) VALUES(GETDATE(),'Total SP Duration',DATEDIFF(ms,@BeginDate,@EndDate))


70 SELECT * FROM @Tm


71 END


72 SET NOCOUNT OFF


73 SET ANSI_WARNINGS ON


74


75 END


76 GO




Prosedürü oluşturduktan sonra çalıştıralım :

exec sp_SampleProcedure @Timer = 1

En son sonuç olarak bize her işlemin ne kadar sürede çalıştığını gösterecek.

dtcomtm
14.04.2010 15:34***BEGIN***
14.04.2010 15:3410.Sample Operation 10
14.04.2010 15:3420.Sample Operation 26
14.04.2010 15:3430.Get Table sizes4843
14.04.2010 15:34***END***
14.04.2010 15:34Total SP Duration4850

SQL Server 2005 de Web Service ( HTTP EndPoint ) Kullanımı


SQL Server 2005 ile IIS olmadan web service yayımlamak mümkün.. Bunun için SQL Server ınızın Windows 2003 / 2008 server veya XP Service Pack 2 üzerine kurulmuş olması gerekiyor.

SQL Server 2005 ile gelen native xml web servislerin nasıl kullanılacağına bir göz atalım..


AdventureWorks database inde bir procedür yaratalım

CREATE PROCEDURE Production.sp_GetProducts
AS
SELECT
ProductID,
ProductNumber,
Name,
ListPrice
FROM Production.Product

GO

Bu proc. bize tüm ürünlerin adı, numarasını ve liste fiyatını gösterecek ve bu prosedürü bir web method haline getirerek web service ile çağıracağız..

SELECT endpoint_id,name FROM sys.endpoints

Yukardaki kodu çalıştırırsanız, sistem tarafından hazırlnamış ve kullanılan endpoint listesini görebilirsiniz..


CREATE ENDPOINT GetProductsEndPoint
STATE = STARTED
AS HTTP
(
PATH = '/Product',
AUTHENTICATION = (INTEGRATED),
PORTS = (CLEAR),
SITE = 'myServerName'
)
FOR SOAP
(
WEBMETHOD 'ProductList'
(NAME='AdventureWorks.Production.sp_GetProducts'),
BATCHES = DISABLED,
WSDL = DEFAULT,
DATABASE = 'AdventureWorks',
NAMESPACE = 'http://tempUri.org/'
)
go

STATE



  • STARTED : Çalışır durumda. Dinliyor ve cevap veriyor

  • DISABLED : Devre dışı.. Dinleme ve cevap verme işlemleri çalışmıyor

  • STOPPED : Dinliyor ancak istemciden istek geldiğinde hata veriyor



HTTP de kullanılan parametreler:
- PATH = '/Product' WebService e ulaşmak için kullanacağımız virtual path. Örneğin "localhost/Product?wsdl" ile ulaşabileceğiz

- AUTHENTICATION = (INTEGRATED) :


  • INTEGRATED : En güvenilir mod. Mümkünse Kerberos-based authentication, değilse NTLM kullanır.

  • DIGEST - INTEGRATED kadar güvenli değildir. Eğer INTEGRATED kullanamıyorsunuz bu modu kullanabilirsiniz

  • BASIC - En az güvenilir moddur. INTEGRATED or DIGEST yöntemleri kullanılamıyorsa kullanılmalıdır. PORT değeri (SSL) olursa çalışır




- PORTS = (CLEAR),



  • CLEAR : HTTP (default 80) port

  • SSL : HTTPS (default 443)




- SITE = 'myServerName' -- Web service in çalışağı makinenin adıdır.. Direk makine ismi verilir. myServerMyInstance gibi bir SQL server instance yarattıysanız ve host unuz bu server olacaksa bile SITE = myServer verilmelidir.


"http://myServerName/Product?wsdl" web service imizi çalışacağı adres.

Şimdi de bunu nasıl çağıracağımızı basit bir asp.net örneği görelim..



  1. Visual Studio 2005 i açın ve yeni bir web projesi oluşturun..

  2. Projenin üzerine sağ tuş ile gelen menüden "Add Web Reference" a tıklayın..

  3. URL'ye "http://myServerName/Product?wsdl" yazın ve "GO" ya basın.. Bu web service de tanımlı web method ların listesini göreceksiniz. Biz sadece "ProductList" isimli bir method oluşturmuştuk..

  4. WebReference name kutusuna "Products" yazın ve "Add Reference" butonuna basın..



Solution Explorer da App_WebReferences>Products>Product.discomap ve App_WebReferences>Products>Product.wsdl isimli 2 dosya eklendiğini göreceksiniz..

Yeni bir web sayfası ekleyin..
Üzerine bir GridView nesnesi ekleyip ID'sini "grdProducts" olarak değiştirin..

Bir button ekleyin ve ID sini "btnLoadProducts" olarak değiştirin.. Butonun onclick ine kod yazacağız ve grid i dolduracağız..

protected void btnLoadProducts_Click(object sender, EventArgs e)
{
Products.GetProductsEndPoint productEndPoint = new Products.GetProductsEndPoint();
productEndPoint.Credentials = System.Net.CredentialCache.DefaultCredentials;

object[] result = productEndPoint.ProductList();

foreach (object o in result)
{
if (o is DataSet)
{
grdProducts.DataSource = (o as DataSet).Tables[0];
grdProducts.DataBind();
break;
}
}
}

Web Method çağırıldığı zaman bir object array döner. Array in itemlarından bir tanesi de webmethod dan dönen tüm resultset i dataset olarak verir. Biz tek bir recordset döndürdüğümüz için DataSet içerisinde 1 tane DataTable taşıyacaktır. Bu datatable ı , grid in source olarak gösterdiğimizde işimiz bitmiş oluyor..