<?xml version="1.0" encoding="UTF-8" ?>
<?xml-stylesheet type="text/xsl" href="http://sqlblog.com/utility/FeedStylesheets/rss.xsl" media="screen"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:wfw="http://wellformedweb.org/CommentAPI/"><channel><title>Did you know? -- Altering the length of a fixed-length column</title><link>http://sqlblog.com/blogs/kalen_delaney/archive/2006/10/13/alter-table-will-not-reclaim-space.aspx</link><description>You may be well aware that if you alter the length of a column to a larger value, that SQL Server doesn’t go through all the rows at the time you issue the ALTER. The ALTER is a metadata only change, and the actual movement of data doesn’t happen until</description><dc:language>en</dc:language><generator>CommunityServer 2.1 SP2 (Build: 61129.1)</generator><item><title>re: Did you know? -- Altering the length of a fixed-length column</title><link>http://sqlblog.com/blogs/kalen_delaney/archive/2006/10/13/alter-table-will-not-reclaim-space.aspx#302</link><pubDate>Fri, 13 Oct 2006 19:34:09 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:302</guid><dc:creator>Peter W. DeBetta</dc:creator><description>So then the question is: How do you &amp;quot;recover&amp;quot; that unused space?&lt;br&gt;&lt;br&gt;I found one way to do it. First, you'll need a not null column, You can either add one, or preferably, use an existing column. &lt;br&gt;&lt;br&gt;Using an existing column&lt;br&gt;1. Create and drop a Clustered Primary Key&lt;br&gt;&lt;br&gt; &amp;nbsp; &amp;nbsp;ALTER TABLE bigchange ADD CONSTRAINT pk_bigchange PRIMARY KEY (col1);&lt;br&gt; &amp;nbsp; &amp;nbsp;GO&lt;br&gt; &amp;nbsp; &amp;nbsp;ALTER TABLE bigchange DROP CONSTRAINT pk_bigchange;&lt;br&gt; &amp;nbsp; &amp;nbsp;GO&lt;br&gt;&lt;br&gt;2. Run the query that shows the leaf offset and see that the offsets are now &amp;quot;fixed&amp;quot;. In this case, the leaf offsets of col1, col2, and col3 are respectively: 4, 6, 3006&lt;br&gt;&lt;br&gt;Creating a new column&lt;br&gt;1. Create the new column. If the table has data the column must have some value. In this case, since there wasn't an identity defined, I just added the new column as an identity.&lt;br&gt;&lt;br&gt; &amp;nbsp; &amp;nbsp;ALTER TABLE bigchange ADD col4 int not null identity(1, 1);&lt;br&gt; &amp;nbsp; &amp;nbsp;GO&lt;br&gt;&lt;br&gt;2. Create and drop a Clustered Primary Key&lt;br&gt;&lt;br&gt; &amp;nbsp; &amp;nbsp;ALTER TABLE bigchange ADD CONSTRAINT pk_bigchange PRIMARY KEY (col1);&lt;br&gt; &amp;nbsp; &amp;nbsp;GO&lt;br&gt; &amp;nbsp; &amp;nbsp;ALTER TABLE bigchange DROP CONSTRAINT pk_bigchange;&lt;br&gt; &amp;nbsp; &amp;nbsp;GO&lt;br&gt;&lt;br&gt;3. Drop the column you added.&lt;br&gt;&lt;br&gt; &amp;nbsp; &amp;nbsp;ALTER TABLE bigchange DROP COLUMN col4;&lt;br&gt;&lt;br&gt;4. Run the query that shows the leaf offset and see that the offsets are now &amp;quot;fixed&amp;quot;. In this case, the leaf offsets of col1, col2, and col3 are respectively: 8, 10, 3010. You'll notice that all the leaf offsets are 4 more than in the first example - a remnant of col4 being there.&lt;br&gt;&lt;br&gt;I'm sure there are other techniques, and if you have them, do tell.&lt;br&gt;&lt;br&gt;--Peter</description></item><item><title>re: Did you know? -- Altering the length of a fixed-length column</title><link>http://sqlblog.com/blogs/kalen_delaney/archive/2006/10/13/alter-table-will-not-reclaim-space.aspx#303</link><pubDate>Fri, 13 Oct 2006 19:40:18 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:303</guid><dc:creator>Peter W. DeBetta</dc:creator><description>OOps - I forgot to mention that in my first example (using an existing column), I changed col1 to be NOT NULL so that I could do the example. So, if you want to try this yourself, replace the original CREATE TABLE code with:&lt;br&gt;&lt;br&gt;CREATE TABLE bigchange&lt;br&gt;(col1 smallint not null, col2 char(2000), col3 char(1000));&lt;br&gt;&lt;br&gt;--Peter</description></item><item><title>re: Did you know? -- Altering the length of a fixed-length column</title><link>http://sqlblog.com/blogs/kalen_delaney/archive/2006/10/13/alter-table-will-not-reclaim-space.aspx#306</link><pubDate>Mon, 16 Oct 2006 14:26:18 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:306</guid><dc:creator>Manu</dc:creator><description>I remember having this problem once, and I reclaimed the space by recreating the clustered key</description></item><item><title>re: Did you know? -- Altering the length of a fixed-length column</title><link>http://sqlblog.com/blogs/kalen_delaney/archive/2006/10/13/alter-table-will-not-reclaim-space.aspx#309</link><pubDate>Tue, 17 Oct 2006 15:10:34 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:309</guid><dc:creator>Peter W. DeBetta</dc:creator><description>Manu,&lt;br&gt;&lt;br&gt;I should have made the generalization that any clustered index would do the trick. Thanks for pointing it out. &lt;br&gt;&lt;br&gt;So if you already have a clustered index or key, you can recreate it. Of course, if the clustered key is being referenced by any foreign keys, you will have to drop those and recreate those references as well.&lt;br&gt;&lt;br&gt;Finally, another method would be (assuming there is no clustered index on the table)...&lt;br&gt;&lt;br&gt; &amp;nbsp; &amp;nbsp;CREATE CLUSTERED INDEX ic_bigchange ON bigchange(col1);&lt;br&gt; &amp;nbsp; &amp;nbsp;GO&lt;br&gt; &amp;nbsp; &amp;nbsp;DROP INDEX bigchange.ic_bigchange ;&lt;br&gt; &amp;nbsp; &amp;nbsp;GO&lt;br&gt;&lt;br&gt;--Peter</description></item><item><title>re: Did you know? -- Altering the length of a fixed-length column</title><link>http://sqlblog.com/blogs/kalen_delaney/archive/2006/10/13/alter-table-will-not-reclaim-space.aspx#381</link><pubDate>Thu, 30 Nov 2006 04:37:14 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:381</guid><dc:creator>Ewart</dc:creator><description>Hi there I've tried the clustered index trick and didn't work for me when changing data types in SQL 2000. &amp;nbsp;If anyone has any ideas:&lt;br&gt;&lt;br&gt;&lt;a rel="nofollow" target="_new" href="http://groups.google.co.nz/group/microsoft.public.sqlserver.server/browse_frm/thread/fabeb25ca4c15b89/6f47e93ff9d446b5?hl=en&amp;amp;"&gt;http://groups.google.co.nz/group/microsoft.public.sqlserver.server/browse_frm/thread/fabeb25ca4c15b89/6f47e93ff9d446b5?hl=en&amp;amp;&lt;/a&gt;&lt;br&gt;&lt;br&gt;regards&lt;br&gt;ewart</description></item><item><title>re: Did you know? -- Altering the length of a fixed-length column</title><link>http://sqlblog.com/blogs/kalen_delaney/archive/2006/10/13/alter-table-will-not-reclaim-space.aspx#1386</link><pubDate>Fri, 01 Jun 2007 21:48:33 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:1386</guid><dc:creator>Shaun</dc:creator><description>&lt;p&gt;Changing a type from fixed-decimal to vardecimal does not follow the principal of delayed change. &amp;nbsp;The data is modifed at time of setting.&lt;/p&gt;
</description></item><item><title>re: Did you know? -- Altering the length of a fixed-length column</title><link>http://sqlblog.com/blogs/kalen_delaney/archive/2006/10/13/alter-table-will-not-reclaim-space.aspx#1941</link><pubDate>Wed, 25 Jul 2007 23:25:06 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:1941</guid><dc:creator>david wei</dc:creator><description>&lt;p&gt;Kalen, &lt;/p&gt;
&lt;p&gt;I know it's an old thread but I am just reviewing all interested articles. (especially yours!)&lt;/p&gt;
&lt;p&gt;After done my own research, I found the following statement is not correct:&lt;/p&gt;
&lt;p&gt;&amp;quot;You may be well aware that if you alter the length of a column to a larger value, that SQL Server doesn’t go through all the rows at the time you issue the ALTER. The ALTER is a metadata only change, and the actual movement of data doesn’t happen until a row is updated.&amp;quot;&lt;/p&gt;
&lt;p&gt;When you alter a column (char or varchar), SQL server actually does move the data inside the page, you can noticed this by using DBCC page to check the this column is listed twice and one is marked as dropped. (the total number of columns is also increased by 1)&lt;/p&gt;
&lt;p&gt;you mentioned this in your storage book.&lt;/p&gt;
&lt;p&gt;The interesting is if you change the length to a SMALLER (not larger) value, SQL server does not move the data.&lt;/p&gt;
&lt;p&gt;David Wei&lt;/p&gt;
</description></item><item><title>re: Did you know? -- Altering the length of a fixed-length column</title><link>http://sqlblog.com/blogs/kalen_delaney/archive/2006/10/13/alter-table-will-not-reclaim-space.aspx#23635</link><pubDate>Mon, 22 Mar 2010 15:08:44 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:23635</guid><dc:creator>Salim Fayad</dc:creator><description>&lt;p&gt;Hi Kallen,&lt;/p&gt;
&lt;p&gt;I wanna congratulate you on the very nice book &amp;quot;Microsoft SQL Server 2008 Internals&amp;quot;. But I have 2 questions:&lt;/p&gt;
&lt;p&gt;1. If I have 2 columns of type &amp;quot;bit&amp;quot; in one table, how are they being stored? I noticed that they have the same offset and that they are saved in the same byte. Is this correct?&lt;/p&gt;
&lt;p&gt;2. I ran your query above and it produced some duplicate column. I noticed that the &amp;quot;sys.partitions&amp;quot; returned 2 records for the same table. Is there some specific criteria that I should put to make it generic to return back all the columns without duplication?&lt;/p&gt;
&lt;p&gt;Thank you very much.&lt;/p&gt;
&lt;p&gt;Regards,&lt;/p&gt;
&lt;p&gt;Salim Fayad&lt;/p&gt;
&lt;p&gt;salimfayad@hotmail.com&lt;/p&gt;
</description></item><item><title>re: Did you know? -- Altering the length of a fixed-length column</title><link>http://sqlblog.com/blogs/kalen_delaney/archive/2006/10/13/alter-table-will-not-reclaim-space.aspx#23636</link><pubDate>Mon, 22 Mar 2010 15:26:33 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:23636</guid><dc:creator>Kalen Delaney</dc:creator><description>&lt;p&gt;Hello Salim&lt;/p&gt;
&lt;p&gt;Up to 8 bit columns will be combined in a single byte, so it will show they have the same offset. &lt;/p&gt;
&lt;p&gt;I'm confused about your second question. My output shows one row for every column. Are you saying you get something different, running the same script?&lt;/p&gt;
&lt;p&gt;Or are you using a different table? You may need to read more about partitions and sys.partitions view. If you have indexes on the table, each index has its own partitions.&lt;/p&gt;
</description></item><item><title>re: Did you know? -- Altering the length of a fixed-length column</title><link>http://sqlblog.com/blogs/kalen_delaney/archive/2006/10/13/alter-table-will-not-reclaim-space.aspx#23655</link><pubDate>Tue, 23 Mar 2010 06:24:00 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:23655</guid><dc:creator>Salim Fayad</dc:creator><description>&lt;p&gt;Hi Kalen,&lt;/p&gt;
&lt;p&gt;You are right. There are 2 partitions on this table that I am doing the query. My question was: Is there some criteria to get the default partition that generates all the columns?&lt;/p&gt;
&lt;p&gt;Thank you.&lt;/p&gt;
</description></item><item><title>re: Did you know? -- Altering the length of a fixed-length column</title><link>http://sqlblog.com/blogs/kalen_delaney/archive/2006/10/13/alter-table-will-not-reclaim-space.aspx#23658</link><pubDate>Tue, 23 Mar 2010 09:23:54 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:23658</guid><dc:creator>Salim Fayad</dc:creator><description>&lt;p&gt;Hi Kalen again,&lt;/p&gt;
&lt;p&gt;Can you please help me in how the Transaction Log stores the LOB? (varbinary(MAX), text, ntext, image, ...)?&lt;/p&gt;
&lt;p&gt;Thank you in advance&lt;/p&gt;
</description></item><item><title>re: Did you know? -- Altering the length of a fixed-length column</title><link>http://sqlblog.com/blogs/kalen_delaney/archive/2006/10/13/alter-table-will-not-reclaim-space.aspx#23719</link><pubDate>Wed, 24 Mar 2010 23:48:47 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:23719</guid><dc:creator>Kalen Delaney</dc:creator><description>&lt;p&gt;Salim&lt;/p&gt;
&lt;p&gt;There is no such thing as a 'default' partition. All the partitions contain rows from the table and all the rows have all the columns. However, if you are seeing multiple rows for each column, you can filter the output for only one partition_number...something like: AND partition_number = 1&lt;/p&gt;
&lt;p&gt;As for you Transaction log question, MS does not make public exactly how LOB data is stored in log records.&lt;/p&gt;
&lt;p&gt;~Kalen&lt;/p&gt;
</description></item><item><title>re: Did you know? -- Altering the length of a fixed-length column</title><link>http://sqlblog.com/blogs/kalen_delaney/archive/2006/10/13/alter-table-will-not-reclaim-space.aspx#26994</link><pubDate>Tue, 13 Jul 2010 15:14:27 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:26994</guid><dc:creator>Mark Patrick</dc:creator><description>&lt;p&gt;I used Peter's technique to fix a large custom SQL table, in Sage CRM, that required many field revisions/deletions, due to poor design and haphazard maintenance. About half way through, I was getting row size errors and couldn't finish my clean-up job. Thanks Peter...and Kalen, for pointing out this somewhat obscure fact about SQL. I was down to considering having to delete the table, and everything related to it, and starting over. You both saved me at least 3-4 solid days of work.&lt;/p&gt;
</description></item><item><title>re: Did you know? -- Altering the length of a fixed-length column</title><link>http://sqlblog.com/blogs/kalen_delaney/archive/2006/10/13/alter-table-will-not-reclaim-space.aspx#36256</link><pubDate>Wed, 15 Jun 2011 10:32:41 GMT</pubDate><guid isPermaLink="false">21093a07-8b3d-42db-8cbf-3350fcbf5496:36256</guid><dc:creator>Martin</dc:creator><description>&lt;p&gt;Hi Kalen,&lt;/p&gt;
&lt;p&gt;I was trying to write a query that I could run against each database to detect tables and indexes with this issue.&lt;/p&gt;
&lt;p&gt;In doing so it came to my attention that the JOIN ON column_id = partition_column_id is not necessarily valid.&lt;/p&gt;
&lt;p&gt;An example where this is the case is below...&lt;/p&gt;
&lt;p&gt;DROP TABLE Foo&lt;/p&gt;
&lt;p&gt;CREATE TABLE Foo (A CHAR(65), B CHAR(66), C CHAR(67), D CHAR(68), E CHAR(69));&lt;/p&gt;
&lt;p&gt;CREATE CLUSTERED INDEX ixA ON Foo(A);&lt;/p&gt;
&lt;p&gt;CREATE NONCLUSTERED INDEX ixB ON Foo(B) INCLUDE (E);&lt;/p&gt;
&lt;p&gt;SELECT CASE max_inrow_length &lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;WHEN 4 THEN 'uniquifier' &lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;ELSE CHAR(max_inrow_length) &lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; END AS actual_column_name,&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; column_id,&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; name AS column_name_according_to_join,&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; max_inrow_length,&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; leaf_offset&lt;/p&gt;
&lt;p&gt;FROM &amp;nbsp; sys.system_internals_partition_columns pc&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; JOIN sys.partitions p&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ON p.partition_id = pc.partition_id &lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; LEFT JOIN sys.columns c&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; ON column_id = partition_column_id&lt;/p&gt;
&lt;p&gt; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; AND c.object_id = p.object_id&lt;/p&gt;
&lt;p&gt;WHERE p.object_id = OBJECT_ID('Foo') &amp;nbsp;AND index_id &amp;gt; 1 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &lt;/p&gt;
&lt;p&gt;Which returns&lt;/p&gt;
&lt;p&gt;actual_column_name column_id &amp;nbsp; column_name_according_to_join &amp;nbsp;max_inrow_length leaf_offset&lt;/p&gt;
&lt;p&gt;------------------ ----------- ------------------------------ ---------------- -----------&lt;/p&gt;
&lt;p&gt;B &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;1 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; A &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;66 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 1&lt;/p&gt;
&lt;p&gt;A &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;3 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; C &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;65 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 67&lt;/p&gt;
&lt;p&gt;uniquifier &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 4 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; D &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;4 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;-1&lt;/p&gt;
&lt;p&gt;E &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;2 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; B &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;69 &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; 132&lt;/p&gt;
</description></item></channel></rss>