Makale Özeti

Bu yazımızda XML ile ilgili bir konuyu işleyeceğiz. SQL Server 2000 üzerinden, XML formatında veri çekmek

Makale

<Selamlama> Merhaba </ Selamlama>
<Kimlere> tüm yazılım geliştiricilere</Kimlere>

Girişten anlayacağınız üzere bu yazımızda XML ile ilgili bir konuyu işleyeceğiz. SQL Server 2000 üzerinden, XML formatında veri çekmek. İnternetin , hayatımızı dört koldan kuşattığı bir ortamda, ona karşı duyarsız kalmak imkansız. Bir şekilde kendimizi bu varolan yapıya taşımalıyız. Fakat bu elbette kolay olmayacaktır. Çünkü, bu ortama geçmeden önce, bir şekilde bu ortamın kurallarına uymalıyız. Nasıl yurt dışına çıktığımızda, anlaşmak için ingilizce bilmek zorunda kalıyorsak, internet üzerinde çalışacak bir yazılım geliştirmek istiyorsak, ortak bir dilin kurallarına uymalıyız. İnternette veriler için kullanılan bu ortak dil, XMLdir. Tamam Xmlin ne olduğunu, yapısını, nasıl xml formatlı veriler oluşturabileceğimizi öğrendik. Fakat eskiden beri depoladığımız veri tabanı sunucularında sakladığımız bilgilerimize ne olacak. Bunları kullanamayacak mıyız? Çözüm geliştirdiğimiz iş ortaklarımızla, elektronik ortamda bu bilgileri paylaşamayacak mıyız? İşte bu yazıda buna çözüm arayacağız. Öncelikle derin bir nefes alıp rahatlayabilirsiniz. Çünkü şu an SQL Server 200 üzerindeki veri tabanınızda sakladığınız tüm bilgilerinizi kullanabileceksiniz. Bu dönüşümle verilerinizi herhangi bir platformdan izlenebilir hale getireceksiniz. Daha önce veri tabanındaki tablolardan bilgi çekmek için SELECT * FROM tablo adı yapısında sql cümleleri kullanıyorduk. Şimdi de pek farklı bir şey yapmayacağız. Sadece sql cümlesi tarafından bize döndürülecek, kayıt kümesinin Xml formatında döndürülmesini sağlayacağız. Bunun için aşağıdaki komut yapısını kullanırız.

SELECT seçilen alanlar
FROM tablo isimleri
WHERE şart
FOR XML AUTO | RAW | EXPLICIT [, XMLDATA]
[, ELEMENTS]
[,BINARY BASE64]

SQL Server üzerinde xml formatında veri döndüren select cümleleri yazarken 3 farklı mod kullanırız. Bunlar AUTO, RAW ve EXPLICIT moddur. Şimdi bu modları daha yakından tanıyalım.

AUTO Modu

Auto modu, veri tabanınızda belirli bir tablonuzdaki bilgileri, tablo ismini ve alan isimlerini başlık olarak alarak, Xml formatında getirir.

SELECT EmployeeID, FirstName, LastName FROM Employees
FOR XML AUTO

Komutunu çalıştırırsak aşağıdaki çıktıyı elde ederiz.

<Employees EmployeeID="1" FirstName="Nancy" LastName="Davolio"/>
<Employees EmployeeID="2" FirstName="Andrew" LastName="Fuller"/>
<Employees EmployeeID="3" FirstName="Janet" LastName="Leverling"/>
<Employees EmployeeID="4" FirstName="Margaret" LastName="Peacock"/>
<Employees EmployeeID="5" FirstName="Steven" LastName="Buchanan"/>
<Employees EmployeeID="6" FirstName="Michael" LastName="Suyama"/>
<Employees EmployeeID="7" FirstName="Robert" LastName="King"/>
<Employees EmployeeID="8" FirstName="Laura" LastName="Callahan"/>
<Employees EmployeeID="9" FirstName="Anne" LastName="Dodsworth"/>

Eğer xml formatlı verideki alan isimlerini değiştirmek için, değiştirilecek alan isminin yanına, yeni alan ismi yazılır.

SELECT EmployeeID [Sicil Numarası],
FirstName İsim,
LastName Soyisim
FROM Employees Personel
FOR XML AUTO

Bu komut satırının sonucu aşağıdadır. Sicil Numarasının yazımında görülen x0020, boşluk karakterinin XML formatındaki kodudur. Dikkat edilirse, EmployeeID alanının yeni ismi, içerisinde boşluk karakteri de içeren "Sicil Numarası" olarak seçilmiş ve boşluk içerdiği için köşeli parantez içerisinde yazılmış. Alan isimlerinin değiştirilmesinin diğer bir yararı programımızda bir güvenlik açığı oluştuğunda, bir şekilde veriler xml formatlı olarak görüntülendiğinde, bunları gören kişilerin, gerçekte veri tabanı üzerinde kullandığımız alan isimlerini anlamasını zorlaştırmasıdır.

<Personel Sicil_x0020_Numarası="1" İsim="Nancy" Soyisim="Davolio"/>
<Personel Sicil_x0020_Numarası="2" İsim="Andrew" Soyisim="Fuller"/>
<Personel Sicil_x0020_Numarası="3" İsim="Janet" Soyisim="Leverling"/>
<Personel Sicil_x0020_Numarası="4" İsim="Margaret" Soyisim="Peacock"/>
<Personel Sicil_x0020_Numarası="5" İsim="Steven" Soyisim="Buchanan"/>
<Personel Sicil_x0020_Numarası="6" İsim="Michael" Soyisim="Suyama"/>
<Personel Sicil_x0020_Numarası="7" İsim="Robert" Soyisim="King"/>
<Personel Sicil_x0020_Numarası="8" İsim="Laura" Soyisim="Callahan"/>
<Personel Sicil_x0020_Numarası="9" İsim="Anne" Soyisim="Dodsworth"/>

Eğer birkaç tabloyu birleştireceksek JOIN komutunu kullanabiliriz. Ayrıca varolan değerlerden yeni sonuçlar üretip bunları yeni bir alan olarak da gösterebiliriz.

SELECT Siparişler.OrderID SiparişNumarası,
CustomerID Kimden,
OrderDate SiparişTarihi,
ProductID ÜrünKodu,
UnitPrice ÜrünBirimFiyatı,
Quantity SiparişMiktarı,
(UnitPrice*Quantity) ÜrünFiyatı
FROM Orders Siparişler JOIN [Order Details] Ürün
ON Siparişler.OrderID = Ürün.OrderID
WHERE Siparişler.OrderID = 10248
FOR XML AUTO

Bu cümle çalıştırıldığında aşağıdaki sonucu üretir.

<Siparişler SiparişNumarası="10248" Kimden="VINET" SiparişTarihi="1996-07-04">
<Ürün ÜrünKodu="11" ÜrünBirimFiyatı="14.0000" SiparişMiktarı="12" ÜrünFiyatı="168.0000"/>
<Ürün ÜrünKodu="42" ÜrünBirimFiyatı="9.8000" SiparişMiktarı="10" ÜrünFiyatı="98.0000"/>
<Ürün ÜrünKodu="72" ÜrünBirimFiyatı="34.8000" SiparişMiktarı="5" ÜrünFiyatı="174.0000"/>
<Ürün ÜrünKodu="14" ÜrünBirimFiyatı="18.6000" SiparişMiktarı="9" ÜrünFiyatı="167.40000"/>

Eğer "FOR XML AUTO" deyimine Elements parametresini eklersek, Veriler ayrı ayrı taglar arasına biçimde listelenir. Her veriye element muamelesi yapılır, böylece her veri onun içeriğini belirtecek taglar arasında, istemciye sunulur.

SELECT Siparişler.OrderID SiparişNumarası,
CustomerID Kimden,
OrderDate SiparişTarihi,
ProductID ÜrünKodu,
UnitPrice ÜrünBirimFiyatı,
Quantity SiparişMiktar
FROM Orders Siparişler JOIN [Order Details] Ürün
ON Siparişler.OrderID = Ürün.OrderID
WHERE Siparişler.OrderID = 10248
FOR XML AUTO, ELEMENTS

Sonuç:

<Siparişler>
<SiparişNumarası>10248</SiparişNumarası>
<Kimden>VINET</Kimden>
<SiparişTarihi>1996-07-04</SiparişTarihi>
<Ürün>
<ÜrünKodu>11</ÜrünKodu>
<ÜrünBirimFiyatı>14.0000</ÜrünBirimFiyatı>
<SiparişMiktarı>12</SiparişMiktarı>
<ÜrünFiyatı>168.0000</ÜrünFiyatı>
</Ürün>
<Ürün>
<ÜrünKodu>42</ÜrünKodu>
<ÜrünBirimFiyatı>9.8000</ÜrünBirimFiyatı>
<SiparişMiktarı>10</SiparişMiktarı>
<ÜrünFiyatı>98.0000</ÜrünFiyatı>
</Ürün>
<Ürün>
<ÜrünKodu>72</ÜrünKodu>
<ÜrünBirimFiyatı>34.8000</ÜrünBirimFiyatı>
<SiparişMiktarı>5</SiparişMiktarı>
<ÜrünFiyatı>174.0000</ÜrünFiyatı>
</Ürün>
<Ürün>
<ÜrünKodu>11</ÜrünKodu>
<ÜrünBirimFiyatı>18.6000</ÜrünBirimFiyatı>
<SiparişMiktarı>9</SiparişMiktarı>
<ÜrünFiyatı>167.4000</ÜrünFiyatı>
</Ürün>

Binary tipli verilere erişilebilmek için de AUTO modu kullanabiliriz. Örneğin Categories tablosundaki resim bilgilerine erişelim.

SELECT CategoryID, Picture
FROM Categories
WHERE CategoryID = 1
FOR XML AUTO

Bu komut çalıştırıldığında, direk olarak Categories tablosunda Picture alanında bulunan binary bilgiyi getirmekten çok, bu veriye nasıl ulaşabileceğimize dair bilgi getirir. Bu referansla HTTP yoluyla SQL Server üzerindeki binary formattaki veriye ulaşabiliriz.

RAW Modu
Bu mod, veri tabanındaki bilgileri xml formatına taşıyan en basit moddur. RAW modunu kullandığınızda, veriler alan isimlerini, element ismi gibi alarak döndürülür. Veri tabanındaki her kayıt satırı, row olarak gösterilir.

SELECT EmployeeID, FirstName, LastName
FROM Employees
FOR XML RAW

Sonuç:

<row EmployeeID="1" FirstName="Nancy" LastName="Davolio"/>
<row EmployeeID="2" FirstName="Andrew" LastName="Fuller"/>
<row EmployeeID="3" FirstName="Janet" LastName="Leverling"/>
<row EmployeeID="4" FirstName="Margaret" LastName="Peacock"/>
<row EmployeeID="5" FirstName="Steven" LastName="Buchanan"/>
<row EmployeeID="6" FirstName="Michael" LastName="Suyama"/>
<row EmployeeID="7" FirstName="Robert" LastName="King"/>
<row EmployeeID="8" FirstName="Laura" LastName="Callahan"/>
<row EmployeeID="9" FirstName="Anne" LastName="Dodsworth"/>

RAW modunda da birkaç tabloyu birleştireceksek JOIN komutunu kullanırız. AUTO Modundan farkı, Raw modunda oluşturulan veri bloğu kendi içerisinde mantıksal bölümlere ayrılmaz, her kayıt satır yeni bir veri bütünü gibi, yeni bir veri satırı olarak görüntülenir. Bu da veri tekrarına yol açar. Eğer sql cümlesinin sonucuna bakarsanız,
( Siparişler SiparişNumarası="10248" Kimden="VINET" SiparişTarihi="1996-07-04" ) bilgisinin, farklı her ürün için yeniden yazıldığını görürsünüz.


SELECT Siparişler.OrderID SiparişNumarası,
CustomerID Kimden,
OrderDate SiparişTarihi,
ProductID ÜrünKodu,
UnitPrice ÜrünBirimFiyatı,
Quantity SiparişMiktarı,
(UnitPrice*Quantity) ÜrünFiyatı
FROM Orders Siparişler JOIN [Order Details] Ürün
ON Siparişler.OrderID = Ürün.OrderID
WHERE Siparişler.OrderID = 10248
FOR XML RAW

Bu cümle çalıştırıldığında aşağıdaki sonucu üretir.

<row SiparişNumarası="10248" Kimden="VINET" SiparişTarihi="1996-07-04"
ÜrünKodu="11" ÜrünBirimFiyatı="14.0000" SiparişMiktarı="12" ÜrünFiyatı="168.0000"/>

<row SiparişNumarası="10248" Kimden="VINET" SiparişTarihi="1996-07-04"
ÜrünKodu="42" ÜrünBirimFiyatı="9.8000" SiparişMiktarı="10" ÜrünFiyatı="98.0000"/>

<row SiparişNumarası="10248" Kimden="VINET" SiparişTarihi="1996-07-04"
ÜrünKodu="72" ÜrünBirimFiyatı="34.8000" SiparişMiktarı="5" ÜrünFiyatı="174.0000"/>

<row SiparişNumarası="10248" Kimden="VINET" SiparişTarihi="1996-07-04"
ÜrünKodu="14" ÜrünBirimFiyatı="18.6000" SiparişMiktarı="9" ÜrünFiyatı="167.40000"/>

Yine Auto modda olduğu gibi, Raw modda da alan isimlerini değiştirmek mümkündür.

Örnek: Şirketimizde farklı görevlerde çalışan, işçi sayısını bulmak istiyoruz.

SELECT Title Görev,
County Ülke,
Count(*) ÇalışanSayısı
FROM Employees
GROUP BY Title, Country
FOR XML RAW

Sonuç:
<row Görev="Sales Manager" Ülke="UK" ÇalışanSayısı="1"/>
<row Görev="Sales Representative" Ülke="UK" ÇalışanSayısı="3"/>
<row Görev="Inside Sales Coordinator" Ülke="USA" ÇalışanSayısı="1"/>
<row Görev="Sales Representative" Ülke="USA" ÇalışanSayısı="3"/>
<row Görev="Vice President, Sales" Ülke="USA" ÇalışanSayısı="1"/>

Raw modunda iken binary tipli verileri, resim gibi,veri tabanından alabilmek için, "BINARY BASE64" parametresini kullanırız.
SELECT picture resim
FROM categories
WHERE categoryid = 1
FOR XML RAW, BINARY BASE64

Bu komutu çalıştırırsak, resmi binary formatta elde etmiş oluruz.

<row resim="FRwvAAIAAAANA........QUAAAAAAADHrQX+"/>

Element parametresi raw modunda iken kullanılamaz.

Explicit Modu

XML sonuçları üzerinde en etkin olabildiğiniz, istediğiniz formatı kendinizin oluşturabildiği, kontrolün tamamen sizde olduğu bir moddur. Dolayısıyla diğer modlara göre çok daha karmaşık sql cümlelerinin yazılmasını gerektirir. Dolayısıyla bu mod için ayrıca bir makale yazacağım. Bir sonraki makalede görüşmek üzere. Yazılımla kalın...