How to Drop Clustered Index on Primary Key Column? – Interview Question of the Week #084

Question: How do you drop the clustered index that enforces a primary key?

Answer: Remove the primary-key constraint with ALTER TABLE … DROP CONSTRAINT. If you still need that primary key, recreate it as NONCLUSTERED as part of a planned change. DROP INDEX cannot directly remove its enforcing index.

A wooden box with a sliding lid beside its former hinged lid and brass hinges

The first two articles in this sequence established the relationship: dropping a primary key can remove its clustered index, while DROP INDEX is refused for that protected index. This question turns the observation into a deliberate change.

In the original Table1 experiment, both metadata queries returned PK_Table1_Col1:

Original native results showing Table1 primary-key constraint and clustered index

After ALTER TABLE Table1 DROP CONSTRAINT PK_Table1_Col1, both queries were empty:

Original native empty primary-key and clustered-index result sets after constraint removal

Those are useful historical results and they remain here. They also show the consequence that a brief answer can overlook: the example removed the primary key, not just a storage structure.

Keep the primary key when that is the goal

For a fresh sample table with no foreign keys, this example first reproduces error3723 and then changes the primary key from clustered to nonclustered in a transaction. It preserves the rows and the uniqueness rule:

IF @@TRANCOUNT <> 0
    THROW 50001, 'Run this demonstration outside an existing transaction.', 1;
IF OBJECT_ID('tempdb..#SqlaConvert39471') IS NOT NULL
    THROW 50001, 'The sample table already exists in this session.', 1;
CREATE TABLE #SqlaConvert39471
 (Col1 int NOT NULL, Col2 varchar(100) NULL,
  CONSTRAINT PK_Sqla39471 PRIMARY KEY CLUSTERED (Col1));
INSERT #SqlaConvert39471 VALUES (1,'One'),(2,'Two');
SELECT N'Before' AS Step, i.name, i.type_desc, i.is_primary_key
FROM tempdb.sys.indexes AS i
WHERE i.object_id = OBJECT_ID('tempdb..#SqlaConvert39471');
BEGIN TRY
    EXEC(N'DROP INDEX PK_Sqla39471 ON #SqlaConvert39471;');
END TRY
BEGIN CATCH
    SELECT ERROR_NUMBER() AS ExpectedError;
END CATCH;
-- Keep the PK rule while changing its physical implementation.
BEGIN TRY
    BEGIN TRANSACTION;
    ALTER TABLE #SqlaConvert39471 DROP CONSTRAINT PK_Sqla39471;
    ALTER TABLE #SqlaConvert39471 ADD CONSTRAINT PK_Sqla39471
        PRIMARY KEY NONCLUSTERED (Col1);
    COMMIT;
END TRY
BEGIN CATCH
    IF XACT_STATE() <> 0 ROLLBACK;
    THROW;
END CATCH;
SELECT N'After' AS Step, i.name, i.type_desc, i.is_primary_key
FROM tempdb.sys.indexes AS i
WHERE i.object_id = OBJECT_ID('tempdb..#SqlaConvert39471');
SELECT Col1, Col2 FROM #SqlaConvert39471 ORDER BY Col1;
DROP TABLE #SqlaConvert39471;
Native SSMS before and after metadata shows a nonclustered primary key with both original table rows preserved.
Current output includes the expected 3723 refusal, the changed primary-key index and the two preserved rows. The complete transaction remains copyable above.

Before the change, the enforcing index is CLUSTERED. After it, the table has a HEAP entry and a NONCLUSTERED primary-key index. The primary key still exists and the two data rows remain. The transaction is important because dropping the constraint alone would leave its rule absent.

Plan the real table’s dependencies

This small sample has no foreign keys. A referenced primary key cannot simply be dropped as shown while dependencies remain. For a real redesign, script those dependencies and constraint properties, plan locking and storage work, and verify the resulting definitions and data. Changing the clustering arrangement can also affect nonclustered indexes.

My original warning that every table must have both a clustered index and a primary key was too broad. Heaps are valid structures, and designs need to match their workload and integrity requirements. The point here is to retain the rules you intend while changing the index that implements them.

Tell me which follow-up question you would ask after this demonstration. Understanding what remains is at least as useful as knowing which DROP command succeeds.

Published by Pinal Dave on SQLAuthority. More of my work at pinaldave.com.


Discover more from SQL Authority with Pinal Dave

Subscribe to get the latest posts sent to your email.

Clustered Index, SQL Constraint and Keys, SQL Server
Previous Post
Does Dropping Clustered Index Drop Primary Key on the Same Column? – Interview Question of the Week #083
Next Post
Does Dropping Primary Key Drop Non-Clustered Index on the Column? – Interview Question of the Week #085

Related Posts

8 Comments. Leave new

  • Sanjay Monpara
    August 14, 2016 11:08 pm

    Hi pinal,
    In this post I read
    “Remember, it is not a good idea to have a table with clustered index or primary key as they are very critical element in RDBMS for database integrity and performance.”

    Could you give say something more about it or give reference of any related post?

    Reply
  • wilfred van Dijk
    August 15, 2016 12:19 pm

    I think it should be WITHOUT CLUSTERED INDEX instead of WITH CLUSTERED INDEX

    Reply
  • Hi Pinal,
    Ur statement dont go well with RDBMS>
    “Remember, it is not a good idea to have a table with clustered index or primary key as they are very critical element in RDBMS for database integrity and performance.”

    Please if you wanted to say something else or guide us how ur statement is correct.
    Thanks

    Reply
    • Hi Ashok,

      I think what I meant to say was Remember, it is not a good idea to have a table without clustered index or primary key as they are very critical element in RDBMS for database integrity and performance.

      I think I had typo there. I have made the correction. I hope now the statement is clear.

      Reply
  • “How to Drop Clustered Index on Primary Key Column?” and the answer is you can not;
    what you have suggested is to drop “Primary Key” it self.

    Reply
  • HI Pinal,
    I am totally agree with you.

    Vineet Goyal

    Reply
  • Mohammed Zaid Meraj
    October 5, 2017 1:28 pm

    getting error like
    Msg 3727, Level 16, State 0, Line 2
    Could not drop constraint. See previous errors

    Reply
  • Alter statement still gives an error i.e.,
    Could not drop the primary key constraint ‘PK_Table1_Col1’ because the table has an XML or spatial index.

    Reply

Leave a Reply

Your email address will not be published. Required fields are marked *

Fill out this field
Fill out this field
Please enter a valid email address.