Question

I have a table in A Microsoft SQL 2012 database, called Courses. It was "upconverted" from an originally SQL 2000 database, upconverted to SQL 2008 database, and then upconverted again to 2012 (You can't directly upconvert from 2000 to 2012).

A result of this is that we have some tables that have the old text/ntext datatype, and I want to change the datatype to varchar(max) or nvarchar(max). For reasons I don't quite understand, I can't simply change the datatype of the ntext columns to nvarchar(max), because whenever I try to do that in Table Design view, I get this error:

enter image description here

Additionally, If I try to simply right click the Courses table in Management studio and Delete it, I see that there are quite a few other database objects dependent on Courses, and upon attempted delete, I get an error message saying I can't do so, because Courses is referenced by another Foreign Key constraint from another object.

So, essentially what I want to do is recreate a table, that has other objects depending on it, and the only thing different about the recreation is that I want to change the text/ntext columns in it to varchar(max) and nvarchar(max) datatypes. Everything currently "depending" on the 'old' Courses table, needs to then "depend" on the 'new' recreated Courses table. What's the easiest way to go about doing so in SQL 2012?

Was it helpful?

Solution

The simple way around this is to change some options in Management Studio.

Go to Tools, Options, Designers, Table and Database Designers. Uncheck "Prevent saving changes that require table re-creation".

Generally speaking, Management Studio will properly handle dependencies when you modify a table in a way that requires it to be recreated (it will do assorted tricks with temp tables behind the scenes, which you can see if you tell it to generate a change script instead of actually making the changes). However, this may involve modifications/changes to related tables or foreign keys. In other words, don't do this on a live system if you can help it, and make sure you've got backups before you do it.

OTHER TIPS

You can modify the ntext columns to nvarchar(max) using T-SQL. I'd only recommend doing this if the table/database is not actively being used. If the table is very small, this method will be quite fast and typically problem-free. However, if you have hundreds of millions of rows or more, I'd be concerned about doing this without testing it first in a non-production environment so you have some idea about how it works, and what space requirements will be in your situation.

To show how this works, and to prove it can be done, I've setup this test-bed.

First, we create a table with an ntext column, and populate it with 1,000 rows of random data:

USE tempdb;

CREATE TABLE dbo.OldTypes
(
    MyNTextColumn ntext NOT NULL
);

;WITH cte AS (
    SELECT v.Num
    FROM (VALUES(0), (1), (2), (3), (4), (5), (6), (7), (8), (9))v(num)
)
INSERT INTO dbo.OldTypes (MyNTextColumn)
SELECT CONVERT(ntext, CONVERT(nvarchar(4000), CRYPT_GEN_RANDOM(8000)))
FROM cte c1
    CROSS JOIN cte c2
    CROSS JOIN cte c3;

Here, we convert the MyNTextColumn to nvarchar(max):

ALTER TABLE dbo.OldTypes
ALTER COLUMN MyNTextColumn nvarchar(max);

This drops the temporary table created above, to clean up:

DROP TABLE dbo.OldTypes;

Alternative way:

Perform a backup before continuing.

You could...

  1. add a new column transfer_temp nvarchar(max) to your existing table
  2. move the data to the new column
  3. rename the column <old_column_name> to <old_column_name>_back
  4. rename the new column transfer_temp to <old_column_name>
  5. test the data
  6. Drop the old column <old_column_name>_back

The advantage is that your data is still in the old column definition up until you drop the column after testing the application and/or data.

This can be achieved as follows:

ALTER TABLE <your_table> ADD transfer_temp AS nvarchar(max)

Then move the data from your old column to the new column:

UPDATE <your_table> SET transfer_temp = <old_column_name>

Rename your columns:

EXEC sp_rename 'dbo.<your_table>.<old_column_name>', '<old_column_name>_back', 'COLUMN'
GO
EXEC sp_rename 'dbo.<your_table>.transfer_temp', '<old_column_name>', 'COLUMN'

Test your application again.

Drop the old data:

ALTER TABLE <your_table> DROP COLUMN <old_column_name>_back

Finished.

sp_rename

Licensed under: CC-BY-SA with attribution
Not affiliated with dba.stackexchange
scroll top