T-SQL Drop Constraint on Dynamically Selected Table - sql-server

I have a situation in which I know a constraint name but do not know the name of a table. I would like to write a script that finds and drops the constraint based on its name, regardless of the table on which it resides. My trouble is that this appears to work only on alter table statements, which assume you know the table name. I can find a constraint using this:
SELECT *
FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS
WHERE CONSTRAINT_NAME='constraint_name'
and would like to use the table info provided there to alter whatever table is in my results and drop the constraint.
Pseudo code of what I want:
alter table (select top 1* TABLE_NAME from
FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS
WHERE CONSTRAINT_NAME='constraint_name') drop constraint 'constraint_name'

declare #constraint varchar(255)
declare #tbalename varchar(255)
declare #tbalename=select table_name from INFORMATION_SCHEMA.TABLE_CONSTRAINTS
WHERE CONSTRAINT_NAME=#constraint
declare #sql nvarchar(max)
set #sql='ALTER TABLE '+#tbalename +'DROP CONSTRAINT '+ #constraint ;
exec(#SQL)

Related

Executing script for add primary keys to all tables returns error

I want to add Primary Key IDD to every 'Temp...' table in the schema. I'm trying to do it the following way:
DECLARE #addId VARCHAR(MAX) = '';
SELECT #addId = #addId + 'ALTER TABLE ['+ TABLE_NAME +'] ADD IDD int IDENTITY(1,1);ALTER TABLE ['+TABLE_NAME +'] ADD PRIMARY KEY (IDD);' FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME LIKE 'Temp%'
EXEC (#addId );
I'm returned with such error:
Multiple identity columns specified for table 'TempTable'. Only one identity column per table is allowed.
What is my wrongdoing?
EDIT: There is no Primary Key already defined in the tables.
try this
SELECT #addId = #addId +
ALTER TABLE ['+ TABLE_NAME +'] ADD IDD int PRIMARY KEY IDENTITY(1,1);
FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME LIKE 'Temp%'
Use this query to get all table which doesn't have primary key:
select * FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_NAME NOT IN(SELECT TABLE_NAME
FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS
WHERE CONSTRAINT_TYPE='PRIMARY KEY')
And modify your dynamic query accordingly.

How can I delete or alter a default constraint from table in SQL Server database for multiple database?

I have gone thorough these previous questions Q1, Q2, Q3. Using this I can catch my exact constraint name. But it is not enough for me.
For example I have done somthing
ALTER TABLE dbo.Documents ADD ShowOnHandset BIT NOT NULL DEFAULT 'FALSE'
Here automatically my constrant named by the machine was DF__Documents__ShowO__7AB2122C on my machine. But I have run the same script in multiple PC, on those PC those constraint are almost same except the last hashed value. DF__Documents__ShowO__54A20B0D DF__Documents__ShowO__5D5216D7
I have seen that the last 8 bit hashed value is not similar. But I need to remove this constraint from all table and I want to replace them with
ALTER TABLE dbo.Documents ADD ShowOnHandset BIT NOT NULL DEFAULT ((1))
But I can't identify the the exact constraint name, so how can I drop it using a single script?
I have found hard-coded solution by those mentioned questions. But I need a single script to do it. Please help me to solve this.
I can catch the constraint name using this code
select name from sys.objects where name like 'DF__Documents__ShowO%'
I know the way how to delete it. Here it is.
ALTER TABLE dbo.AppSystems DROP constraint [constraint_name]
But I am unable to do it. Because I couldn't put the value constraint_name even if I can caught it. So how could I put this name here to drop it.
Update Modified the Question.
Run this and output as text, then copy the result and run in another query window
Fritz with the code below to ADD the updated constraint:
;With cte As (select object_id From sys.objects where name like 'DF__Documents__ShowO%')
Select 'Alter Table ' + Object_Name(df.object_id) + N' Add Constraint Default (1) For ShowOnHandset'
From sys.default_constraints As df
Join cte As c
On c.object_id = df.object_id
This deletes the constraints
;With cte As (select object_id From sys.objects where name like 'DF__Documents__ShowO%')
Select 'Alter Table ' + Object_Name(df.object_id) + N' Drop Constraint [' + df.Name + ']'
From sys.default_constraints As df
Join cte As c
On c.object_id = df.object_id
In MS SQL you can specify constraint name explicit:
ALTER TABLE dbo.Documents ADD ShowOnHandset BIT NOT NULL CONSTRAINT DF_Documents_ShowOnHandset DEFAULT 'FALSE'
Try dynamic query:
Declare #MyVariable varchar(max)
Declare #Variable varchar(max)
Set #MyVariable=(Select name from sys.objects
where parent_object_id=Object_ID('Documents','U') and name like 'DF__Documents__Show%')
Set #variable='ALTER TABLE dbo.AppSystems DROP constraint' +#MyVariable
Exec(#variable)

Truncate Table With Foreign Key

I have one database having above 1000+ tables. I am creating fresh Blank setup. For that i have to truncate all the tables but some of the tables i do not wish to truncate so i created on table and stored the names in the table.
----------- Create hardcode table ----------------------
Create table TblHardCodeTableNotToTruncate(TableName varchar(100))
go
insert into TblHardCodeTableNotToTruncate
select 'TblHardCodeTableNotToTruncate'
go
---- insert the table names which dont wish to truncate ------------
Insert into TblHardCodeTableNotToTruncate
select 'TblAccount'
go
Insert into TblHardCodeTableNotToTruncate
select 'TblCity'
go
etc, Following is the query i used to truncate all the tables except these inserted tables
------------------------- Truncate all the tables except the tables specified in the Hardcode table -------------------------
EXEC sp_MSForEachTable 'ALTER TABLE ? NOCHECK CONSTRAINT ALL'
GO
EXEC sp_MSForEachTable 'ALTER TABLE ? DISABLE TRIGGER ALL'
GO
DECLARE #TBLTEMP TABLE(TABLENAME VARCHAR(100))
insert into #TBLTEMP
select name from sysobjects where xtype = 'U'
delete from #TBLTEMP where tablename in (
select tablename from TblHardCodeTableNotToTruncate)
DECLARE #SQLQUERY VARCHAR(MAX) =''
DECLARE #INTCNT INT = 1
DECLARE #TABLENAME VARCHAR(100) =''
WHILE (SELECT COUNT(*) FROM #TBLTEMP) > 0
BEGIN
select top 1 #TABLENAME = TABLENAME from #TBLTEMP
SET #SQLQUERY = 'Truncate table ' + #TABLENAME
EXEC(#SQLQUERY)
PRINT #SQLQUERY
DELETE FROM #TBLTEMP WHERE TABLENAME = #TABLENAME
END
go
EXEC sp_MSForEachTable 'ALTER TABLE ? CHECK CONSTRAINT ALL'
GO
EXEC sp_MSForEachTable 'ALTER TABLE ? ENABLE TRIGGER ALL'
go
But i get the error foreign key reference error. I know i need to drop constraint before doing it. But is there any way to do it as i cannot drop then truncate and again add each time with so many tables. Is there any unique script can we write in below which will drop constraint if exists,truncate table and add the dropped constraint again to the table again.
I'm afraid that there is no way to do that without dropping constraints,
you can write a code that extracts the constraints for the tables and drop them it's simple.
Create a temporary table and use this code to get the tables constraint and notice that the sysconstraints.status must be 1 or 3 to get foreign and primary keys:
Select SysObjects.[Name] As "Constraint Name",
Tabls.[Name] as "Table Name",
Cols.[Name] As "Column Name"
From SysObjects Inner Join
(Select [Name],[ID] From SysObjects) As Tabls
On Tabls.[ID] = Sysobjects.[Parent_Obj]
Inner Join sysconstraints On sysconstraints.Constid = Sysobjects.[ID]
Inner Join SysColumns Cols On Cols.[ColID] = sysconstraints.[ColID]
And Cols.[ID] = Tabls.[ID]
where sysconstraints.status in (1, 3)
order by [Tabls].[Name]
you gonna have to recreate these constraints again after truncate, that's simple too, but I'm not gonna do all your job :)
Even if all tabled are empty and you disable all constraints the truncate ill fail due to the mere FK existence. You really must drop it.
You can create a script to automate it (truncate all tables dropping and recreating FKs)
I found one here (use with discretion)
http://www.sqlservercentral.com/scripts/Development/62892/
Also if you just want to create a "blanket" DB you can export the script to create all objects and just populate that few (domain?) tables do you need.

How can I alter a smalldatetime column with a default to be datetime?

I have a number of columns in my database that were originally created as smalldatetime and that really need to be datetime. Many of these columns were created with the DDL:
[columnname] smalldatetime not null default getdate()
...which means that in order to alter the column's type, I first have to drop the default, and then re-create the default after altering it.
Of course, I didn't specify a name for the default in the DDL, so the columns all have defaults with names like DF__CaseLock__CaseCo__182C9B23. And when my application creates its database, it does so by executing a script, so the names of the defaults in my customers' databases are (I'm guessing; I haven't verified this) different from their names in mine.
And even if I know the name of the default constraint, I can't figure out the syntax for adding it back in after I drop it. In fact, it's not clear to me that it's possible to add a default constraint to an existing column.
It appears that what I have to do is something like this:
declare #t table (id int not null primary key, date smalldatetime null)
insert into #t (id, date)
select id, date_column from my_table
drop constraint constraint_name
alter table my_table drop column date_column;
alter table my_table add date_column datetime default getdate()
update my_table set date_column = t.date FROM my_table m JOIN #t t ON m.id = t.ID
...only I can only write that script if I know what constraint_name is, because I can't drop a column that's referenced in a constraint.
Is this really that hard?
You can add a default constraint like this:
ALTER TABLE TableName
ADD CONSTRAINT DF_DefaultName DEFAULT 'Default Value' FOR ColumnName
You can interrogate the sys tables to find the existing constraints. When you add them back in, you should provide an explicit name for them. Here's a blog post that has a number of scripts for dealing with dropping/adding unnamed constraints. Hope that helps!
I'm afraid you have to resort to dynamic SQL.
Bear in mind though that any data that was previously set by the old default will remain.
DECLARE #query varchar(256)
SET #query = (
SELECT 'ALTER TABLE my_table DROP CONSTRAINT ' + d.name
FROM sysobjects d
INNER JOIN sysobjects t ON t.id = d.parent_obj
WHERE d.type = 'D'
AND t.name = 'my_table')
EXEC(#query)
ALTER TABLE my_table
ADD CONSTRAINT DF_date_column default getdate() for date_column
EDIT: Where multiple default columns exist in my_table:
CREATE TABLE #Defaults (
strName varchar(256) PRIMARY KEY
)
INSERT INTO #Defaults (strName)
SELECT d.name
FROM sysobjects d
INNER JOIN sysobjects t ON t.id = d.parent_obj
WHERE d.type = 'D'
AND t.name = 'my_table'
DECLARE #name varchar(256), #query varchar(256)
SET #name = (SELECT TOP 1 strName FROM #Defaults)
WHILE #name IS NOT NULL
BEGIN
SET #query = 'ALTER TABLE my_table DROP CONSTRAINT ' + #name
EXEC(#query)
DELETE FROM #Defaults
WHERE strName = #name
SET #name = (SELECT TOP 1 strName FROM #Defaults)
END
ALTER TABLE my_table
ADD CONSTRAINT DF_date_column1 default getdate() for date_column1
ALTER TABLE my_table
ADD CONSTRAINT DF_date_column2 default getdate() for date_column2
DROP TABLE #Defaults

Drop foreign key without knowing the name of the constraint?

I have created one table using the below command:
create table Table1(
Id int Not Null
Foreign key
references Table2(Id)
on delete cascade
on update cascade,
UserName nvarchar(150),
TimeInSeconds int Not Null
primary key(Id,TimeInSeconds)
);
But now I want to drop the foreign key.
As I haven't given a constraint name, I can't use:
Alter table <tablename>
drop foreign key <foreign key name>
Is there any way?
You can find the name of the constraint in INFORMATION_SCHEMA.TABLE_CONSTRAINTS
select CONSTRAINT_NAME
from INFORMATION_SCHEMA.TABLE_CONSTRAINTS
where TABLE_NAME = 'Table1'
Similar to Ed's Answer but you can use this to select the key name based on the table and column name.
That way you can run it in a script or maybe as a subquery to drop the constraint.
SELECT CONSTRAINT_NAME
FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE
WHERE TABLE_NAME = 'post'
AND COLUMN_NAME = 'userID'
Expanding on the answers since I ran into some gotchas. Also, I had 2 foreign keys declared, so I added an optional key to keep, if it's null it'll just be ignored:
declare #name varchar(255),
#table varchar(255) = 'mytable',
#column varchar(255) = 'mykeycolumn',
#validkey varchar(255) = 'mykeyIwanttokeep'
SELECT #name = CONSTRAINT_NAME
FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE
WHERE TABLE_NAME = #table
AND COLUMN_NAME = #column
AND (CONSTRAINT_NAME != #validkey or #validkey is null)
declare #sql varchar(1023) = 'alter table ' + #table + ' drop ' + #name
exec (#sql)
A SQL Server option:
DECLARE #foreignkey varchar(100)
DECLARE #tablename varchar(100)
DECLARE #command nvarchar(1000)
DECLARE db_cursor CURSOR FOR
SELECT fk.name, t.name
FROM sys.foreign_keys fk
JOIN sys.tables t ON t.object_id = fk.parent_object_id
WHERE t.name IN (
'table_1_name_here',
'table_2_name_here'
)
OPEN db_cursor
FETCH NEXT FROM db_cursor INTO #foreignkey, #tablename
WHILE ##FETCH_STATUS = 0
BEGIN
SELECT #command = 'ALTER TABLE ' + #tablename + ' DROP CONSTRAINT ' + #foreignkey
EXECUTE(#command)
FETCH NEXT FROM db_cursor INTO #foreignkey, #tablename
END
CLOSE db_cursor
DEALLOCATE db_cursor
The SQL selects all the constraints for the tables you care about into a cursor and drops them one by one. All you need to know are the names of the tables you want them dropped from.
To drop a foreign key use the following commands :
SHOW CREATE TABLE table_name;
ALTER TABLE table_name DROP FOREIGN KEY table_name_ibfk_3;
("table_name_ibfk_3" is constraint foreign key name assigned for unnamed constraints). It varies.
ALTER TABLE table_name DROP column_name.
If you just look at the table in enterprise manager / management studio you will be able to see the list of keys and delete it from there.
Never mind, below is Postgres syntax. It would be better if the question had sql server in the title as I didn't notice the tag
You could also drop and re-add the primary key on the parent table using cascade. This will remove any foreign keys that reference that table without you needing to know the foreign key names.
ALTER TABLE parent_table
DROP CONSTRAINT 'pk_id' CASCADE
-- add back pk
ALTER TABLE parent_table
ADD CONSTRAINT 'pk_id' PRIMARY KEY (id)
WARNING: you'd want to check all the dependencies first and if there are other tables, you'd need to add back their foreign keys. That does allow you to name the foreign keys properly when you add them back. This approach also may not be viable in a high transaction system due to the blocking transaction.
you can put:
> show create table tablename;
you will see how was created the table...columns, types...etc. and you could see your constraint name.

Resources