<?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>mssql 彙整 - 泰克哪裡去</title>
	<atom:link href="https://tech.uccu.website/tag/mssql/feed" rel="self" type="application/rss+xml" />
	<link>https://tech.uccu.website/tag/mssql</link>
	<description>一個科技相關的隨手記錄網站</description>
	<lastBuildDate>Sun, 26 Jul 2020 05:52:51 +0000</lastBuildDate>
	<language>zh-TW</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.8.1</generator>
<site xmlns="com-wordpress:feed-additions:1">119574712</site>	<item>
		<title>單元測試與資料表自動遞增Id的問題</title>
		<link>https://tech.uccu.website/unittest-with-dbcc-checkident-reseed.html?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=unittest-with-dbcc-checkident-reseed</link>
					<comments>https://tech.uccu.website/unittest-with-dbcc-checkident-reseed.html#respond</comments>
		
		<dc:creator><![CDATA[鳴人]]></dc:creator>
		<pubDate>Tue, 19 May 2020 06:38:16 +0000</pubDate>
				<category><![CDATA[Database]]></category>
		<category><![CDATA[程式設計]]></category>
		<category><![CDATA[mssql]]></category>
		<category><![CDATA[unittest]]></category>
		<guid isPermaLink="false">https://tech.uccu.website/?p=28</guid>

					<description><![CDATA[<p>今天同事問了一個關於資料庫建立資料表重設Id遞增值的問題，主要是在單元測試中，使用的資料庫並不是每次都重新建立 ... <a title="單元測試與資料表自動遞增Id的問題" class="read-more" href="https://tech.uccu.website/unittest-with-dbcc-checkident-reseed.html" aria-label="Read more about 單元測試與資料表自動遞增Id的問題">閱讀全文</a></p>
<p>這篇文章 <a href="https://tech.uccu.website/unittest-with-dbcc-checkident-reseed.html">單元測試與資料表自動遞增Id的問題</a> 最早出現於 <a href="https://tech.uccu.website">泰克哪裡去</a>。</p>
]]></description>
										<content:encoded><![CDATA[
<p>今天同事問了一個關於資料庫建立資料表重設Id遞增值的問題，主要是在單元測試中，使用的資料庫並不是每次都重新建立，而是在執行單元測試之前，將資料表中的資料刪除，並且將Id欄位的初始值重設。<br>為了達到上面的需求，所以在一開始的時候會執行刪除資料和<a href="https://docs.microsoft.com/zh-tw/sql/t-sql/database-console-commands/dbcc-checkident-transact-sql?view=sql-server-ver15">DBCC CHECKIDENT (&#8216;TableName&#8217;, RESEED, 0)</a>將資料表的遞增種子重設為0，這樣在新增資料的時候就會+1變成從1開始(一般正常的情況)。</p>



<p>不過問題是，如果資料庫和資料表是第一次剛建立的，使用這個指令會讓Id欄位一開始的編號是0，期望的初始編號是1，但是在之後刪除資料並且使用上面的指令後，再新增資料的初始編號就會從1開始，符合期望的數字。</p>



<span id="more-28"></span>



<p>這個問題我試了一下，發現如果是資料庫與資料表剛建立的時候，若是執行<a href="https://docs.microsoft.com/zh-tw/sql/t-sql/database-console-commands/dbcc-checkident-transact-sql?view=sql-server-ver15">DBCC CHECKIDENT (&#8216;TableName&#8217;, NORESEED</a>)會取得NULL，但是新增資料的時候Id會是1(沒有執行ReSeed的情況下)，這部份感覺上應該是資料庫有自行處理這一個部份，所以若是在一開始執行ReSeed，反而是讓資料庫不處理NULL到1的部份，新增資料時的Id就變成是0。</p>



<p>原本建議同事在執行完單元測試的時候刪除資料時再做ReSeed的動作，不過他說有時候想要在新增資料後看看資料庫的內容，所以不想要立即刪除資料，因此詢問如何在執行單元測試之前判斷資料庫或資料表是否剛建立？</p>



<p>針對這個問題，我回到如何得知資料庫內的種子遞增值的方向來思考，如何在執行ReSeed之前取得目前的值，判斷是否為NULL再來針對接下來執行相對應的動作。</p>



<p>簡單查了一下，可以利用<a href="https://docs.microsoft.com/zh-tw/sql/t-sql/functions/ident-current-transact-sql?view=sql-server-ver15">IDENT_CURRENT( &#8216;table_or_view&#8217; )</a>這個語法來得知目前資料表的遞增值，透過Select IDENT_CURRENT( &#8216;table_or_view&#8217; ) As Seed來取得，後面的As Seed部份是將取得的值放在名為Seed名稱的欄位，沒有這一段也沒關係，只是沒有欄位名稱。</p>



<p>從微軟的文件庫中還有看到IDENT_SEED ( &#8216;table_or_view&#8217; )這個指令，是用來查詢最初設定欄位的遞增值，因為有時候可能會設定自動遞增的欄位不是從1開始，這時候就可以利用這個函數來查詢初始的設定，回傳的結果並不會受到DBCC CHECKIDENT重設的影響，也許以後會用到。</p>



<h3 class="wp-block-heading">2020/05/27 Update:</h3>



<p>後來同事告知使用Select IDENT_CURRENT( &#8216;table_or_view&#8217; ) As Seed的方式仍然會有問題，也就是說當資料表剛被建立，尚未新增資料的時候，IDENT_CURRENT函數取得的是1，新增多筆資料刪除之後再ReSeed設0，IDENT_CURRENT函數取得也會是1。</p>



<p>因為當資料表剛被建立尚未新增資料前，若是使用DBCC CHECKIDENT來ReSeed設0，第一筆資料新增的時候會直接使用ReSeed時給定的初始值(也就是0)。但是若資料表有新增過資料再刪除，重新ReSeed為0的時候，作法變成是給定的初始值+1，從上面的例子ReSeed為0的情況再+1就變成1，所以兩個情況都會取得1。</p>



<p>至於上次為何我會取到NULL值，應該是我當時在測試的時候沒有留意，執行IDENT_CURRENT函數的時候是在資料表尚未建立的時候(不存在的TableName)，所以取得的結果是NULL。</p>



<p>印象中上次在查詢資料的時候有看到另外的解法，就是去撈取系統資料表中的記錄，只是語法麻煩了一點，這次再把它找出來試了一下，並且留意資料表建立前後的問題，結果是可行的，語法如下：</p>



<blockquote class="wp-block-quote is-layout-flow wp-block-quote-is-layout-flow"><p>IF EXISTS (SELECT * FROM sys.identity_columns WHERE OBJECT_NAME(OBJECT_ID) = &#8216;<span class="has-inline-color has-vivid-green-cyan-color">TableName</span>&#8216; AND last_value IS NOT NULL)<br>DBCC CheckIdent(&#8216;<span class="has-inline-color has-vivid-green-cyan-color">TableName</span>&#8216;, ReSeed, 0);<br>Else<br>Print(&#8216;no need reseed&#8217;)</p></blockquote>



<h3 class="wp-block-heading"><strong>參考來源：</strong></h3>



<ul class="wp-block-list"><li><a href="https://docs.microsoft.com/zh-tw/sql/t-sql/functions/ident-current-transact-sql?view=sql-server-ver15">IDENT_CURRENT (Transact-SQL)</a></li><li><a href="https://stackoverflow.com/questions/472578/dbcc-checkident-sets-identity-to-0">DBCC CHECKIDENT Sets Identity to 0</a></li></ul>
<p>這篇文章 <a href="https://tech.uccu.website/unittest-with-dbcc-checkident-reseed.html">單元測試與資料表自動遞增Id的問題</a> 最早出現於 <a href="https://tech.uccu.website">泰克哪裡去</a>。</p>
]]></content:encoded>
					
					<wfw:commentRss>https://tech.uccu.website/unittest-with-dbcc-checkident-reseed.html/feed</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">28</post-id>	</item>
	</channel>
</rss>
