<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>SQL Server ASP.NET C# Kitabı</title>
	<atom:link href="http://www.ahmetkaymaz.com/wp-seo-link-holder_akaymaz.php/feed/?404;http://www.ahmetkaymaz.com:80/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.ahmetkaymaz.com</link>
	<description>SQL Server, C#, VB.NET, ASP.NET, AJAX ile ilgili örnek kitap ve ipuçları</description>
	<lastBuildDate>Wed, 08 Feb 2012 14:03:52 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>VS &#8211; JScript Editor Extensions</title>
		<link>http://www.ahmetkaymaz.com/2010/06/12/vs-jscript-editor-extensions/</link>
		<comments>http://www.ahmetkaymaz.com/2010/06/12/vs-jscript-editor-extensions/#comments</comments>
		<pubDate>Sat, 12 Jun 2010 13:51:03 +0000</pubDate>
		<dc:creator>Ahmet Kaymaz</dc:creator>
				<category><![CDATA[C#, VB.NET, ASP.NET]]></category>

		<guid isPermaLink="false">http://www.ahmetkaymaz.com/?p=368</guid>
		<description><![CDATA[Visual Studio gibi başarılı bir editörün özellikle 2010 sürümünden sonra geliştirilen eklentileri programcılar için önemli kolaylıklar sağlamaktadır. Fakat çoğu zaman editörü yavaşlattığı için zorunlu olmadıkça bu eklentileri yüklemiyorum. Fakat geçenlerde Java Script tarafında code-behind tarafındaki #region ifadesine benzer bir yöntemin olup olmadığını araştırırken Microsoft&#8217;un çıkardığı &#8220;JScript Editor Extensions&#8221; isimli extension çok işimi gördü. Bu sayede [...]]]></description>
			<content:encoded><![CDATA[<div class="google_plus_one"><g:plusone size="standard" count="true" url="http://www.ahmetkaymaz.com/2010/06/12/vs-jscript-editor-extensions/"></g:plusone></div><p>Visual Studio gibi başarılı bir editörün özellikle 2010 sürümünden sonra geliştirilen eklentileri programcılar için önemli kolaylıklar sağlamaktadır. Fakat çoğu zaman editörü yavaşlattığı için zorunlu olmadıkça bu eklentileri yüklemiyorum. Fakat geçenlerde Java Script tarafında code-behind tarafındaki #region ifadesine benzer bir yöntemin olup olmadığını araştırırken Microsoft&#8217;un çıkardığı &#8220;<b>JScript Editor Extensions</b>&#8221; isimli extension çok işimi gördü. Bu sayede Java Script tarafındaki parantezlerle boğuşmamış olacağız. Daha kolay iç içe kod yazabileceğiz. </p>
<p><img src="http://www.ahmetkaymaz.com/wp-content/uploads/JScript_Editor_Extensions.png"></p>
<p>Bu sorun için macro çözümleri de geliştirilmiş ancak çok ilgimi çekmedi. Araçla ilgili detaylar aşağıdaki adreste bulunmaktadır;</p>
<p><a href="http://visualstudiogallery.msdn.microsoft.com/872d27ee-38c7-4a97-98dc-0d8a431cc2ed" target="_blank">http://visualstudiogallery.msdn.microsoft.com/872d27ee-38c7-4a97-98dc-0d8a431cc2ed</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.ahmetkaymaz.com/2010/06/12/vs-jscript-editor-extensions/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>SQL Server&#8217;da Satırın Fiziksel Konumu (%%physloc%%)</title>
		<link>http://www.ahmetkaymaz.com/2010/06/10/sql-serverda-satirin-fiziksel-konumu-physloc/</link>
		<comments>http://www.ahmetkaymaz.com/2010/06/10/sql-serverda-satirin-fiziksel-konumu-physloc/#comments</comments>
		<pubDate>Thu, 10 Jun 2010 09:23:49 +0000</pubDate>
		<dc:creator>Ahmet Kaymaz</dc:creator>
				<category><![CDATA[SQL Server, Oracle]]></category>

		<guid isPermaLink="false">http://www.ahmetkaymaz.com/?p=365</guid>
		<description><![CDATA[Oracle&#8217;da satırların disk üzerindeki fiziksel konumunu döndüren ROWID komutu bulunmaktadır. Bu tür komutlar değerleri veritabanında tutulmadığı o anda hesaplandığı için sahte komut(pseudo-column) olarak tanımlanır. Birçok veritabanı yönetim sisteminde her satır için arka tarafta bir ID bilgisi tutulmaktadır. Fakat bu değerleri geliştirilerin okuması zor olabiliyor. SQL Server 2005&#8242;te aynı amaç için %%lockres%% komutu eklendi. Bu komutun [...]]]></description>
			<content:encoded><![CDATA[<div class="google_plus_one"><g:plusone size="standard" count="true" url="http://www.ahmetkaymaz.com/2010/06/10/sql-serverda-satirin-fiziksel-konumu-physloc/"></g:plusone></div><p>Oracle&#8217;da satırların disk üzerindeki fiziksel konumunu döndüren <b>ROWID</b> komutu bulunmaktadır. Bu tür komutlar değerleri veritabanında tutulmadığı o anda hesaplandığı için sahte komut(pseudo-column) olarak tanımlanır. Birçok veritabanı yönetim sisteminde her satır için arka tarafta bir ID bilgisi tutulmaktadır. Fakat bu değerleri geliştirilerin okuması zor olabiliyor. SQL Server 2005&#8242;te aynı amaç için <b>%%lockres%%</b> komutu eklendi. Bu komutun SQL Server 2008&#8242;deki karşılığı <b>%%physloc%%</b> komutudur. <span id="more-365"></span>SQL Server 2005 tarafında aşağıdaki gibi kullanıyoruz.</p>
<pre name="code" class="sql">
SELECT *,%%lockres%% FROM OGRENCI
</pre>
<p><img src="http://www.ahmetkaymaz.com/wp-content/uploads/SQL_Server_Physical_Location_1.jpg"></p>
<p>Şekilde görüldüğü gibi SQL Server her satırı tekil bir RID değeriyle ayırmış durumda. Bu adres bilgisi verinin bulunduğu Data File:Page:Row Slot değerini içermektedir.</p>
<p>Kaynak kilitlemesi doğrudan fiziksel alan üzerinden olmaktadır. Bunu aşağıdaki gibi net bir şekilde görebiliriz. OGRENCI tablosu üzerinde 2 INSERT ve 1 UPDATE işlemi gerçekleştireceğiz. Transaction açıkken tablonun lock durumuna bakacağız. Aktif kilitlemeleri görmek için <b> sys.dm_tran_locks</b> isimli DMV kullanılabilir.</p>
<pre name="code" class="sql">
BEGIN TRAN

UPDATE OGRENCI SET AdSoyad='Serdar' WHERE AdSoyad='Ömer'
INSERT OGRENCI VALUES('Berk')
INSERT OGRENCI VALUES('Berk')

SELECT
    o.NAME obj_name, l.resource_description, l.request_mode, l.request_status, request_owner_type, request_session_id,
    ogr.*
FROM sys.dm_tran_locks l
    INNER JOIN sys.dm_exec_sessions s on l.request_session_id = s.session_id
    INNER JOIN sys.partitions p on l.resource_associated_entity_id = p.hobt_id
    INNER JOIN sys.objects o ON o.object_id = p.object_id
    CROSS APPLY (SELECT *
                         FROM OGRENCI (NOLOCK)
                         WHERE %%lockres%% = l.resource_description) ogr
ROLLBACK
</pre>
<p><img src="http://www.ahmetkaymaz.com/wp-content/uploads/SQL_Server_Physical_Location_2.jpg"></p>
<p>Şekilde de görüldüğü gibi SQL Server ilgili satırlar üzerinde exclusive lock (X) türünde bir kilit yerleştirmiş.</p>
<p>SQL Server 2008&#8242;de aynı komut çalışmakla birlikte <b>%%physloc%%</b> isminde yeni komut eklendi.</p>
<pre name="code" class="sql">
SELECT *,%%physloc%% FROM OGRENCI
</pre>
<p><img src="http://www.ahmetkaymaz.com/wp-content/uploads/SQL_Server_Physical_Location_3.jpg"></p>
<p>SQL Server 2008&#8242;deki bu komut hexadecimal türünde değer döndürmektedir. Bu değerin kolayca okunabilmesi için <b>sys.fn_PhysLocFormatter</b> fonksiyonu kullanılır.</p>
<pre name="code" class="sql">
SELECT %%physloc%% AdresHex,
sys.fn_PhysLocFormatter(%%physloc%%) Adres,
* FROM OGRENCI
</pre>
<p><img src="http://www.ahmetkaymaz.com/wp-content/uploads/SQL_Server_Physical_Location_4.jpg"></p>
<p>&#8220;Zeynep&#8221; kaydı 1 nolu data file içerisindeki 79 nolu data page içerisindeki 2 nolu slotta bulunmaktadır.</p>
<p>Daha önceki makalelerimde anlattığım gibi bir data page yapısını görmek için <b>DBCC PAGE</b> komutu kullanılabilir. Bu komut aşağıdaki parametreleri alır.</p>
<ul>
<li>Database ID veya Database Adı</li>
<li>Data File Numarası</li>
<li>Data Page Numarası</li>
<li>Sayfa içeriğinin detay seviyesi (ne kadar detay yazdırılacak)</li>
<ul>
<li>0 = Başlık</li>
<li>1 = Başlık ve Satırlar için hex açıklama</li>
<li>2 = Başlık ve Page seviyesinde detay</li>
<li>3 = Başlık ve Satırların detaylı içeriği</li>
</ul>
</ul>
<p><code>DBCC PAGE ({dbid|dbname}, pagenum [,print option] [,cache] [,logical])</code></p>
<pre name="code" class="sql">
DBCC TRACEON(3604)
DBCC PAGE (Deneme, 1, 79, 3)
DBCC TRACEOFF(3604)
</pre>
<p><code>DBCC execution completed. If DBCC printed error messages, contact your system administrator.</p>
<p>PAGE: (1:79)</p>
<p>BUFFER:</p>
<p>BUF @0x00000007A5FD1140</p>
<p>bpage = 0x00000007A582E000           bhash = 0x0000000000000000           bpageno = (1:79)<br />
bdbid = 8                            breferences = 0                      bcputicks = 0<br />
bsampleCount = 0                     bUse1 = 22529                        bstat = 0xc0010b<br />
blog = 0xca2159bb                    bnext = 0x0000000000000000           </p>
<p>PAGE HEADER:</p>
<p>Page @0x00000007A582E000</p>
<p>m_pageId = (1:79)                    m_headerVersion = 1                  m_type = 1<br />
m_typeFlagBits = 0x4                 m_level = 0                          m_flagBits = 0x8000<br />
m_objId (AllocUnitId.idObj) = 65     m_indexId (AllocUnitId.idInd) = 256<br />
Metadata: AllocUnitId = 72057594042187776<br />
Metadata: PartitionId = 72057594041204736                                 Metadata: IndexId = 0<br />
Metadata: ObjectId = 165575628       m_prevPage = (0:0)                   m_nextPage = (0:0)<br />
pminlen = 4                          m_slotCnt = 5                        m_freeCnt = 8005<br />
m_freeData = 177                     m_reservedCnt = 0                    m_lsn = (288:608:2)<br />
m_xactReserved = 0                   m_xdesId = (0:0)                     m_ghostRecCnt = 0<br />
m_tornBits = 0                       </p>
<p>Allocation Status</p>
<p>GAM (1:2) = ALLOCATED                SGAM (1:3) = ALLOCATED<br />
PFS (1:1) = 0x61 MIXED_EXT ALLOCATED  50_PCT_FULL                         DIFF (1:6) = CHANGED<br />
ML (1:7) = NOT MIN_LOGGED            </p>
<p>Slot 0 Offset 0x60 Length 16</p>
<p>Record Type = PRIMARY_RECORD         Record Attributes =  NULL_BITMAP VARIABLE_COLUMNS<br />
Record Size = 16<br />
Memory Dump @0x000000004804A060</p>
<p>0000000000000000:   30000400 01000001 00100041 686d6574 †0..........Ahmet </p>
<p>Slot 0 Column 1 Offset 0xb Length 5 Length (physical) 5</p>
<p>AdSoyad = Ahmet                      </p>
<p>Slot 1 Offset 0x70 Length 16</p>
<p>Record Type = PRIMARY_RECORD         Record Attributes =  NULL_BITMAP VARIABLE_COLUMNS<br />
Record Size = 16<br />
Memory Dump @0x000000004804A070</p>
<p>0000000000000000:   30000400 01000001 00100041 686d6574 †0..........Ahmet </p>
<p>Slot 1 Column 1 Offset 0xb Length 5 Length (physical) 5</p>
<p>AdSoyad = Ahmet                      </p>
<p>Slot 2 Offset 0x80 Length 17</p>
<p>Record Type = PRIMARY_RECORD         Record Attributes =  NULL_BITMAP VARIABLE_COLUMNS<br />
Record Size = 17<br />
Memory Dump @0x000000004804A080</p>
<p>0000000000000000:   30000400 01000001 0011005a 65796e65 †0..........Zeyne<br />
0000000000000010:   70†††††††††††††††††††††††††††††††††††p                </p>
<p>Slot 2 Column 1 Offset 0xb Length 6 Length (physical) 6</p>
<p>AdSoyad = Zeynep                     </p>
<p>Slot 3 Offset 0x91 Length 15</p>
<p>Record Type = PRIMARY_RECORD         Record Attributes =  NULL_BITMAP VARIABLE_COLUMNS<br />
Record Size = 15<br />
Memory Dump @0x000000004804A091</p>
<p>0000000000000000:   30000400 01000001 000f00d6 6d6572††††0..........Ömer  </p>
<p>Slot 3 Column 1 Offset 0xb Length 4 Length (physical) 4</p>
<p>AdSoyad = Ömer                       </p>
<p>Slot 4 Offset 0xa0 Length 17</p>
<p>Record Type = PRIMARY_RECORD         Record Attributes =  NULL_BITMAP VARIABLE_COLUMNS<br />
Record Size = 17<br />
Memory Dump @0x000000004804A0A0</p>
<p>0000000000000000:   30000400 01000001 0011004d 65686d65 †0..........Mehme<br />
0000000000000010:   74†††††††††††††††††††††††††††††††††††t                </p>
<p>Slot 4 Column 1 Offset 0xb Length 6 Length (physical) 6</p>
<p>AdSoyad = Mehmet                     </p>
<p>DBCC execution completed. If DBCC printed error messages, contact your system administrator.<br />
DBCC execution completed. If DBCC printed error messages, contact your system administrator.</code></p>
<p>Bu komutun gerçek hayatta kullanıldığı alanlardan biri üzerinde herhangi bir unique key olmayan tablolardaki çift kayıtların silinmesidir. Bu kayıtları silmek için kayıt değerlerin göre gruplama yapıp en düşük veya en yüksek fiziksel konuma sahip olanlar hariç diğerleri silinir. OGRENCI tablosunda 2 tane &#8220;Ahmet&#8221; değeri vardı bunları tek düşürmek için aşağıdaki kod yeterli olacaktır.</p>
<pre name="code" class="sql">
DELETE OGRENCI
WHERE OGRENCI.%%physloc%%
NOT IN (SELECT MIN(%%physloc%%)
        FROM OGRENCI
        GROUP BY AdSoyad);
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.ahmetkaymaz.com/2010/06/10/sql-serverda-satirin-fiziksel-konumu-physloc/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Local System, Local Service, Network Service Hesapları</title>
		<link>http://www.ahmetkaymaz.com/2010/04/25/local-system-local-service-network-service-hesaplari/</link>
		<comments>http://www.ahmetkaymaz.com/2010/04/25/local-system-local-service-network-service-hesaplari/#comments</comments>
		<pubDate>Sun, 25 Apr 2010 15:03:20 +0000</pubDate>
		<dc:creator>Ahmet Kaymaz</dc:creator>
				<category><![CDATA[SQL Server, Oracle]]></category>

		<guid isPermaLink="false">http://www.ahmetkaymaz.com/?p=362</guid>
		<description><![CDATA[Kendimiz bir servis yazdığında veya SQL Server kurulumunda en çok karşımızı çıkan konusu servisi hangi kullanıcı çalıştıracak. Bu iş genel olarak Local System, Local Service, Network Service kullanıcı hesapları tercih edilir. Bu küçük yazıda bu kullanıcıların farkını belirtip SQL Server cephesinde nasıl bir tercih yapmamız gerektiğini not alacağız.
Local System : Makine üzerindeki en yetkili hesaptır. [...]]]></description>
			<content:encoded><![CDATA[<div class="google_plus_one"><g:plusone size="standard" count="true" url="http://www.ahmetkaymaz.com/2010/04/25/local-system-local-service-network-service-hesaplari/"></g:plusone></div><p>Kendimiz bir servis yazdığında veya SQL Server kurulumunda en çok karşımızı çıkan konusu servisi hangi kullanıcı çalıştıracak. Bu iş genel olarak Local System, Local Service, Network Service kullanıcı hesapları tercih edilir. Bu küçük yazıda bu kullanıcıların farkını belirtip SQL Server cephesinde nasıl bir tercih yapmamız gerektiğini not alacağız.</p>
<p><b>Local System :</b> Makine üzerindeki en yetkili hesaptır. Hatta Administrator hesabından daha yetkilidir diyebiliriz. Hem yerel hem de network kaynaklarına erişebilir. Bu hesabın adı gerçekte &#8220;NT AUTHORITY\SYSTEM&#8221; olarak geçmektedir. Temelde NT AUTHORITY\SYSTEM ve Builtin\Administrators yetkilerini içerir. Bu yüzden SQL Server tarafından default olarak sysadmin rolünü alır.</p>
<p><b>Network Service :</b> Local System / Administrator kullanıcısına göre daha az yetkili olup network kaynaklarına erişecek servis kullanıcısıdır. Bu hesabın kullanıcı adı &#8220;NT AUTHORITY\NETWORK SERVICE&#8221; olarak geçmektedir.</p>
<p><b>Local Service :</b> Network Service kullanıcısıyla aynı sınırlı yetkilere sahip olup tek farkı network kaynaklarına erişemez. Bu hesabın kullanıcısı &#8220;NT AUTHORITY\LOCAL SERVICE&#8221; olarak geçmektedir. Bu account  SQL Server veya SQL Server Agent servisleri tarafından desteklenmemektedir. Bu kullanıcı genellikle makinenin dışındaki kaynaklara erişmeyecek servisler tarafında tercih edilir.</p>
<p>SQL Server servisi için mümkün olduğunca Local non-system veya Service kullanıcısını kullanmak yerine bu iş oluşturulmuş bir Domain hesabının kullanılması tavsiye edilir. Ve bu domain hesabının da olabildiğince minimum yetkilere sahip olması gerekmektedir. Eğer SQL Server üzerinden dosya paylaşımı, linked server gibi network kaynak erişimi olacaksa doğru yetkilendirilmiş AD kullanıcısı tercih edilmesi daha doğru olacaktır. Ayrıca birden fazla SQL Server sunucusu varsa bunların tek bir domain kullanıcısı tarafından başlatılması yönetim kolaylığı sağlayacaktır. Eğer SQL Server&#8217;in bulunduğu makine Domain&#8217;de bulunmuyorsa yerel kullanıcı servisi kullanıcısı olarak tercih edilebilir. Tabi bu kullanıcının Administrator yetkilerine sahip olmamasına dikkat edilmelidir.</p>
<p>Özetle SQL Server ve alt birimlerini için mümkün olduğunca az yetkili bir kullanıcıyla çalıştırmak ve SQL Server ve Agent için ayrı kullanıcıları tercih etmek tavsiye edilir.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ahmetkaymaz.com/2010/04/25/local-system-local-service-network-service-hesaplari/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Index&#8217;lerin Aktif/Pasif (Enabled/Disable) Yapılması</title>
		<link>http://www.ahmetkaymaz.com/2010/04/21/indexlerin-aktifpasif-enableddisable-yapilmasi/</link>
		<comments>http://www.ahmetkaymaz.com/2010/04/21/indexlerin-aktifpasif-enableddisable-yapilmasi/#comments</comments>
		<pubDate>Wed, 21 Apr 2010 13:36:04 +0000</pubDate>
		<dc:creator>Ahmet Kaymaz</dc:creator>
				<category><![CDATA[SQL Server, Oracle]]></category>

		<guid isPermaLink="false">http://www.ahmetkaymaz.com/?p=358</guid>
		<description><![CDATA[SQL Server 2000&#8242;de mevcut bir indexi aktif veya pasif yapamıyoruz. Sadece drop edebiliriz. Oysa bazı durumlarda örneğin optimizasyon işlemlerinde veya büyük aktarımlar için (DTS, BCP, BULK INSERT ) kısıtlı zamanlarda geçici olarak bazı indexleri pasif yapma ihtiyacı doğabiliyor. SQL Server 2005 ve sonrasında gelen ALTER INDEX komutu sayesinde bu işlem yapılabilmektedir.
Aşağıdaki komutları kullanarak örnek MUSTERI [...]]]></description>
			<content:encoded><![CDATA[<div class="google_plus_one"><g:plusone size="standard" count="true" url="http://www.ahmetkaymaz.com/2010/04/21/indexlerin-aktifpasif-enableddisable-yapilmasi/"></g:plusone></div><p>SQL Server 2000&#8242;de mevcut bir indexi aktif veya pasif yapamıyoruz. Sadece drop edebiliriz. Oysa bazı durumlarda örneğin optimizasyon işlemlerinde veya büyük aktarımlar için (DTS, BCP, BULK INSERT ) kısıtlı zamanlarda geçici olarak bazı indexleri pasif yapma ihtiyacı doğabiliyor. SQL Server 2005 ve sonrasında gelen <b>ALTER INDEX</b> komutu sayesinde bu işlem yapılabilmektedir.<span id="more-358"></span></p>
<p>Aşağıdaki komutları kullanarak örnek MUSTERI tablosunu oluşturalım.</p>
<pre name="code" class="sql">
--Tabloyu oluşturalım
CREATE TABLE MUSTERI(MusteriId int,AdSoyad varchar(50),KayitTarih smalldatetime)
GO
--Tablo üzerinde index oluşturalım
CREATE UNIQUE CLUSTERED INDEX IX_MusteriId ON MUSTERI(MusteriId)
GO
CREATE INDEX IX_AdSoyad ON MUSTERI(AdSoyad)
GO
CREATE INDEX IX_KayitTarih ON MUSTERI(KayitTarih)
GO
--Tabloya örnek kayıt girelim
INSERT INTO MUSTERI VALUES(1,'Ahmet Kaymaz',GETDATE())
INSERT INTO MUSTERI VALUES(2,'Ömer Kaymaz',GETDATE())
INSERT INTO MUSTERI VALUES(3,'Zeynep Kaymaz',GETDATE())
</pre>
<p>Bir non-clustered index&#8217;i disable ettiğimiz zaman sorguları en az maliyetle çalışmasından görevli SQL Server Optimizer aracı bu index&#8217;leri yoksayar. Ayrıca index datası fiziksel olarak silinir. Aşağıdaki sorguyu çalıştırıp Execution Plan&#8217;ına bakalım.</p>
<pre name="code" class="sql">
SET SHOWPLAN_TEXT ON
SELECT MusteriId,AdSoyad FROM MUSTERI WHERE AdSoyad ='Ahmet Kaymaz'
</pre>
<p><i>  |&#8211;Index Seek(OBJECT:([Deneme].[dbo].[MUSTERI].[IX_AdSoyad]), SEEK:([Deneme].[dbo].[MUSTERI].[AdSoyad]=[@1]) ORDERED FORWARD)</i></p>
<p>&#8220;SET SHOWPLAN_TEXT ON&#8221; komutu yürütme planını metinsel olarak görmemizi sağlar. Grafiksel olarak bu planı görmek için &#8220;Include Actual Execution Plan&#8221; düğmesini tıklamamıza yeterli olacaktır.</p>
<p><img src="http://www.ahmetkaymaz.com/wp-content/uploads/Enabling_Disabling_Index_1.jpg"></p>
<p>Yürütme planı bu sorgu için MUSTERI tablosu üzerinde IX_AdSoyad indeksinin kullanılarak index seek operasyonun yapıldığını anlatmaktadır. Şimdi bu indexi DISABLE edelim. </p>
<pre name="code" class="sql">
ALTER INDEX IX_AdSoyad ON MUSTERI DISABLE
</pre>
<p>Disable işlemi ALTER INDEX komutuyla yapılabildiği gibi aşağıdaki gibi Management Studio üzerinden de yapılabilir.</p>
<p><img src="http://www.ahmetkaymaz.com/wp-content/uploads/Enabling_Disabling_Index_2.jpg"></p>
<p>Bu işlemden sonra aynı sorguyu çalıştırdığımızda bu sefer Execution Plan olarak aşağıdaki gibi bir sonuç dönecektir.</p>
<p><i>  |&#8211;Clustered Index Scan(OBJECT:([Deneme].[dbo].[MUSTERI].[IX_MusteriId]), WHERE:([Deneme].[dbo].[MUSTERI].[AdSoyad]=[@1]))</i></p>
<p>Görüldüğü gibi Optimize IX_AdSoyad indexini görmezden gelip doğrudan clustered index scan operasyonunu uyguladı. </p>
<p>Non-clustered index&#8217;in disable edilmesinden sonra bu index için oluşturulmuş olan index datalarının silindiğini yazmıştık. Bunu doğrulamak için sys.sysindexes view&#8217;i çalıştırılabilir. Index&#8217;i disable yapmadan önce aşağıdaki sorguyu çalıştıracak olursak sonuç olarak &#8220;3&#8243; değeri dönecektir.</p>
<pre name="code" class="sql">
SELECT rowcnt FROM sys.sysindexes WHERE name = 'IX_AdSoyad'
</pre>
<p>Disable işleminden sonra rowcnt değeri &#8220;0&#8243; olarak dönecektir. Çünkü index page&#8217;ler silinmiş oldu. Ayrıca indexin aktif/pasif bilgisi de aynı view&#8217;deki <b>is_disabled</b> kolonunda belirtilmektedir.</p>
<p>Clustered Index&#8217;e gelince durum biraz daha farklılık arzetmektedir. SQL Server sisteminde non-clustered indexler varsa clustered index üzerine kurulduğu için clustered index tarafındaki düzenleme non-clustered indexleri etkilemektedir. Dolayısıyla clustered index&#8217;in disable edilmesi tüm non-clustered indexlerin disable olmasına neden olur. Ve daha öncemli clustered index tablonun kendisini ifade ettiği için bu disable işleminden sonra sistem kataloğunda indexle ilgili bilgi tutulsa da kullanıcı ilgili tabloya erişemez.</p>
<pre name="code" class="sql">
ALTER INDEX IX_MusteriId ON MUSTERI DISABLE
</pre>
<p>Bu işlem sonrasında SQL Server aşağıdaki gibi uyarıyı verecektir.</p>
<p><i><br />
Warning: Index &#8216;IX_AdSoyad&#8217; on table &#8216;MUSTERI&#8217; was disabled as a result of disabling the clustered index on the table.<br />
Warning: Index &#8216;IX_KayitTarih&#8217; on table &#8216;MUSTERI&#8217; was disabled as a result of disabling the clustered index on the table.<br />
</i></p>
<p>Şimdi örnek sorgumuzu çalıştıracak olursak aşağıdaki hatayla karşılaşırız.<br />
<font color=red>The query processor is unable to produce a plan because the index &#8216;IX_MusteriId&#8217; on table or view &#8216;MUSTERI&#8217; is disabled.</font></p>
<p>Herhangi bir indexi yeniden aktifleştirmek için <b>ALTER INDEX REBUILD</b> veya <b>CREATE INDEX WITH DROP_EXISTING</b> komutları kullanılır. Yani indexler yeniden oluşturulur. Tüm indexleri rebuild etmek için <b>ALTER INDEX ALL</b> komutu kullanılır. Ayrıca clustered index&#8217;in aktifleştirilmesi tablo üzerindeki non-clustered indexlerin de aktifleştirileceği anlamına gelmez. Bu yüzden hepsinin bağımsız olarak rebuild edilmesi gerekmektedir. Tüm indexleri yeniden aktifleştirelim.</p>
<pre name="code" class="sql">
ALTER INDEX ALL ON MUSTERI REBUILD
</pre>
<p>Index&#8217;lerin drop edilmeden doğrudan pasif yapılması bulk import/update işlemleri için kolaylık sağlamaktadır.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ahmetkaymaz.com/2010/04/21/indexlerin-aktifpasif-enableddisable-yapilmasi/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The SSIS subsystem failed to load</title>
		<link>http://www.ahmetkaymaz.com/2010/04/12/the-ssis-subsystem-failed-to-load/</link>
		<comments>http://www.ahmetkaymaz.com/2010/04/12/the-ssis-subsystem-failed-to-load/#comments</comments>
		<pubDate>Mon, 12 Apr 2010 09:17:41 +0000</pubDate>
		<dc:creator>Ahmet Kaymaz</dc:creator>
				<category><![CDATA[SQL Server, Oracle]]></category>

		<guid isPermaLink="false">http://www.ahmetkaymaz.com/?p=355</guid>
		<description><![CDATA[SQL Server&#8217;in bulunduğu makineyi değiştirdikten sonra mevcut sistemde tanımlı Job&#8217;ları da yeni sunucuya aktardık. Yöntem olarak msdb veritabanını attach ettik. Bu Job&#8217;lar SSIS paketlerini çalıştırıyor. Job&#8217;ları çalıştırdığımızda aşağıdaki hatayı aldım.
Unable to start execution of step 1 (reason: The SSIS subsystem failed to load [see the SQLAGENT.OUT file for details]; The job has been suspended).  [...]]]></description>
			<content:encoded><![CDATA[<div class="google_plus_one"><g:plusone size="standard" count="true" url="http://www.ahmetkaymaz.com/2010/04/12/the-ssis-subsystem-failed-to-load/"></g:plusone></div><p>SQL Server&#8217;in bulunduğu makineyi değiştirdikten sonra mevcut sistemde tanımlı Job&#8217;ları da yeni sunucuya aktardık. Yöntem olarak msdb veritabanını attach ettik. Bu Job&#8217;lar SSIS paketlerini çalıştırıyor. Job&#8217;ları çalıştırdığımızda aşağıdaki hatayı aldım.</p>
<p><font color=red>Unable to start execution of step 1 (reason: The SSIS subsystem failed to load [see the SQLAGENT.OUT file for details]; The job has been suspended).  The step failed.</font></p>
<p>Bu sorunun nedeni eski ile yeni sunucunun SQL Server kurulum klasörlerinin farklı oluşuymuş. Çünkü SQL Server <i>TSQL, CmdExec, SSIS, PowerShell, Snapshot, LogReader, Distribution &#8230;</i> gibi SQL Server Agent üzerindeki alt sistemlere ait DLL bilgilerini <b>msdb.dbo.syssubsystems</b> tablosunda tutuyor. Bu tablodaki kütüphane adresleri eski sunucuda farklı olduğu için sistem SSIS paketlerini hangi motorla çalıştıracağını bilemiyor. </p>
<p>Bu sorunun kolay bir çözüm var. <b>sp_verify_subsystems</b> prosedürü ilgili alt sistemler için doğru DLL adreslerini yeniden oluşturuyor. Aşağıdaki gibi tablodaki mevcut kayıtları silip ilgili prosedürü çalıştırmamız yeterli olacaktır.</p>
<pre name="code" class="sql">--Mevcut kayıtları sil
DELETE FROM msdb.dbo.syssubsystems

--Tabloyu yeni DLL adresleriyle yeniden doldur
EXEC msdb.dbo.sp_verify_subsystems 1</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.ahmetkaymaz.com/2010/04/12/the-ssis-subsystem-failed-to-load/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Database cannot be upgraded because it is read-only or has read-only files</title>
		<link>http://www.ahmetkaymaz.com/2010/04/05/database-cannot-be-upgraded-because-it-is-read-only-or-has-read-only-files/</link>
		<comments>http://www.ahmetkaymaz.com/2010/04/05/database-cannot-be-upgraded-because-it-is-read-only-or-has-read-only-files/#comments</comments>
		<pubDate>Mon, 05 Apr 2010 09:01:30 +0000</pubDate>
		<dc:creator>Ahmet Kaymaz</dc:creator>
				<category><![CDATA[SQL Server, Oracle]]></category>

		<guid isPermaLink="false">http://www.ahmetkaymaz.com/?p=352</guid>
		<description><![CDATA[Birkaç gün önce sunucu iyileştirme kapsamında SQL Server 2008 instance üzerinde bulunan bir veritabanını detach edip network üzerinden ikinci sunucuya kopyalayıp aynı şekilde SQL Server 2008 R2 üzerine attach etmeye çalışırken aşağıdaki hatayla karşılaştım.
Msg 3415, Level 16, State 3, Line 1
Database [database_name] cannot be upgraded because it is read-only or has read-only files. Make the [...]]]></description>
			<content:encoded><![CDATA[<div class="google_plus_one"><g:plusone size="standard" count="true" url="http://www.ahmetkaymaz.com/2010/04/05/database-cannot-be-upgraded-because-it-is-read-only-or-has-read-only-files/"></g:plusone></div><p>Birkaç gün önce sunucu iyileştirme kapsamında SQL Server 2008 instance üzerinde bulunan bir veritabanını detach edip network üzerinden ikinci sunucuya kopyalayıp aynı şekilde SQL Server 2008 R2 üzerine attach etmeye çalışırken aşağıdaki hatayla karşılaştım.<br/></p>
<p><font color=red>Msg 3415, Level 16, State 3, Line 1<br />
Database [database_name] cannot be upgraded because it is read-only or has read-only files. Make the database or files writeable, and rerun recovery.<br />
Msg 1813, Level 16, State 2, Line 1<br />
Could not open new database [database_name]. CREATE DATABASE is aborted.<br />
</font></p>
<p>Mesajın içeriğine bakınca database dosyalarının işletim sistemi üzerinde salt-okunur olduğunu düşündüm. Oysa dosyaları read-only durumda değildi. SQL Server&#8217;i çalıştıran kullanıcının permission ayarlarına baktım onlar da full görünüyordu. Yaptığım araştırmalarda bu işin nedenlerinin farklı olabileceği ve farklı şekillerde çözülebileceği söyleniyor. Muhtemel neden ve çözümleri aşağıda bulabilirsiniz;</p>
<p>Öncelikle bu dosyaların attach edilmesi esnasında başka bir instance tarafından kullanılmadığında ve dosya özelliklerinden ve ya kullanıcı yetkilerinden salt-okunur olmadıklarından emin olmamız gerekiyor.</p>
<p>Birinci çözüm olarak &#8220;<b>Everyone</b>&#8221; kullanıcısına full access yetkisi verilir. Dosyalar attach edildikten sonra işlem başarılı olduktan sonra Everyone yetkisi geri alınır.</p>
<p>İkinci çözüm veya sorunun nedeni olarak SQL Server kullanıcısına bakılabilir. Benim sorunum buydu. SQL Server servisi AUTHORITY\NETWORKSERVICE kullanıcısıyla başlatılmıştı. Bu kullanıcının attach etmek hakkı olmadığı için servis kullanıcısını LOCAL ACCOUNT olarak değiştirince sorun çözüldü.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ahmetkaymaz.com/2010/04/05/database-cannot-be-upgraded-because-it-is-read-only-or-has-read-only-files/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>JQUERY &#8211; ASP.NET POST işleminde Türkçe Karakter Sorunu</title>
		<link>http://www.ahmetkaymaz.com/2010/02/25/jquery-asp-net-post-isleminde-turkce-karakter-sorunu/</link>
		<comments>http://www.ahmetkaymaz.com/2010/02/25/jquery-asp-net-post-isleminde-turkce-karakter-sorunu/#comments</comments>
		<pubDate>Thu, 25 Feb 2010 14:33:22 +0000</pubDate>
		<dc:creator>Ahmet Kaymaz</dc:creator>
				<category><![CDATA[C#, VB.NET, ASP.NET]]></category>

		<guid isPermaLink="false">http://www.ahmetkaymaz.com/?p=349</guid>
		<description><![CDATA[JQuery aracılığıyla bir formu ASP.NET sayfasına doğrudan POST veya GET ile gönderebilmek için Form Serialize işlemi gerçekleştirilir. Bu amaçla .serialize() veya .serializeArray() yordamları kullanılır. 
Özellikle Internet Explorer ortamında bir formu serialize edip ASP.NET sayfasında okumaya çalıştığımızda Türkçe Karakter sorunu yaşanmaktadır. Örneğin &#8220;öçşğüİ&#8221; değeri Ã¶Ã§ÅÄÃ¼Ä şeklinde görünmektedir. Bu karakterlerin UTF-8 olarak gönderilmesi için aşağıdaki örnekte gösterildiği [...]]]></description>
			<content:encoded><![CDATA[<div class="google_plus_one"><g:plusone size="standard" count="true" url="http://www.ahmetkaymaz.com/2010/02/25/jquery-asp-net-post-isleminde-turkce-karakter-sorunu/"></g:plusone></div><p>JQuery aracılığıyla bir formu ASP.NET sayfasına doğrudan POST veya GET ile gönderebilmek için Form Serialize işlemi gerçekleştirilir. Bu amaçla <b>.serialize()</b> veya <b>.serializeArray()</b> yordamları kullanılır. </p>
<p>Özellikle Internet Explorer ortamında bir formu serialize edip ASP.NET sayfasında okumaya çalıştığımızda Türkçe Karakter sorunu yaşanmaktadır. Örneğin &#8220;öçşğüİ&#8221; değeri Ã¶Ã§ÅÄÃ¼Ä şeklinde görünmektedir. Bu karakterlerin UTF-8 olarak gönderilmesi için aşağıdaki örnekte gösterildiği gibi &#8220;application/x-www-form-urlencoded; charset=utf-8&#8243; şeklinde content teype belirmek gerekiyor.</p>
<pre name="code" class="javascript">
var formValue=$("#aspnetForm").serializeNoViewState();

$.ajax({
	type: "POST",
	url: "OrnekSayfa.aspx?Prm=1",
	data: formValue,

	beforeSend: function (xhr) {
	    xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded; charset=utf-8");
	},

	contentType: "application/x-www-form-urlencoded; charset=utf-8",
	dataType: "json", 

	success: function (msg, status) {
		alert(msg);
	},
	error: function (xhr, msg, e) {
	    alert("Hata Oluştu!\n" + xhr.responseText +"\n"+msg );
	},

	complete: function() {
		alert('İstek başarıyla gönderildi.');
	}
});
</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.ahmetkaymaz.com/2010/02/25/jquery-asp-net-post-isleminde-turkce-karakter-sorunu/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>ASP.NET requestValidationMode ayarı</title>
		<link>http://www.ahmetkaymaz.com/2010/02/24/asp-net-requestvalidationmode-ayari/</link>
		<comments>http://www.ahmetkaymaz.com/2010/02/24/asp-net-requestvalidationmode-ayari/#comments</comments>
		<pubDate>Wed, 24 Feb 2010 13:41:01 +0000</pubDate>
		<dc:creator>Ahmet Kaymaz</dc:creator>
				<category><![CDATA[C#, VB.NET, ASP.NET]]></category>

		<guid isPermaLink="false">http://www.ahmetkaymaz.com/?p=345</guid>
		<description><![CDATA[ASP.NET sayfasına POST işlemi yaptığımızda post edilen metin içerisinde &#8220;&#8221; gibi web safyaları için tehlike oluşturabilecek değerler gönderildiği zaman ASP.NET WP, &#8220;A potentially dangerous Request.Form value was detected from the client&#8221; hatasını fırlatır. Bu hatayı engellemek yani kullanıcının bu tür değerleri girmesine izin vermek için ASP.NET sayfasının tanımlama satırına validateRequest=&#8221;false&#8221; ibaresi yazılır. Aynı şekilde uygulamadaki [...]]]></description>
			<content:encoded><![CDATA[<div class="google_plus_one"><g:plusone size="standard" count="true" url="http://www.ahmetkaymaz.com/2010/02/24/asp-net-requestvalidationmode-ayari/"></g:plusone></div><p>ASP.NET sayfasına POST işlemi yaptığımızda post edilen metin içerisinde &#8220;<>&#8221; gibi web safyaları için tehlike oluşturabilecek değerler gönderildiği zaman ASP.NET WP, &#8220;<font color=red>A potentially dangerous Request.Form value was detected from the client</font>&#8221; hatasını fırlatır. Bu hatayı engellemek yani kullanıcının bu tür değerleri girmesine izin vermek için ASP.NET sayfasının tanımlama satırına <b>validateRequest=&#8221;false&#8221;</b> ibaresi yazılır. Aynı şekilde uygulamadaki tüm sayfalar için bu ayarın geçerli olması için Web.Config dosyasına aşağıdaki gibi ekleme yapılabilir.</p>
<p>&lt;pages validateRequest=&quot;false&quot; /&gt; </p>
<p>Cross-site scripting (XSS) attack riskini engellemek için ASP.NET tüm sürümlerinde request validation özelliği varsayılan olarak aktifdir. ASP.NET&#8217;in önceki sürümlerinde bu doğrulama işlemi sadece ASPX sayfaları için yapılmaktaydı. 4.0 sürümüyle birlikte doğrulama işlemi doğrudan BeginRequest aşamasında devreye alınacak şekilde düzenlendi. Böylece uygulamaya gelen tüm istekler için yani sadece ASPX sayfaları değil, Web Servisi çağırma, HTTP handler çalıştırma gibi tüm ASP.NET kaynaklarına istek gönderildiği zaman doğrulama işlemi devreye alınmış oldu.</p>
<p>Bazı durumlarda .NET Framework 4.0 altında eski sürüm ugyulamalarını çalıştırma durumumuz olabilir. Bu durumda hangi sürüm algoritmasının kullanacağını belirtmek için <b>requestValidationMode</b> niteliği kullanılır.</p>
<p>&lt;system.web&gt;<br />
   &lt;httpRuntime requestValidationMode=&quot;2.0&quot; /&gt;<br />
&lt;/system.web&gt;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ahmetkaymaz.com/2010/02/24/asp-net-requestvalidationmode-ayari/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>SQL Server Replication &#8211; Şema Değişikliği</title>
		<link>http://www.ahmetkaymaz.com/2010/02/22/sql-server-replication-sema-degisikligi/</link>
		<comments>http://www.ahmetkaymaz.com/2010/02/22/sql-server-replication-sema-degisikligi/#comments</comments>
		<pubDate>Mon, 22 Feb 2010 09:09:00 +0000</pubDate>
		<dc:creator>Ahmet Kaymaz</dc:creator>
				<category><![CDATA[SQL Server, Oracle]]></category>

		<guid isPermaLink="false">http://www.ahmetkaymaz.com/?p=342</guid>
		<description><![CDATA[Kurulu olan bir replikasyona yeni nesne ekleme, mevcut nesne silme gibi işlemler bir gereksinim olduğu gibi bazı durumlarda tablodaki kolonların veri tipi değişimi, kolon adı değişimi gibi ihtiyaçlar da doğabiliyor. Daha önce yazdığımız SQL Server Replication – Yeni Tablo Ekleme makalesinde replikasyona yeni bir tablo nesnesinin nasıl ekleneceğini örneklendirmiştik. Bu yazıda da bir tablodaki kolonu [...]]]></description>
			<content:encoded><![CDATA[<div class="google_plus_one"><g:plusone size="standard" count="true" url="http://www.ahmetkaymaz.com/2010/02/22/sql-server-replication-sema-degisikligi/"></g:plusone></div><p>Kurulu olan bir replikasyona yeni nesne ekleme, mevcut nesne silme gibi işlemler bir gereksinim olduğu gibi bazı durumlarda tablodaki kolonların veri tipi değişimi, kolon adı değişimi gibi ihtiyaçlar da doğabiliyor. Daha önce yazdığımız <a href="http://www.ahmetkaymaz.com/2009/01/02/sql-server-replication-yeni-tablo-ekleme/">SQL Server Replication – Yeni Tablo Ekleme</a> makalesinde replikasyona yeni bir tablo nesnesinin nasıl ekleneceğini örneklendirmiştik. Bu yazıda da bir tablodaki kolonu replikasyona eklemek, replikasyonda çıkarmak ve şemasını değiştirdiğimizde replikasyonun nasıl etkileneceğini göreceğiz. <span id="more-342"></span></p>
<p>SQL Server üzerinde replike edilen bir tabloya yeni bir kolon eklediğimizde veya tablodan kaldırdığımızda (ALTER TABLE ADD / ALTER TABLE DROP) SQL Server 2000 bunu doğrudan replikasyona dahil etmez SQL Server 2005 ise bunu default olarak replikasyona dahil eder. SQL Server 2000&#8242;de yeni kolonu replikasyona dahil etmek için ya sözkonusu tablo yeniden replikasyona dahil edilir veya <b>sp_repladdcolumn</b> ve <b>sp_repldropcolumn</b> prosedürleri kullanılır. Eğer tablodaki kayıtlar az ise aşağıdaki gibi tabloyu mevcut replikasyondan çıkarıp yeniden dahil etmek daha kolay bir çözüm olarak tercih edilebilir.</p>
<pre name="code" class="sql">--W00 isimli abonenin Urun nesnesine olan aboneliğini kaldırıyoruz
exec sp_dropsubscription @publication = 'MerkezData'
, @article = 'Urun'
, @subscriber = 'W00'
, @destination_db = 'akaymaz' 

--Mevcut publication içerisinden Urun tablosunu çıkarıyoruz
exec sp_droparticle @publication = 'MerkezData'
, @article = 'Urun'

--Urun tablosuna Fiyat kolonu ekleyelim
ALTER TABLE Urun ADD Fiyat int null

--MerkezData isimli yayına Urun nesnesini ekliyoruz
exec sp_addarticle @publication = 'MerkezData'
, @article = 'Urun'
, @source_table = 'Urun'
, @ins_cmd = N'SQL', @del_cmd = N'SQL', @upd_cmd = N'SQL'

--W00 istemcisinin Urun nesnesine abone edelim
exec sp_addsubscription @publication = 'MerkezData'
, @article = 'Urun'
, @subscriber = 'W00'
, @destination_db = 'akaymaz'</pre>
<p>Bu kodları çalıştırdıktan sonra Urun tablosunun yeniden abonelere aktarmak için bu tablo için snapshot oluşturmak gerekir.</p>
<p><img src="http://www.ahmetkaymaz.com/wp-content/uploads/SQL_Replication_Change_Schema_1.jpg"></p>
<p>Bunu oluşturmak için &#8220;Snapshot Agent&#8221; servisini başlatmak yeterli olacaktır. Snapshot Agent, eklenen tablo için bir snapshot oluşturacaktır. Bu snapshot içerisinde tablodaki tüm kayıtlar olacağı için bu yöntem yükse satırlı tablolarda sorun teşkil edebilir. Büyük tablolar veya snapshot oluşturulmasını istemediğimiz durumlar için ikinci yöntem alternatif olarak kullanılabilir. Bu yöntem <b>sp_repladdcolumn</b> ve <b>sp_repldropcolumn</b> prosedürlerinin kullanılmasıdır. Bu prosedürler publish edilmiş tabloya yeni kolon ekler veya tablodaki kolonu çıkarır. Örneğin Urun tablosunda bulunan Fiyat kolonunu replikasyona dahil edelim. Fakat bu tabloda daha önce bulunan kayıtları da karşı tarafa aktarmamız gerekiyor. snapshot işlemi olmayacağı için ara bir kolon oluşturmamız gerekecektir. Aşağıdaki gibi tmpFiyat isimli bir alan oluşturacağız Fiyat alanındaki değerleri tmpFiyat alanına taşıyacağız. Fiyat alanını silip ardından replikasyonda dahil edilecek şekilde yeniden oluşturacak ve tmpFiyat alanındaki verileri Fiyat alanına taşıyacağız.</p>
<pre name="code" class="sql">exec sp_repladdcolumn @source_object = 'Urun'
, @column = 'tmpFiyat'
, @typetext = 'int NULL'
, @publication_to_add = 'MerkezData'

update Urun set tmpFiyat = Fiyat

exec sp_repldropcolumn @source_object = 'Urun'
, @column = 'Fiyat'

exec sp_repladdcolumn @source_object = 'Urun'
, @column = 'Fiyat'
, @typetext = 'int NULL'
, @publication_to_add = 'MerkezData' 

update Urun set Fiyat = tmpFiyat

exec sp_repldropcolumn @source_object = 'Urun'
, @column = 'tmpFiyat'</pre>
<p>Bu yöntemlerden farklı olarak şu da yapılabilir; replikasyonu kurarken kullandığımız <b>sp_articlecolumn</b> isimli prosedür aracılığıyla mevcut replikasyona tablodaki kolon eklenir. Böylece bundaki sonraki işlemlerde bu kolon da dahil edilmiş olur. O arada o kolondaki eski kayıtları linked server veya Import/Export ile aboneye taşıyıp şube ile merkez senkronize edilebilir.</p>
<pre name="code" class="sql">exec sp_articlecolumn @publication = N'MerkezData',
@article = N'Urun',
@column = N'Fiyat', @operation = N'add'

exec sp_articlecolumn @publication = N'MerkezData',
@article = N'Urun',
@column = N'Fiyat', @operation = N'drop'</pre>
<p>SQL Server 2005&#8242;te 2000&#8242;den farklı olarak replike edilen bir tabloya yeni kolon eklediğimizde bu kolon default olarak replikasyona dahil edilir. Aşağıdaki gibi Cinsiyet alanını eklediğimizde otomatik olarak abonedeki Musteri tablosuna da Cinsiyet alanı eklenecektir.<br />
<i>ALTER TABLE Musteri ADD Cinsiyet int</i><br />
Aynı şekilde alanı DROP ettiğimizde abonedeki Cinsiyet alanı da kaldırılmış olacaktır.<br />
<i>ALTER TABLE Musteri DROP COLUMN Cinsiyet</i></p>
<p>SQL Server 2005&#8242;te de mevcut bir kolonu replikasyona dahil etmek için <b>sp_articlecolumn</b> yordamı kullanılabilir.</p>
<p>Şimdi şema değişikliği konusuna değinelim. SQL Server 2000&#8242;de replikasyonda bulunan bir tablo üzerinde ortamında şema değişikliği yapmak istediğimizde aşağıdaki hata mesajıyla karşılaşırız.</p>
<p><i>ALTER TABLE Urun ALTER COLUMN Fiyat numeric(9,2)</i></p>
<p><i>&#8220;Cannot alter/drop the table &#8216;Urun&#8217; because it is being published for replication&#8221;.</i></p>
<p>SQL Server 2005&#8242;te tahmin edileceği gibi kolon ekleme, çıkarma gibi şema değişikliği de default olarak aboneye yansır. Bu özellik <i>sp_addpublication</i>  veya <i>sp_changepublication</i> yordamları için kullanılan <b>@replicate_ddl</b> parametresiyle belirlenmektedir.</p>
<pre name="code" class="sql">sp_changepublication @publication='MerkezData',
	@property = N'replicate_ddl', @value = 0</pre>
]]></content:encoded>
			<wfw:commentRss>http://www.ahmetkaymaz.com/2010/02/22/sql-server-replication-sema-degisikligi/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Replikasyonda MaxCmdsInTran Parametresi</title>
		<link>http://www.ahmetkaymaz.com/2010/02/12/replikasyonda-maxcmdsintran-parametresi/</link>
		<comments>http://www.ahmetkaymaz.com/2010/02/12/replikasyonda-maxcmdsintran-parametresi/#comments</comments>
		<pubDate>Fri, 12 Feb 2010 09:38:27 +0000</pubDate>
		<dc:creator>Ahmet Kaymaz</dc:creator>
				<category><![CDATA[SQL Server, Oracle]]></category>

		<guid isPermaLink="false">http://www.ahmetkaymaz.com/?p=340</guid>
		<description><![CDATA[SQL Server 2000 üzerinde kurduğumuz replikasyon aracılığıyla 50 tane şubeyi merkeze kolayca ve hızlıca taşıyabildik. Ancak SQL Server 2005 kullanan şubelerimiz nedenini henüz çözemediğim bir yavaşlıktan dolayı şube tarafında çok uzun sayıdaki transactionlar merkeze geç aktarılıyor. Farklı alternatifler denememe rağmen başarılı olamadık. Şube tarafındaki bulk işlemlerden dolayı bir transaction içerisinde çok sayıda command eklenmektedir. Buradaki [...]]]></description>
			<content:encoded><![CDATA[<div class="google_plus_one"><g:plusone size="standard" count="true" url="http://www.ahmetkaymaz.com/2010/02/12/replikasyonda-maxcmdsintran-parametresi/"></g:plusone></div><p>SQL Server 2000 üzerinde kurduğumuz replikasyon aracılığıyla 50 tane şubeyi merkeze kolayca ve hızlıca taşıyabildik. Ancak SQL Server 2005 kullanan şubelerimiz nedenini henüz çözemediğim bir yavaşlıktan dolayı şube tarafında çok uzun sayıdaki transactionlar merkeze geç aktarılıyor. Farklı alternatifler denememe rağmen başarılı olamadık. Şube tarafındaki bulk işlemlerden dolayı bir transaction içerisinde çok sayıda command eklenmektedir. Buradaki sıkıntı kuyrukta bekleyen çok sayıdan komut satırının herhangi bir bağlantı kesilmesinde rollback edilecek olması ve her defasında yeniden baştan itibaren aboneye gönderilmesidir. Örneğin bir transaction setinde 100bin komut olduğunu düşünelim. Bunları adım adım aboneye gönderirken 90bininci satırda herhangi bir bağlantı kesilmeside abone üzerinde tüm işlemler rollback edilecek ve bir sonraki bağlantıda 100bin satır yeniden gönderilecektir. Bu işlemi hızlandırmak için bir çözüm bulamadım. Bunun yerine bir transaction içerisine daha az komut eklenecek şekilde bir düzenleme yapmak en azından rollback sürecinde daha az satır için gerigönderme işlemi yapmış olacaktır.</p>
<p>Bu işlem için SQL Server 2000 SP1 ile gelen <b>MaxCmdsInTran</b> parametresi kullanılmaktadır. Bu parametre için MSDN&#8217;de aşağıdaki tanım yazılmıştır. </p>
<p><i>-MaxCmdsInTran number_of_commands</p>
<p>Requires Service Pack 1 or later. MaxCmdsInTran specifies the maximum number of statements grouped into a transaction as the Log Reader writes commands to the distribution database. Using this parameter allows the Log Reader Agent and Distribution Agent to divide large transactions (consisting of many commands) at the Publisher into several smaller transactions when applied at the Subscriber. Specifying this parameter can reduce contention at the Distributor and reduce latency between the Publisher and Subscriber. Because the original transaction is applied in smaller units, the Subscriber can access rows of a large logical Publisher transaction prior to the end of the original transaction, breaking strict transactional atomicity. The default is 0, which preserves the transaction boundaries of the Publisher.</i></p>
<p>Bu parametre Log Reader servisi için kullanılmaktadır. Görsel olarak set edilecek bir alan bulunmamaktadır. Bunun için SQL Server Agent altında çalışan Log Reader servisine ait Job&#8217;ın özellikleri kullanılır. Log Reader job&#8217;ının Properties menüsü tıklanarak Agent&#8217;i çalıştıran adıma &#8220;-MaxCmdsInTrans 1000&#8243; şeklinde değer girilebilir. Bu durumda Log Reader bulk işlemlerinde her transaction bloğunda 1000 komut olacak şeklinde ayarlama yapar.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.ahmetkaymaz.com/2010/02/12/replikasyonda-maxcmdsintran-parametresi/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

