How to drop default constraint based on column name - sql

I was looking this article
and I have just a question how to add IFEXISTS() in the select part:
I want to run #command only if there some rows. I think it will throw an error if I dont check select part?
declare #table_name nvarchar(256)
declare #Command nvarchar(max) = ''
set #table_name = N'ATableName'
select #Command = #Command + 'ALTER TABLE ' + #table_name + ' drop constraint ' + d.name + CHAR(10)+ CHAR(13)
from sys.tables t
join sys.default_constraints d on d.parent_object_id = t.object_id
join sys.columns c on c.object_id = t.object_id
and c.column_id = d.parent_column_id
where t.name = #table_name and c.name in ('column1','column2','column3')
--print #Command
execute (#Command)

Related

SQL Server how to find specific data across entire database

I have this script which finds all tables that contain data in column RGNCODE. I'm trying to amend this to find tables that contain a specific value for rgncode across all tables. So RGNCODE = 'UK'. Unsure where to add this in?
SELECT
sys.columns.name AS ColumnName,
tables.name AS TableName
FROM sys.columns
JOIN sys.tables ON sys.columns.object_id = tables.object_id
WHERE
sys.columns.name = 'rgncode' and
tables.name in (
SELECT [TableName] = so.name
FROM sysobjects so, sysindexes si
WHERE so.xtype = 'U' AND si.id = so.id
GROUP BY so.name
HAVING max(si.rows) > 0
)
A dynamic statement, using system catalog views, is an option here:
DECLARE #stm nvarchar(max) = N''
SELECT #stm = #stm +
CASE WHEN #stm = N'' THEN '' ELSE N'UNION ALL ' END +
N'SELECT ''' +
QUOTENAME(sch.[name]) + '.' + QUOTENAME(tab.[name]) + ''' AS TableName FROM ' +
QUOTENAME(sch.[name]) + '.' + QUOTENAME(tab.[name]) +
N' WHERE RGNCODE = ''UK'' HAVING COUNT(*) > 0 '
FROM sys.columns col
JOIN sys.tables tab ON col.object_id = tab.object_id
JOIN sys.schemas sch ON tab.schema_id = sch.schema_id
WHERE col.[name] = 'RGNCODE'
PRINT #stm
EXEC sp_executesql #stm
I think the following cursor will help you:
CREATE TABLE ##DataTable
(TblName VARCHAR(100),RowNum INT)
GO
DECLARE #TableName AS VARCHAR(200)
DECLARE #SQLText AS nVARCHAR(MAX)
DECLARE #TableCount AS INT
DECLARE TableDect CURSOR
FOR
SELECT
tables.name AS TableName
FROM
sys.columns
JOIN sys.tables ON
sys.columns.object_id = tables.object_id
WHERE
sys.columns.name = 'rgncode' and tables.name in (
SELECT
[TableName] = so.name
FROM
sysobjects so,
sysindexes si
WHERE
so.xtype = 'U'
AND
si.id = so.id
GROUP BY
so.name
HAVING max(si.rows) >0 )
OPEN TableDect
FETCH NEXT FROM TableDect INTO #TableName
WHILE ##FETCH_STATUS = 0
BEGIN
SET #SQLText = N'SELECT #NumberOUT=COUNT(*) FROM ' + QUOTENAME(#TableName) + ' WHERE rgncode=''UK'''
SET #TableCount = 0
EXECUTE sp_executesql #SQLText ,N'#NumberOUT nvarchar(25) OUTPUT' ,#NumberOUT=#TableCount OUTPUT
INSERT INTO ##DataTable values(#TableName,#TableCount)
FETCH NEXT FROM TableDect INTO #TableName
END
CLOSE TableDect;
DEALLOCATE TableDect
SELECT * FROM ##DataTable

SQL Server 2014 Dynamic SQL

Please take a look at the code and help me on the last part, --put all together = fail !!!
I wanted to generate a string for executing sp_executesql but I'm getting an error at the end. I also tried open cursor but it error out too.
Basically I'm trying to get actual row count per column per table for all tables
because general rowcount want give you if new column added and populated.
USE AdventureWorks2014
GO
-- Create view to hold the dataset
Alter view vColumnSchema
AS
with myColumnName
As
(
Select TOP (100) PERCENT
GetDate() As create_date,
##SERVERNAME As Server_Name,
DB_Name() AS database_name,
c.[object_id],
s.name AS [schema_name],
t.name as table_name,
c.name as column_name,
p.rows AS NUM_ROWS,
c.[precision]
from sys.tables as t
INNER JOIN sys.columns as c with(nolock) on t.[object_id] = c.[object_id]
INNER JOIN sys.indexes AS i ON t.object_id = i.object_id
INNER JOIN sys.partitions AS p ON i.object_id = p.object_id AND i.index_id = p.index_id
INNER JOIN sys.schemas AS s ON s.schema_id = t.schema_id
WHERE t.name NOT LIKE 'dt%'
AND i.object_id > 255
AND i.index_id <= 1
And s.name is not null
Order by s.name,
t.name
)
Select Top 100 percent
create_date,
Server_Name,
database_name,
[schema_name],
table_name,
column_name,
NUM_ROWS,
case when precision = 0 then
'Select Count('+column_name+')'+' from ' +[schema_name]+'.'+table_name+ ' where '+column_name+'<> '''' '
else
'Select Count(' +column_name+')'+' from ' +[schema_name]+ '.'+table_name+' where '+column_name+'> 0'
END as ColumnCount,
case when precision = 0
then ' <> '''' '
Else '> 0'
END As WhereClause
from myColumnName
Order by [schema_name],
table_name
GO
select * from vColumnSchema
where table_name = 'ProductCostHistory'
go
select * from Production.ProductCostHistory -- 395 records
--pick one record and test it = pass
Select Count(EndDate) from Production.ProductCostHistory where EndDate<> '' --200 records
GO
--test = pass on both whereClause
Declare #Column_name nvarchar(50) = 'EndDate'
Declare #Schema_Name nvarchar(20) = 'Production'
declare #table_name nvarchar(50) = 'ProductCostHistory'
declare #whereClause nvarchar(5) = '<> '''' '
declare #sqltext nvarchar(max) ='
select count('+#Column_name+') as ColumnCount from ' +#Schema_Name+'.'+#table_name+' where '+#Column_name+' '+#WhereClause+'
'
EXECUTE sp_executesql #sqltext
GO
--examine each column = pass
Declare #Column_name nvarchar(50) = 'select Column_name from vColumnSchema'
EXECUTE sp_executesql #Column_name
GO
Declare #schema_name nvarchar(50) = 'select schema_name from vColumnSchema'
EXECUTE sp_executesql #schema_name
GO
declare #table_name nvarchar(50) = 'select table_name from vColumnSchema'
EXECUTE sp_executesql #table_name
GO
declare #WhereClause nvarchar(50) = 'select WhereClause from vColumnSchema'
EXECUTE sp_executesql #WhereClause
GO
--put all together = fail !!!
declare #Column_name nvarchar(50) = 'select Column_name from vColumnSchema'
declare #schema_name nvarchar(50) = 'select schema_name from vColumnSchema'
declare #table_name nvarchar(50) = 'select table_name from vColumnSchema'
declare #WhereClause nvarchar(5) = 'select WhereClause from vColumnSchema';
declare #sqltext nvarchar(max) ='
select count('+#Column_name+') as ColumnCount from ' +#Schema_Name+'.'+#table_name+' where '+#Column_name+' '+#WhereClause+'
'
EXECUTE sp_executesql #sqltext
go
If you want the number of rows per column per table:
DECLARE #sql NVARCHAR(MAX) = '';
SELECT #sql = #sql +
N'SELECT '''
+ t.name + ''' AS TableName, '''
+ c.name + ''' AS ColName, COUNT(' + QUOTENAME(c.name) + ') AS [RowCount] FROM '
+ QUOTENAME(t.name) + ' UNION ALL' + CHAR(10)
FROM sys.tables t
INNER JOIN sys.columns c
ON c.object_id = t.object_id
WHERE
t.type = 'U'
AND c.system_type_id <> 35
SELECT #sql = LEFT(#sql, LEN(#sql) - 11)
PRINT #sql
EXECUTE sp_executesql #sql
Not Sure what your end game is But this might help and does not use dynamic sql ...
You can put the number of columns in your original query without a CTE
This puts the col count in the original select
Select TOP (100) PERCENT
GetDate() As create_date,
##SERVERNAME As Server_Name,
DB_Name() AS database_name,
c.[object_id],
s.name AS [schema_name],
t.name as table_name,
c.name as column_name,
p.rows AS NUM_ROWS,
c.[precision] ,
(Select COUNT(c2.object_id)
FROM sys.columns c2
INNER JOIN sys.tables t2 ON t2.object_id = c2.object_id
WHERE t2.object_id = t.object_id
GROUP BY c2.object_id) as ColCountThisTbl
from sys.tables as t
INNER JOIN sys.columns as c with(nolock) on t.[object_id] = c.[object_id]
INNER JOIN sys.indexes AS i ON t.object_id = i.object_id
INNER JOIN sys.partitions AS p ON i.object_id = p.object_id AND i.index_id = p.index_id
INNER JOIN sys.schemas AS s ON s.schema_id = t.schema_id
WHERE t.name NOT LIKE 'dt%'
AND i.object_id > 255
AND i.index_id <= 1
And s.name is not null
Order by s.name,
t.name `enter code here`

Programmatically rename all system name constraints

I have a distributed application that lives at many customer sites. The previous developer was not very good in giving user defined names to constraints. How could I go about renaming all the constrains to something like 'DF_[TableName]_[ColumnName]'? I could try and cursor over the list of tables. Do you think this would be a problem if I deploy this to a customer site? Or is there a better way to accomplish this?
SELECT sys.schemas.name as [Schema],
sys.tables.name as [TableName],
sys.all_columns.name as [Column],
default_constraints.name as [Constraint]
FROM
sys.all_columns
INNER JOIN sys.tables
ON all_columns.object_id = tables.object_id
INNER JOIN sys.schemas
ON tables.schema_id = schemas.schema_id
INNER JOIN sys.default_constraints
ON all_columns.default_object_id = default_constraints.object_id
where default_constraints.name like '%[0-9]%'
If you are using a naming convention for each constraint type, then this would help you. Here I am putting an example of how to handle this with Default constraint. The procedure will find default constraints, drop those that don't follow naming conventions and create new ones with the old one's definition.
This is a simple version for one time run
DECLARE #SchemaName sysname = 'dbo';
DECLARE #TableName sysname = NULL;
DECLARE #ColumnName sysname = NULL;
DECLARE #sql VARCHAR(max) = '';
SELECT
#sql +=
'ALTER TABLE [' + s.name + '].[' + o.name + '] DROP CONSTRAINT [' + dc.name + ']; ' +
'ALTER TABLE [' + s.name + '].[' + o.name + '] ADD CONSTRAINT [DF_' + o.name + '_' + c.name + '] DEFAULT ' + dc.DEFINITION + ' FOR [' + c.name + '];'
FROM dbo.sysobjects do
INNER JOIN dbo.sysobjects o ON do.parent_obj = o.id
INNER JOIN sys.default_constraints dc ON dc.object_id = do.id
INNER JOIN sys.columns c ON c.object_id = o.id
AND c.column_id = dc.parent_column_id
INNER JOIN sys.schemas s ON s.schema_id = dc.schema_id
WHERE o.type = 'U'
AND do.type = 'D'
AND s.name = #SchemaName
AND o.name = CASE WHEN ISNULL(#TableName,'') = ''
THEN o.name
ELSE #TableName END
AND c.name = CASE WHEN ISNULL(#ColumnName,'') = ''
THEN c.name
ELSE #ColumnName END
AND do.name NOT LIKE 'DF_' + o.name + '_' + c.name
ORDER BY o.name
--PRINT (#sql)
EXECUTE(#sql)
And this is a procedure in case you want to keep running the procedure every once in a while
USE [YourDatabaseName]
GO
-- Check if the procedure exists and drop it if so
IF EXISTS (SELECT *
FROM sys.objects
WHERE object_id = OBJECT_ID(N'[dbo].[usp_NamingConventionDefaultConstraint]') AND type in (N'P', N'PC'))
DROP PROCEDURE [dbo].[usp_NamingConventionDefaultConstraint]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
--procedure can be used for specific schema/table/columns or those can be left null to include everything.
CREATE PROC [dbo].[usp_NamingConventionDefaultConstraint]
#SchemaName sysname = 'dbo',
#TableName sysname = NULL,
#ColumnName sysname = NULL
AS
BEGIN
SET NOCOUNT ON;
DECLARE #sql VARCHAR(max)
DECLARE GetIndexes CURSOR
FOR
SELECT
--here drop the old constraint and create a new one with the old's definition
'ALTER TABLE [' + s.name + '].[' + o.name + '] DROP CONSTRAINT [' + dc.name + ']; ' +
'ALTER TABLE [' + s.name + '].[' + o.name + '] ADD CONSTRAINT [DF_' + o.name + '_' + c.name + '] DEFAULT ' + dc.DEFINITION + ' FOR [' + c.name + '];'
AS dc_alter
FROM dbo.sysobjects do
INNER JOIN dbo.sysobjects o ON do.parent_obj = o.id
INNER JOIN sys.default_constraints dc ON dc.object_id = do.id
INNER JOIN sys.columns c ON c.object_id = o.id
AND c.column_id = dc.parent_column_id
INNER JOIN sys.schemas s ON s.schema_id = dc.schema_id
WHERE o.type = 'U'
-- work only on default constraints
AND do.type = 'D'
AND s.name = #SchemaName
AND o.name = CASE WHEN ISNULL(#TableName,'') = '' THEN o.name ELSE #TableName END
AND c.name = CASE WHEN ISNULL(#ColumnName,'') = '' THEN c.name ELSE #ColumnName END
-- here goes the naming convention you have in mind
--DF_TableName_ColumnName
AND do.name NOT LIKE 'DF_' + o.name + '_' + c.name
ORDER BY o.name
OPEN GetIndexes
FETCH NEXT FROM GetIndexes
INTO #sql
WHILE ##FETCH_STATUS = 0
BEGIN
IF ISNULL(#sql,'')<>''
BEGIN
EXEC (#sql)
END
FETCH NEXT FROM GetIndexes
INTO #sql
END
CLOSE GetIndexes
DEALLOCATE GetIndexes
END
GO

Dynamic update statement with variable column names

We're looking to do an update in several SQL Server databases to change all NULL values in a certain table to be empty strings instead of NULL. We're potentially going to be doing this across hundreds of databases. The table name will always be the same, but the column names are variable based on how the front-end application is configured (don't judge... I didn't create this system).
Is there a way to do an update on all of these columns without knowing the column names ahead of time?
You can pass the name of the column in dynamic sql:
declare #sql nvarchar (1000);
set #sql = N'update table set ' + #column_name + '= ''''';
exec sp_executesql #sql;
You can look in the sys.columns table and join on the table name or object_id.
DECLARE #OBJ_ID INT
SELECT #OBJ_ID = OBJECT_ID
FROM SYS.tables
WHERE name = 'YOURTABLE'
SELECT * FROM SYS.columns
WHERE OBJECT_ID = #OBJ_ID
You could use the name field from the sys.columns query as a basis to perform the update on.
Assuming you want all columns of varchar/char types only (or change the type filter to whatever you need):
DECLARE #tableName varchar(10)
SET #tableName = 'yourtablenamehere'
DECLARE #sql VARCHAR(MAX)
SET #sql = ''
SELECT #sql = #sql + 'UPDATE ' + #tableName + ' SET ' + c.name + ' = '''' WHERE ' + c.name + ' IS NULL ;'
FROM sys.columns c
INNER JOIN sys.tables t ON c.object_id = t.object_id
INNER JOIN sys.types y ON c.system_type_id = y.system_type_id
WHERE t.name = #tableName AND y.name IN ('varchar', 'nvarchar', 'char', 'nchar')
EXEC (#sql)
This can be achieved with cursors. You first select the column names like #Darren mentioned, then you Set a Cursor with those values and loop:
Open oColumnsCursor
Fetch Next From oColumnscursor
Into #ColumnName
While ##FETCH_STATUS=0
Begin
Set #oQuery = 'Update [DB]..[Table] Set [' + #ColumnName + '] = ''NewValue'' Where [' + #ColumnName + '] = ''OldValue'''
Execute(#oQuery)
Fetch Next From oColumnscursor Into #ColumnName
Set #oCount = #oCount + 1
End
Close oColumnsCursor;
Deallocate oColumnsCursor;
This will work when you know the Table Name:
DECLARE #tableName varchar(10)
SET #tableName = 'Customers'
DECLARE #sql VARCHAR(MAX)
SET #sql = ''
SELECT #sql = #sql + 'UPDATE ' + #tableName + ' SET ' + c.name + ' = ISNULL('+ c.name +','''');'
FROM sys.columns c
INNER JOIN sys.tables t ON c.object_id = t.object_id
INNER JOIN sys.types y ON c.system_type_id = y.system_type_id
WHERE y.name IN ('varchar', 'nvarchar', 'char', 'nchar')
AND t.name = #tableName;
EXEC(#sql);
And this will iterate all Tables and all Columns in a Db:
DECLARE #sql VARCHAR(MAX)
SET #sql = ''
SELECT #sql = #sql + 'UPDATE ' + t.name + ' SET ' + c.name + ' = ISNULL('+ c.name +','''');'
FROM sys.columns c
INNER JOIN sys.tables t ON c.object_id = t.object_id
INNER JOIN sys.types y ON c.system_type_id = y.system_type_id
WHERE y.name IN ('varchar', 'nvarchar', 'char', 'nchar');
EXEC(#sql);
Below is the procedure.
ALTER PROCEDURE [dbo].[util_db_updateRow]
#colval_name NVARCHAR (30), -- column and values e.g. tax='5.50'
#idf_name NVARCHAR (300), -- column name
#idn_name NVARCHAR (300), -- column value
#tbl_name NVARCHAR (100) -- table name
AS
BEGIN
SET NOCOUNT ON;
DECLARE #sql NVARCHAR(MAX)
-- construct SQL
SET #sql = 'UPDATE ' + #tbl_name + ' SET ' + #colval_name +
' WHERE ' + #idf_name + '=' + #idn_name;
-- execute the SQL
EXEC sp_executesql #sql
SET NOCOUNT OFF
RETURN
END
Below is the stored procedure where you can pass Schema Name, Table Name and list of column names separted by comma.It works only in Sql Server 2016 or higher.
CREATE OR ALTER PROCEDURE UpdateData
(#SchemaName NVARCHAR(Max),#TableName NVARCHAR(MAX),#ColumnNames NVARCHAR(MAX))
AS
BEGIN
DECLARE #DynamicSql NVARCHAR(MAX);
SET #DynamicSql = 'UPDATE ' +'[' +#SchemaName+'].' + '[' +#TableName+']' +' SET ' + STUFF((SELECT ', [' + C.name + '] = ' + '''NEW_VALUE'''
FROM sys.columns C
INNER JOIN sys.tables T ON T.object_id = C.object_id
INNER JOIN sys.schemas S ON T.schema_id = S.schema_id
WHERE
T.name = #TableName
AND S.Name = #SchemaName
AND [C].[name] in (SELECT VALUE FROM string_split(#ColumnNames,','))
FOR XML PATH('')), 1,1, '')
print #DynamicSql;
EXEC (#DynamicSql);
END

How to drop SQL default constraint without knowing its name?

In Microsoft SQL Server, I know the query to check if a default constraint exists for a column and drop a default constraint is:
IF EXISTS(SELECT * FROM sysconstraints
WHERE id=OBJECT_ID('SomeTable')
AND COL_NAME(id,colid)='ColName'
AND OBJECTPROPERTY(constid, 'IsDefaultCnst')=1)
ALTER TABLE SomeTable DROP CONSTRAINT DF_SomeTable_ColName
But due to typo in previous versions of the database, the name of the constraint could be DF_SomeTable_ColName or DF_SmoeTable_ColName.
How can I delete the default constraint without any SQL errors? Default constraint names don't show up in INFORMATION_SCHEMA table, which makes things a bit trickier.
So, something like 'delete the default constraint in this table/column', or 'delete DF_SmoeTable_ColName', but don't give any errors if it can't find it.
Expanding on Mitch Wheat's code, the following script will generate the command to drop the constraint and dynamically execute it.
declare #schema_name nvarchar(256)
declare #table_name nvarchar(256)
declare #col_name nvarchar(256)
declare #Command nvarchar(1000)
set #schema_name = N'MySchema'
set #table_name = N'Department'
set #col_name = N'ModifiedDate'
select #Command = 'ALTER TABLE ' + #schema_name + '.[' + #table_name + '] DROP CONSTRAINT ' + d.name
from sys.tables t
join sys.default_constraints d on d.parent_object_id = t.object_id
join sys.columns c on c.object_id = t.object_id and c.column_id = d.parent_column_id
where t.name = #table_name
and t.schema_id = schema_id(#schema_name)
and c.name = #col_name
--print #Command
execute (#Command)
Rob Farley's blog post might be of help:
Two ways to find / drop a default constraint without knowing its name
Something like:
declare #table_name nvarchar(256)
declare #col_name nvarchar(256)
set #table_name = N'Department'
set #col_name = N'ModifiedDate'
select t.name, c.name, d.name, d.definition
from
sys.tables t
join sys.default_constraints d on d.parent_object_id = t.object_id
join sys.columns c on c.object_id = t.object_id
and c.column_id = d.parent_column_id
where
t.name = #table_name
and c.name = #col_name
I found that this works and uses no joins:
DECLARE #ObjectName NVARCHAR(100)
SELECT #ObjectName = OBJECT_NAME([default_object_id]) FROM SYS.COLUMNS
WHERE [object_id] = OBJECT_ID('[tableSchema].[tableName]') AND [name] = 'columnName';
EXEC('ALTER TABLE [tableSchema].[tableName] DROP CONSTRAINT ' + #ObjectName)
Just make sure that columnName does not have brackets around it because the query is looking for an exact match and will return nothing if it is [columnName].
To drop constraint for multiple columns:
declare #table_name nvarchar(256)
declare #Command nvarchar(max) = ''
set #table_name = N'ATableName'
select #Command = #Command + 'ALTER TABLE ' + #table_name + ' drop constraint ' + d.name + CHAR(10)+ CHAR(13)
from sys.tables t
join sys.default_constraints d on d.parent_object_id = t.object_id
join sys.columns c on c.object_id = t.object_id
and c.column_id = d.parent_column_id
where t.name = #table_name and c.name in ('column1','column2','column3')
--print #Command
execute (#Command)
Expanded solution (takes table schema into account):
-- Drop default contstraint for SchemaName.TableName.ColumnName
DECLARE #schema_name NVARCHAR(256)
DECLARE #table_name NVARCHAR(256)
DECLARE #col_name NVARCHAR(256)
DECLARE #Command NVARCHAR(1000)
set #schema_name = N'SchemaName'
set #table_name = N'TableName'
set #col_name = N'ColumnName'
SELECT #Command = 'ALTER TABLE [' + #schema_name + '].[' + #table_name + '] DROP CONSTRAINT ' + d.name
FROM sys.tables t
JOIN sys.default_constraints d
ON d.parent_object_id = t.object_id
JOIN sys.schemas s
ON s.schema_id = t.schema_id
JOIN sys.columns c
ON c.object_id = t.object_id
AND c.column_id = d.parent_column_id
WHERE t.name = #table_name
AND s.name = #schema_name
AND c.name = #col_name
EXECUTE (#Command)
Run this command to browse all constraints:
exec sp_helpconstraint 'mytable' --and look under constraint_name.
It will look something like this: DF__Mytable__Column__[ABC123]. Then you can just drop the constraint.
Drop all default contstraints in a database - safe for nvarchar(max) threshold.
/* WARNING: THE SAMPLE BELOW; DROPS ALL THE DEFAULT CONSTRAINTS IN A DATABASE */
/* MAY 03, 2013 - BY WISEROOT */
declare #table_name nvarchar(128)
declare #column_name nvarchar(128)
declare #df_name nvarchar(128)
declare #cmd nvarchar(128)
declare table_names cursor for
SELECT t.name TableName, c.name ColumnName
FROM sys.columns c INNER JOIN
sys.tables t ON c.object_id = t.object_id INNER JOIN
sys.schemas s ON t.schema_id = s.schema_id
ORDER BY T.name, c.name
open table_names
fetch next from table_names into #table_name , #column_name
while ##fetch_status = 0
BEGIN
if exists (SELECT top(1) d.name from sys.tables t join sys.default_constraints d on d.parent_object_id = t.object_id join sys.columns c on c.object_id = t.object_id and c.column_id = d.parent_column_id where t.name = #table_name and c.name = #column_name)
BEGIN
SET #df_name = (SELECT top(1) d.name from sys.tables t join sys.default_constraints d on d.parent_object_id = t.object_id join sys.columns c on c.object_id = t.object_id and c.column_id = d.parent_column_id where t.name = #table_name and c.name = #column_name)
select #cmd = 'ALTER TABLE [' + #table_name + '] DROP CONSTRAINT [' + #df_name + ']'
print #cmd
EXEC sp_executeSQL #cmd;
END
fetch next from table_names into #table_name , #column_name
END
close table_names
deallocate table_names
I hope this could be helpful for whom has similar problem .
In ObjectExplorer window, select your database=> Tables,=> your table=> Constraints. If the customer is defined on create column time, you can see the default name of constraint including the column name.
then use:
ALTER TABLE yourTableName DROP CONSTRAINT DF__YourTa__NewCo__47127295;
(the constraint name is just an example)
Following solution will drop specific default constraint of a column from the table
Declare #Const NVARCHAR(256)
SET #Const = (
SELECT TOP 1 'ALTER TABLE' + YOUR TABLE NAME +' DROP CONSTRAINT '+name
FROM Sys.default_constraints A
JOIN sysconstraints B on A.parent_object_id = B.id
WHERE id = OBJECT_ID('YOUR TABLE NAME')
AND COL_NAME(id, colid)='COLUMN NAME'
AND OBJECTPROPERTY(constid,'IsDefaultCnst')=1
)
EXEC (#Const)
declare #ery nvarchar(max)
declare #tab nvarchar(max) = 'myTable'
declare #qu nvarchar(max) = 'alter table '+#tab+' drop constraint '
select #ery = (select bj.name from sys.tables as tb
inner join sys.objects as bj
on tb.object_id = bj.parent_object_id
where tb.name = #tab and bj.type = 'PK')
exec(#qu+#ery)
Take a look.
I had some columns that had multiple default constraints created, so I create the following stored procedure:
CREATE PROCEDURE [dbo].[RemoveDefaultConstraints] #table_name nvarchar(256), #column_name nvarchar(256)
AS
BEGIN
DECLARE #ObjectName NVARCHAR(100)
START: --Start of loop
SELECT
#ObjectName = OBJECT_NAME([default_object_id])
FROM
SYS.COLUMNS
WHERE
[object_id] = OBJECT_ID(#table_name)
AND [name] = #column_name;
-- Don't drop the constraint unless it exists
IF #ObjectName IS NOT NULL
BEGIN
EXEC ('ALTER TABLE '+#table_name+' DROP CONSTRAINT ' + #ObjectName)
GOTO START; --Used to loop in case of multiple default constraints
END
END
GO
-- How to run the stored proc. This removes the default constraint(s) for the enabled column on the User table.
EXEC [dbo].[RemoveDefaultConstraints] N'[dbo].[User]', N'enabled'
GO
-- If you hate the proc, just get rid of it
DROP PROCEDURE [dbo].[RemoveDefaultConstraints]
GO
Useful for some columns that had multiple default constraints or check constraints created:
Modified https://stackoverflow.com/a/16359095/206730 script
Note: this script is for sys.check_constraints
declare #table_name nvarchar(128)
declare #column_name nvarchar(128)
declare #constraint_name nvarchar(128)
declare #constraint_definition nvarchar(512)
declare #df_name nvarchar(128)
declare #cmd nvarchar(128)
PRINT 'DROP CONSTRAINT [Roles2016.UsersCRM].Estado'
declare constraints cursor for
select t.name TableName, c.name ColumnName, d.name ConstraintName, d.definition ConstraintDefinition
from sys.tables t
join sys.check_constraints d on d.parent_object_id = t.object_id
join sys.columns c on c.object_id = t.object_id
and c.column_id = d.parent_column_id
where t.name = N'Roles2016.UsersCRM' and c.name = N'Estado'
open constraints
fetch next from constraints into #table_name , #column_name, #constraint_name, #constraint_definition
while ##fetch_status = 0
BEGIN
print 'CONSTRAINT: ' + #constraint_name
select #cmd = 'ALTER TABLE [' + #table_name + '] DROP CONSTRAINT [' + #constraint_name + ']'
print #cmd
EXEC sp_executeSQL #cmd;
fetch next from constraints into #table_name , #column_name, #constraint_name, #constraint_definition
END
close constraints
deallocate constraints
Always generate script and review before you run. Below the script
select 'Alter table dbo.' + t.name + ' drop constraint '+ d.name
from sys.tables t
join sys.default_constraints d on d.parent_object_id = t.object_id
join sys.columns c on c.object_id = t.object_id
and c.column_id = d.parent_column_id
where c.name in ('VersionEffectiveDate','VersionEndDate','VersionReasonDesc')
order by t.name
declare #table_name nvarchar(100)
declare #col_name nvarchar(100)
declare #constraint nvarchar(100)
set #table_name = N'TableName'
set #col_name = N'ColumnName'
IF EXISTS (select c.*
from sys.columns c
inner join sys.tables t on t.object_id = c.object_id
where t.name = #table_name
and c.name = #col_name)
BEGIN
select #constraint=d.name
from
sys.tables t
join sys.default_constraints d on d.parent_object_id = t.object_id
join sys.columns c on c.object_id = t.object_id
and c.column_id = d.parent_column_id
where
t.name = #table_name
and c.name = #col_name
IF LEN(ISNULL(#constraint, '')) <> 0
BEGIN
DECLARE #sqlcmd VARCHAR(MAX)
SET #sqlcmd = 'ALTER TABLE ' + QUOTENAME(#table_name) + ' DROP CONSTRAINT' +
QUOTENAME(#constraint);
EXEC (#sqlcmd);
END
END
GO
This will check if the foreign key exists or not. If it exists, then drop that.
DECLARE #SCHEMA_NAME NVARCHAR(256)
-- The table name you what drop the foreign key from.
DECLARE #ALTER_TABLE_NAME NVARCHAR(256)
-- The table name is liked with the foreign key.
DECLARE #REF_TABLE_NAME NVARCHAR(256)
DECLARE #COMMAND NVARCHAR(MAX)
SET #SCHEMA_NAME = N'MySchema';
SET #ALTER_TABLE_NAME = N'MyAlterTable';
SET #REF_TABLE_NAME = N'MyReferTable';
IF EXISTS (
SELECT NAME
FROM SYS.FOREIGN_KEYS
WHERE PARENT_OBJECT_ID = (
SELECT OBJECT_ID
FROM SYS.OBJECTS
WHERE OBJECT_ID = OBJECT_ID(#ALTER_TABLE_NAME)
)
AND REFERENCED_OBJECT_ID = (
SELECT OBJECT_ID
FROM SYS.OBJECTS
WHERE OBJECT_ID = OBJECT_ID(#REF_TABLE_NAME)
)
)
BEGIN
SELECT #COMMAND = 'ALTER TABLE ['
+ #SCHEMA_NAME
+ '].['
+ #ALTER_TABLE_NAME
+ '] DROP CONSTRAINT '
+ NAME
FROM SYS.FOREIGN_KEYS
WHERE PARENT_OBJECT_ID = (
SELECT OBJECT_ID
FROM SYS.OBJECTS
WHERE OBJECT_ID = OBJECT_ID(#ALTER_TABLE_NAME)
)
AND REFERENCED_OBJECT_ID = (
SELECT OBJECT_ID
FROM SYS.OBJECTS
WHERE OBJECT_ID = OBJECT_ID(#REF_TABLE_NAME)
)
EXECUTE (#COMMAND)
END
GO
Here is a simple solution, just replace your_table and the column_name.
DECLARE #var0 nvarchar(128)
SELECT #var0 = name
FROM sys.default_constraints
WHERE parent_object_id = object_id(N'${default_schema}.your_table')
AND col_name(parent_object_id, parent_column_id) = 'column_name';
IF #var0 IS NOT NULL
EXECUTE ('ALTER TABLE ${default_schema}.your_table DROP CONSTRAINT [' + #var0 + ']');
GO