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)
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
I am using a Multi tenant Shared schema database, so i have so many schema,
Required:
I want to remove some schema; for that i have to remove all the CONSTRAINT of tables in that schema to delete a table. I got the the list of query to remove all the CONSTRAINT of a schema and the query to delete the tables from below code
Question:
From the below code i got a list of Queries,now i am copy that queries and executing that list of queries manually,can i do that automatically ?
Code
SET NOCOUNT ON;
DECLARE #SchemaName nvarchar(250)
SET #SchemaName='schemaname1'
--Step 1: Remove all CONSTRAINT
SELECT 'ALTER TABLE ' +'[' + s.name + '].[' + t.name + ']' +' DROP CONSTRAINT [' + f.name +']'
FROM sys.foreign_keys f
INNER JOIN sys.TABLES t ON f.parent_object_id=t.object_id
INNER JOIN sys.schemas s ON t.schema_id=s.schema_id
WHERE t.is_ms_shipped=0
and t.schema_id = schema_id(#SchemaName);
--Step 2: Drop all Tables
SELECT 'DROP TABLE ' + '[' + s.name + '].[' + t.name + ']'
FROM sys.TABLES t
INNER JOIN sys.schemas s ON t.schema_id=s.schema_id
WHERE t.is_ms_shipped=0 and t.schema_id = schema_id(#SchemaName);
Using COALESCE function we can turn multiple rows into a single string in SQL Server
Following code is working fine, to delete All the table in a Schema
SELECT * INTO #mytemp FROM INFORMATION_SCHEMA.SCHEMATA
WHERE [SCHEMA_NAME] in ('schemaname1','schemaname2','schemaname3')
WHILE (SELECT Count(*) FROM #mytemp) > 0
BEGIN
DECLARE #SCHEMA_NAME varchar(100)
SELECT #SCHEMA_NAME = [SCHEMA_NAME] FROM #mytemp
DECLARE #SQL VARCHAR(MAX)
SET #SQL='';
--Step 1: Remove all CONSTRAINT
SELECT #SQL= COALESCE(#SQL,'') +'ALTER TABLE ' +'[' + s.name + '].[' + t.name + ']' +' DROP CONSTRAINT [' + f.name +']'+ ' ; '
FROM sys.foreign_keys f
INNER JOIN sys.TABLES t ON f.parent_object_id=t.object_id
INNER JOIN sys.schemas s ON t.schema_id=s.schema_id
WHERE t.is_ms_shipped=0
and t.schema_id = schema_id(#SCHEMA_NAME);
--Step 2: Drop all Tables
SELECT #SQL= COALESCE(#SQL,'')+'DROP TABLE ' + '[' + s.name + '].[' + t.name + ']'+ ' ; '
FROM sys.TABLES t
INNER JOIN sys.schemas s ON t.schema_id=s.schema_id
WHERE t.is_ms_shipped=0 and t.schema_id = schema_id(#SCHEMA_NAME);
EXEC(#SQL)
--Custom Query End
DELETE #mytemp WHERE [SCHEMA_NAME] = #SCHEMA_NAME
END
DROP TABLE #mytemp
I have a problem with IF NOT EXISTS statement. I have used the following code inside of using a stored procedure:
IF NOT EXISTS(SELECT 1 FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'tableName'
AND COLUMN_NAME = #fieldName
AND TABLE_SCHEMA = 'dbo')
BEGIN
DECLARE #paramDefinitions NVARCHAR(1000)
SET #paramDefinitions=
'#dataType nvarchar(100) OUTPUT'
SET #typeQuery = 'SELECT #dataType =
CASE
WHEN s.name = ''nvarchar'' THEN ''nvarchar('' + CAST(c.max_length AS varchar(4)) + '')''
WHEN s.name = ''varchar'' THEN ''varchar('' + CAST(c.max_length AS varchar(4)) + '')''
WHEN s.name = ''char'' THEN ''char('' + CAST(c.max_length AS varchar(4)) + '')''
WHEN s.name = ''nchar'' THEN ''nchar('' + CAST(c.max_length AS varchar(4)) + '')''
ELSE s.name
END
FROM sys.views t JOIN sys.columns c ON t.object_id = c.object_id
JOIN sys.types s ON c.user_type_id = s.user_type_id
WHERE t.name = ''tablename'' AND c.name =' + #tmpField
EXEC sp_executesql #typeQuery, #paramDefinitions, #dataType OUTPUT
SET #updateTable = 'Alter table dbo.tablename add ' + #field +' '+ #dataType
print #updateTable
EXEC sp_executesql #updateTable
END
If I now start the SP it tries to recreate the already existing columns, but it will also create any new column. If I change it to IF EXISTSit won't do anything.
If I run the select statement by itself I get a 1 as a result if the column exists and nothing if it doesn't. Where is my mistake? Is it not possible to use IF NOT EXISTS for this purpose?
If I want to check if a table contains some column, I use COLUMNPROPERTY:
IF COLUMNPROPERTY(object_id('[dbo].[TABLE]'), 'COLUMN_NAME', 'AllowsNull') is NULL
BEGIN
SELECT 'The column does not exists'
END
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