I am trying to rename the column datatype from text to ntext but getting error
Msg 4927, Level 16, State 1, Line 1
Cannot alter column 'ColumnName' to be data type ntext.
query that i m using is as follows:-
alter table tablename alter column columnname ntext null
Conversion not allowed. Add new column as ntext then copy converted data to new column, then delete old column. Might consume a lot of diskspace if it's a large table!
You should use NVARCHAR(MAX) instead of NTEXT which will not be supported in the future.
Msg 4927
I expect you'll need to copy the data out - i.e. add a scratch column, fill it; drop the old column; add the new column, copy the data back, remove the scratch column:
ALTER TABLE TableName ADD tmp text NULL
GO
UPDATE TableName SET tmp = ColumnName
GO
ALTER TABLE TableName DROP COLUMN ColumnName
GO
ALTER TABLE TableName ADD ColumnName ntext NULL
GO
UPDATE TableName SET ColumnName = tmp
GO
ALTER TABLE TableName DROP COLUMN tmp
For applying database-wide, you can script it out from info-schema (note you should filter out any system tables etc):
SELECT 'ALTER TABLE [' + TABLE_SCHEMA + '].[' + TABLE_NAME+ '] ADD [__tmp] text NULL
GO
UPDATE [' + TABLE_SCHEMA + '].[' + TABLE_NAME+ '] SET [__tmp] = [' + COLUMN_NAME + ']
GO
ALTER TABLE [' + TABLE_SCHEMA + '].[' + TABLE_NAME+ '] DROP COLUMN [' + COLUMN_NAME + ']
GO
ALTER TABLE [' + TABLE_SCHEMA + '].[' + TABLE_NAME+ '] ADD [' + COLUMN_NAME + '] ntext ' +
CASE IS_NULLABLE WHEN 'YES' THEN 'NULL' ELSE 'NOT NULL' END + '
GO
UPDATE [' + TABLE_SCHEMA + '].[' + TABLE_NAME+ '] SET [' + COLUMN_NAME + '] = [__tmp]
GO
ALTER TABLE [' + TABLE_SCHEMA + '].[' + TABLE_NAME+ '] DROP COLUMN [__tmp]'
FROM INFORMATION_SCHEMA.COLUMNS WHERE DATA_TYPE = 'text'
In MySQL, the query is:
ALTER TABLE [tableName] CHANGE [oldColumnName] [newColumnName] [newColumnType];
Related
Note> I can not modify old scripts!!!
First script create table TABLENAME.
I have table TABLENAME with column COLUMNNAME DATE DEFAULT GETDATE();
I need to do: ->
ALTER TABLE TABLENAME
ALTER COLUMN COLUMNNAME DATETIME;
I get a error:
The object 'DF__TABLENAME__COLUMNNAME__7BC8385B' is dependent on column 'COLUMNNAME'.
I have this scripts on multiple databases so this part 'DF__TABLENAME__COLUMNNAME__7BC8385B'
is on every database different.
I can make
ALTER TABLE TABLENAME
DROP CONSTRAINT DF__TABLENAME__COLUMNNAME__7BC8385B;
And it will work, but It will not be very effective use it manually on all DB, I need make the script which will alter this column on everywhere without needed to know that constraint name.
If you've got variable constraint names you'll have to generate the change script per database. If you've got faith in this you can put the resulting script into an sp_executesql call.
This is using the sys views to query the database structure and generate the script in the last result column.
declare #TableName nvarchar(128) = 'TABLENAME';
declare #ColumnName nvarchar(128) = 'COLUMNNAME';
SELECT t.name [table], c.name [column], typ.name [type]
, def.name [DefaultConstraint], def.definition [DefaultValue]
, 'ALTER TABLE [' + t.name + '] DROP CONSTRAINT [' + def.name + ']; ALTER TABLE [' + t.name + '] ALTER COLUMN [' + c.name + '] DATETIME; ALTER TABLE [' + t.name + '] ADD CONSTRAINT [DF_' + t.name + '_' + c.name + '] DEFAULT getdate() FOR [' + c.name + '];'
FROM sys.columns c
JOIN sys.tables t ON c.object_id = t.object_id
JOIN sys.types typ on c.user_type_id=typ.user_type_id
LEFT JOIN sys.default_constraints def on c.default_object_id=def.object_id
WHERE typ.name = 'date'
and t.name = #TableName and c.name = #ColumnName
order by t.name, c.name
Does anyone have a script that will delete all non-system tables/procs/views from a database?
I created some views, procs and tables which I need to clean up and doing them individually is too cumbersome.
You could always query your system catalog views and have it generate the necessary DROP statements:
SELECT 'DROP PROCEDURE [' + SCHEMA_NAME(schema_id) + '].[' + pr.NAME +']'
FROM sys.procedures pr
WHERE pr.is_ms_shipped = 0
UNION
SELECT 'DROP VIEW [' + SCHEMA_NAME(schema_id) + '].[' + v.NAME + ']'
FROM sys.views v
WHERE v.is_ms_shipped = 0
UNION
SELECT 'ALTER TABLE [' + SCHEMA_NAME(schema_id) + '].[' + OBJECT_NAME(fk.parent_object_ID) + '] DROP CONSTRAINT ' + fk.name
FROM sys.foreign_keys fk
WHERE is_ms_shipped = 0
UNION
SELECT 'DROP TABLE [' + SCHEMA_NAME(schema_id) + '].[' + t.NAME + ']'
FROM sys.tables t
WHERE t.is_ms_shipped = 0
This will generate a long list of DROP ..... statements, just copy & paste those into a new SSMS window and execute them.
Wouldn't it be easier to drop/recreate the database?
DROP DATABASE yourdbname
CREATE DATABASE yourdbname
How to change one attribute in a table using T-SQL to allow nulls (not null --> null)? Alter table maybe?
-- replace NVARCHAR(42) with the actual type of your column
ALTER TABLE your_table
ALTER COLUMN your_column NVARCHAR(42) NULL
Yes you can use ALTER TABLE as follows:
ALTER TABLE [table name] ALTER COLUMN [column name] [data type] NULL
Quoting from the ALTER TABLE documentation:
NULL can be specified in ALTER COLUMN to force a NOT NULL column to allow null values, except for columns in PRIMARY KEY constraints.
ALTER TABLE is right:
ALTER TABLE MyCustomers ALTER COLUMN CompanyName VARCHAR(20) NULL
For MySQL, MariaDB
ALTER TABLE [table name] MODIFY COLUMN [column name] [data type] NULL
Use MODIFY COLUMN instead of ALTER COLUMN.
ALTER TABLE public.contract_termination_requests
ALTER COLUMN management_company_id DROP NOT NULL;
I wrote this so I could edit all tables and columns to null at once:
select
case
when sc.max_length = '-1' and st.name in ('char','decimal','nvarchar','varchar')
then
'alter table [' + so.name + '] alter column [' + sc.name + '] ' + st.name + '(MAX) NULL'
when st.name in ('char','decimal','nvarchar','varchar')
then
'alter table [' + so.name + '] alter column [' + sc.name + '] ' + st.name + '(' + cast(sc.max_length as varchar(4)) + ') NULL'
else
'alter table [' + so.name + '] alter column [' + sc.name + '] ' + st.name + ' NULL'
end as query
from sys.columns sc
inner join sys.types st on st.system_type_id = sc.system_type_id
inner join sys.objects so on so.object_id = sc.object_id
where so.type = 'U'
and st.name <> 'timestamp'
order by st.name
This is the approach to do this: -
Check whether the table or column exists or not.
If yes, then alter the column. e.g:-
IF EXISTS (SELECT 1 FROM INFORMATION_SCHEMA.COLUMNS WHERE
TABLE_CATALOG = 'DBName' AND
TABLE_SCHEMA = 'SchemaName' AND
TABLE_NAME = 'TableName' AND
COLUMN_NAME = 'ColumnName')
BEGIN
ALTER TABLE DBName.SchemaName.TableName ALTER COLUMN ColumnName [data type] NULL
END
If you don't have any schema then delete the schema line because you don't need to give the default schema.
So the simplest way is,
alter table table_name change column_name column_name int(11) NULL;
what would be the simplest way to change every nvarchar column in a database to a varchar?
I personally would prefer nvarchar, but the data arch has specified that varchar must be used.
Here, to get you started:
Select 'Alter Table [' + TABLE_SCHEMA + '].[' + TABLE_NAME + '] Alter Column [' + COLUMN_NAME + '] VarChar(' + CAST(CHARACTER_MAXIMUM_LENGTH As VARCHAR) + ')'
From INFORMATION_SCHEMA.COLUMNS
WHERE DATA_TYPE = 'NVARCHAR'
This will generate all the needed alter statements for you (cut, paste, run).
Note that this does not take any constraints into account.
In order to handle MAX and exclude the niggly sysdiagrams:
SELECT
'
ALTER TABLE [' + TABLE_SCHEMA + '].[' + TABLE_NAME + ']
ALTER COLUMN [' + COLUMN_NAME + ']
VARCHAR(' +
(CASE WHEN CHARACTER_MAXIMUM_LENGTH = -1
THEN 'MAX'
ELSE CAST(CHARACTER_MAXIMUM_LENGTH AS VARCHAR)
END)
+ ')
'
FROM INFORMATION_SCHEMA.COLUMNS
WHERE DATA_TYPE = 'NVARCHAR' AND TABLE_NAME <> 'SYSDIAGRAMS'
Ask the data arch to do it?
or
Generate a script of all objects in your system, alter then nvarchar's, then create a new database and import the data into it from the old one.
or
Write alter scripts to update the existing database.
(This may be the best approach if it's a production database, or a client database.)
I have a list of half a dozen MSSQL 2008 tables that I would like to remove at once from my database. The data has been entirely migrated to new tables. There is no reference in the new tables to the old tables.
The problem being that old tables comes with loads of inner FK constraints that have been autogenerated by a tool (aspnet_regsql actually). Hence dropping manually all constraints is a real pain.
How can I can drop the old tables ignoring all inner constraints?
It depends on how you want to drop the tables. If list of tables need to drop covers almost above 20 % of tables under your DB.
Then I will disable all the constraints in that DB under my script and drop the tables and Enable the constraints under the same script.
--To Disable a Constraint at DB level
EXEC sp_MSForEachTable 'ALTER TABLE ? NOCHECK CONSTRAINT ALL'
--Write the code to DROP tables
DROP TABLE TABLENAME
DROP TABLE TABLENAME
DROP TABLE TABLENAME
--To Enable a Constraint at DB level
EXEC sp_MSForEachTable 'ALTER TABLE ? CHECK CONSTRAINT ALL'
Finally to check the Status of your constraints fire up this Query.
--Checks the Status of Constraints
SELECT (CASE
WHEN OBJECTPROPERTY(CONSTID, 'CNSTISDISABLED') = 0 THEN 'ENABLED'
ELSE 'DISABLED'
END) AS STATUS,
OBJECT_NAME(CONSTID) AS CONSTRAINT_NAME,
OBJECT_NAME(FKEYID) AS TABLE_NAME,
COL_NAME(FKEYID, FKEY) AS COLUMN_NAME,
OBJECT_NAME(RKEYID) AS REFERENCED_TABLE_NAME,
COL_NAME(RKEYID, RKEY) AS REFERENCED_COLUMN_NAME
FROM SYSFOREIGNKEYS
ORDER BY TABLE_NAME, CONSTRAINT_NAME,REFERENCED_TABLE_NAME, KEYNO
If you dont want to disable the constraints at Database level then make a list of tables which you want to drop.
Step1 : Check the Constraints associated with thos tables
SELECT *
FROM sys.foreign_keys
WHERE referenced_object_id = object_id('dbo.Tablename')
Step2 : Disable the Constraints which are associated with these tables.
ALTER TABLE MyTable NOCHECK CONSTRAINT MyConstraint
Step3 : Drop the tables
DROP TABLE TABLENAME
A simple DROP TABLE dbo.MyTable will ignore all constraints (and triggers) except foreign keys (unless you drop the child/referencing table first) where you may have to drop these first.
Edit: after comment:
There is no automatic way. You'll have to iterate through sys.foreign_keys and generate some ALTER TABLE statements.
Run the following script to delete all the constraints in all tables under current DB and then run the drop table statements.
DECLARE #dropAllConstraints NVARCHAR(MAX) = N'';
SELECT #dropAllConstraints += N'
ALTER TABLE ' + QUOTENAME(OBJECT_SCHEMA_NAME(parent_object_id))
+ '.' + QUOTENAME(OBJECT_NAME(parent_object_id)) +
' DROP CONSTRAINT ' + QUOTENAME(name) + ';'
FROM sys.foreign_keys;
EXEC sp_executesql #dropAllConstraints
I found a reasonable(ish) way to do it by making SQL write the SQL to drop the constraints:
select concat("alter table ", table_name, " drop ", constraint_type ," ", constraint_name, ";")
from information_schema.table_constraints
where table_name like 'somefoo_%'
and
constraint_type <> "PRIMARY KEY";
You will want to modify the table name to suit your needs, or possibly select against other column/values.
Also, this would select any non primary key constraint, which might be too big of a sledgehammer. Maybe you need to just set it to =?
I am not a DBA. there may be better ways to do this, but it worked well enough for my purposes.
I finally found the solution based on the script provided by Jason Presley. This script automatically removes all constraints in the DB. It's easy to add a WHERE clause so that it only applies to the set of concerned tables. After that, dropping all tables is a straightforward.
Be very careful with the following script, all tables, views, functions, stored procedures and user defined types from a database ignoring all constraints.
/*
Description: This script will remove all tables, views, functions, stored procedures and user defined types from a database.
*/
declare #n char(1)
set #n = char(10)
declare #stmt nvarchar(max)
-- procedures
select #stmt = isnull( #stmt + #n, '' ) +
'drop procedure [' + schema_name(schema_id) + '].[' + name + ']'
from sys.procedures
-- check constraints
select #stmt = isnull( #stmt + #n, '' ) +
'alter table [' + schema_name(schema_id) + '].[' + object_name( parent_object_id ) + '] drop constraint [' + name + ']'
from sys.check_constraints
-- functions
select #stmt = isnull( #stmt + #n, '' ) +
'drop function [' + schema_name(schema_id) + '].[' + name + ']'
from sys.objects
where type in ( 'FN', 'IF', 'TF' )
-- views
select #stmt = isnull( #stmt + #n, '' ) +
'drop view [' + schema_name(schema_id) + '].[' + name + ']'
from sys.views
-- foreign keys
select #stmt = isnull( #stmt + #n, '' ) +
'alter table [' + schema_name(schema_id) + '].[' + object_name( parent_object_id ) + '] drop constraint [' + name + ']'
from sys.foreign_keys
-- tables
select #stmt = isnull( #stmt + #n, '' ) +
'drop table [' + schema_name(schema_id) + '].[' + name + ']'
from sys.tables
-- user defined types
select #stmt = isnull( #stmt + #n, '' ) +
'drop type [' + schema_name(schema_id) + '].[' + name + ']'
from sys.types
where is_user_defined = 1
exec sp_executesql #stmt
I suspect that you would have to do an 'alter' command on the offending tables before the drop to remove the forigen key contraints.
ALTER TABLE Orders DROP FOREIGN KEY fk_PerOrders;
DROP TABLE Orders;
Of course if you drop the child tables first, then you wont have this problem.
(unless you have table A contraint to table B and table B constraint to A, then you will need to Alter one of the tables, e.g. A to remove the constraint)
e.g. this WONT work, since Orders has a contraint from Order_Lines
DROP TABLE Orders;
DROP TABLE Order_lines;
e.g. this will work
DROP TABLE Order_lines;
DROP TABLE Orders;