Drop constraint names received from different query - sql

I'm trying to drop a few constraints which have been automatically generated when I add the default value somewhere.
I use the following script to return me the names of the constraints:
SELECT default_constraints.name 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 tables.name = 'TrainingType'
AND default_constraints.name like 'DF__TrainingT__Soft__%'
OR default_constraints.name like 'DF__TrainingT__EndUs__%'
OR default_constraints.name like 'DF__TrainingC__Compu__%'
This returns me the following:
| name
---------------------------------
1 | DF__TrainingC__Compu__2058C9F1
2 | DF__TrainingT__EndUs__1559B68C
3 | DF__TrainingT__Softw__05CD5A39
Now I'm trying to drop the constraints with these values, but it doesn't allow me to do DROP CONSTRAINT ( ... )
ALTER TABLE TrainingType
DROP CONSTRAINT (
SELECT default_constraints.name 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 tables.name = 'TrainingType'
AND default_constraints.name like 'DF__TrainingT__Soft__%'
OR default_constraints.name like 'DF__TrainingT__EndUs__%'
OR default_constraints.name like 'DF__TrainingC__Compu__%'
)
So how can I drop the constraints correctly?

Dynamic Sql using the select ... for xml path ('') method of string concatenation to concatenate the commands into one variable to execute with sp_executesql:
declare #sql nvarchar(max);
select #sql = (
select
'alter table '+quotename(schema_name(dc.schema_id))
+'.'+quotename(object_name(dc.parent_object_id))
+' drop constraint '+quotename(name)+';'+char(10)
from sys.default_constraints as dc
where parent_object_id = object_id(N'TrainingType')
and dc.name like 'DF__TrainingT__Soft__%'
or dc.name like 'DF__TrainingT__EndUs__%'
or dc.name like 'DF__TrainingC__Compu__%'
for xml path (''), type).value('.','nvarchar(max)')
set #sql = 'use '+quotename(db_name())+';'+char(10)+#sql;
select #sql
exec sp_executesql #sql;
This is a good primer on dynamic sql:
The curse and blessings of dynamic SQL - Erland Sommarskog
rextester demo: http://rextester.com/HSV25230
Generated code from the demo:
use [rextester];
alter table [dbo].[Pilots] drop constraint [DF__Pilots__df__173EF6DF];
alter table [dbo].[Pilots] drop constraint [DF__Pilots__other_df__18331B18];

Maybe it'll work once you add the ID as column and name as a second column.
This should be the proper syntax:
ALTER TABLE "table_name"
DROP [CONSTRAINT|INDEX] "CONSTRAINT_NAME";

You can't inject dynamic qualifiers into a drop clause like that. They have to be issued one at a time. A similar method would be to generate a script to run as individual sql commands.
SELECT
'ALTER TABLE TrainingType DROP CONSTRAINT ( '
+ default_constraints.name +')'
+ CHAR(10)+CHAR(13)+ GO '
FROM sys.all_columns
INNER JOIN sys.tables ON all_columns.object_id = tables.object_id
....
You now have one statement per drop command that you can apply against your database.

Related

How to drop foreign keys of a particular column

I have created a foreign key without specifying the name so sql server has created it with auto generated name. Now I want to drop the column which has this foreign key. The problem is that i don't know the name of this foreign key. Is there any way to drop all the foreign keys for particular column in particular table?
So far I've found this script which drops all default constraints for column
DECLARE #tableName VARCHAR(MAX)
DECLARE #ConstraintName nvarchar(200)
DECLARE #columnName VARCHAR(MAX)
SET #tableName = 'tablename'
SET #columnName = 'columnname'
SELECT #ConstraintName = Name
FROM SYS.DEFAULT_CONSTRAINTS
WHERE PARENT_OBJECT_ID = OBJECT_ID(#tableName)
AND PARENT_COLUMN_ID = (
SELECT column_id FROM sys.columns
WHERE NAME = #columnName AND object_id = OBJECT_ID(#tableName))
IF #ConstraintName IS NOT NULL
BEGIN
EXEC('ALTER TABLE '+#tableName+' DROP CONSTRAINT ' + #ConstraintName)
END
ALTER TABLE [tablename] DROP COLUMN columnname
GO
But it doesn't help with foreign key constraints.
If you want to get more information about FK and specifically about a particular scheme and table than you can use.
SELECT
t.Name as TableName,
c.name as ColumnName,
fk.name as FK_NAME
FROM sys.foreign_keys as fk
inner join sys.tables as t on fk.parent_object_id = t.object_id
inner join sys.columns as c on c.object_id = t.object_id
inner join sys.schemas as sc on t.schema_id = sc.schema_id
WHERE sc.name = 'Schema' and t.name = 'Table' and c.name = 'Column'
If you are interested only about certain column then u can use Ross Presser answer.
Also if you want to drop all fk constraint you can execute this:
Declare #sql nvarchar(4000)
SET #sql = N'';
SELECT #sql = #sql + '
ALTER TABLE [' + sc.NAME + '].[' + OBJECT_NAME(fk.parent_object_id) + ']' + ' DROP CONSTRAINT ' + '[' + fk.NAME + ']
'
FROM sys.foreign_keys as fk
inner join sys.tables as t on fk.parent_object_id = t.object_id
inner join sys.columns as c on c.object_id = t.object_id
inner join sys.schemas as sc on t.schema_id = sc.schema_id
WHERE sc.name = 'schemaName' and c.name = 'columnName' -- you can include and fk name
ORDER BY fk.NAME
PRINT #sql;
--EXEC sys.sp_executesql #sql;
You can get all the constraint list along with the names assigned to particular tables with the help of the below query:
SELECT * FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS
WHERE TABLE_NAME='YourTableName';
Once you find the constraint you want to delete you can do it with the help of below query:
ALTER TABLE Orders
DROP CONSTRAINT constraint_name;
You can find all constraints throughout the database that use the column:
SELECT * FROM INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE CCU
WHERE CCU.COLUMN_NAME='someColumn'
The output gives the constraint name and the table it is attached to.
Here's an example to find foreign keys using the system views (which aren't amazingly well documented):
select fk.name as ForeignKeyName
, t_parent.name as ParentTableName
, c_parent.name as ParentColumnName
, t_child.name as ReferencedTableName
, c_child.name as ReferencedColumnName
from sys.foreign_keys fk
inner join sys.foreign_key_columns fkc on fkc.constraint_object_id = fk.object_id
inner join sys.tables t_parent on t_parent.object_id = fk.parent_object_id
inner join sys.columns c_parent on fkc.parent_column_id = c_parent.column_id
and c_parent.object_id = t_parent.object_id
inner join sys.tables t_child on t_child.object_id = fk.referenced_object_id
inner join sys.columns c_child on c_child.object_id = t_child.object_id
and fkc.referenced_column_id = c_child.column_id
order by t_parent.name, c_parent.name

Drop default constraint in SQL Server on many columns

For SQL Server 2008 R2 I want to remove default constraints for date columns that allow null and the constraint contains 1899. And I want a script that can tested and then executed in live. I don't wan't to fiddle with this in live environment. Another reason for a script is that there is several databases with the same scheme
With help from Google I have the following script that list columns
SELECT tables.name, all_columns.name, all_columns.is_nullable, default_constraints.name, default_constraints.definition
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
schemas.name = 'dbo'
and default_constraints.definition like '%1899%'
and all_columns.is_nullable = 1
order by tables.name, all_columns.name, default_constraints.name
Now this list over hundred columns. The next script do what I want for the column CargoPool.Created. But how can I iterate all rows created from my first script ?
DECLARE #tableName VARCHAR(MAX) = 'CargoPool'
DECLARE #columnName VARCHAR(MAX) = 'Created'
DECLARE #ConstraintName nvarchar(200)
SELECT #ConstraintName = Name
FROM SYS.DEFAULT_CONSTRAINTS
WHERE PARENT_OBJECT_ID = OBJECT_ID(#tableName)
AND PARENT_COLUMN_ID = (
SELECT column_id FROM sys.columns
WHERE NAME = #columnName AND object_id = OBJECT_ID(#tableName))
IF #ConstraintName IS NOT NULL
EXEC('ALTER TABLE '+#tableName+' DROP CONSTRAINT ' + #ConstraintName)
If you want to drop all the constraints from your first query, you can build up a dynamic SQL with the results of that query and then execute it:
DECLARE #sql AS NVARCHAR(MAX) = N''
SELECT #sql = #sql + N'ALTER TABLE '
+ QUOTENAME(schemas.name) + N'.' + QUOTENAME(tables.name)
+ N' DROP CONSTRAINT ' + QUOTENAME(default_constraints.name) + N'; '
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
schemas.name = N'dbo'
and default_constraints.definition like N'%1899%'
and all_columns.is_nullable = 1
order by tables.name, all_columns.name, default_constraints.name
exec sp_executesql #sql;

How to drop a Unique Constraint set on a single column

I have created a table below,
"CREATE TABLE UNIQ(NUM INT UNIQUE, NAMES VARCHAR(10))"
Now i want to drop/disable the UNIQUE constraint set on NUM column.
How to do this with Query..?
I googled and got to know that, if i am giving constraint name while creating table, then using that name i can easily drop the contraint.
EX:
CREATE TABLE UNIQ(NUM INT CONSTRAINT CONTR_NAME UNIQUE, NAMES VARCHAR(10))
For dropping constraint.,
ALTER TABLE UNIQ DROP CONSTRAINT CONTR_NAME
Thanks in advance.. :)
Thanks
Mahesh
ALTER TABLE UNIQ
DROP CONSTRAINT [name of constraint]
The below query should help you find the name of the constraint
SELECT
o.name AS ConstraintName,
c.name AS ColumnName
FROM sys.objects o
JOIN sys.objects p
ON o.parent_object_id = p.object_id
JOIN sys.columns c
ON c.object_id = p.object_id
WHERE o.type_desc LIKE '%CONSTRAINT'
AND p.Name = 'UNIQ'
Try this:
DECLARE #ConstraintName VARCHAR(256)
SET #ConstraintName = (
SELECT obj.name
FROM sys.columns col
LEFT OUTER JOIN sys.objects obj
ON obj.object_id = col.default_object_id
AND obj.type = 'UQ'
WHERE col.object_id = OBJECT_ID('TableName')
AND obj.name IS NOT NULL
AND col.name = 'ColunmName'
)
IF(#ConstraintName IS NOT NULL)
BEGIN
EXEC ('ALTER TABLE [TableName] DROP CONSTRAINT ['+#ConstraintName+']')
END

Search text in stored procedure in SQL Server

I want to search a text from all my database stored procedures. I use the below SQL:
SELECT DISTINCT
o.name AS Object_Name,
o.type_desc
FROM sys.sql_modules m
INNER JOIN
sys.objects o
ON m.object_id = o.object_id
WHERE m.definition Like '%[ABD]%';
I want to search for [ABD] in all stored procedures including square brackets, but it's not giving the proper result. How can I change my query to achieve this?
Escape the square brackets:
...
WHERE m.definition Like '%\[ABD\]%' ESCAPE '\'
Then the square brackets will be treated as a string literals not as wild cards.
Try this request:
Query
SELECT name
FROM sys.procedures
WHERE Object_definition(object_id) LIKE '%strHell%'
Have you tried using some of the third party tools to do the search? There are several available out there that are free and that saved me a ton of time in the past.
Below are two SSMS Addins I used with good success.
ApexSQL Search – Searches both schema and data in databases and has additional features such as dependency tracking and more…
SSMS Tools pack – Has same search functionality as previous one and several other cool features. Not free for SQL Server 2012 but still very affordable.
I know this answer is not 100% related to the questions (which was more specific) but hopefully others will find this useful.
I usually run the following to achieve that:
select distinct object_name(id)
from syscomments
where text like '%[ABD]%'
order by object_name(id)
Good practice to work with SQL Server.
Create below stored procedure and set short key,
CREATE PROCEDURE [dbo].[Searchinall]
(#strFind AS VARCHAR(MAX))
AS
BEGIN
SET NOCOUNT ON;
--TO FIND STRING IN ALL PROCEDURES
BEGIN
SELECT OBJECT_NAME(OBJECT_ID) SP_Name
,OBJECT_DEFINITION(OBJECT_ID) SP_Definition
FROM sys.procedures
WHERE OBJECT_DEFINITION(OBJECT_ID) LIKE '%'+#strFind+'%'
END
--TO FIND STRING IN ALL VIEWS
BEGIN
SELECT OBJECT_NAME(OBJECT_ID) View_Name
,OBJECT_DEFINITION(OBJECT_ID) View_Definition
FROM sys.views
WHERE OBJECT_DEFINITION(OBJECT_ID) LIKE '%'+#strFind+'%'
END
--TO FIND STRING IN ALL FUNCTION
BEGIN
SELECT ROUTINE_NAME Function_Name
,ROUTINE_DEFINITION Function_definition
FROM INFORMATION_SCHEMA.ROUTINES
WHERE ROUTINE_DEFINITION LIKE '%'+#strFind+'%'
AND ROUTINE_TYPE = 'FUNCTION'
ORDER BY
ROUTINE_NAME
END
--TO FIND STRING IN ALL TABLES OF DATABASE.
BEGIN
SELECT t.name AS Table_Name
,c.name AS COLUMN_NAME
FROM sys.tables AS t
INNER JOIN sys.columns c
ON t.OBJECT_ID = c.OBJECT_ID
WHERE c.name LIKE '%'+#strFind+'%'
ORDER BY
Table_Name
END
END
Now - Set short key as below,
So next time whenever you want to find a particular text in any of the four objects like Store procedure, Views, Functions and Tables. You just need to write that keyword and press shortcut key.
For example: I want to search 'PaymentTable' then write 'PaymentTable' and make sure you select or highlight the written keyword in query editor and press shortcut key ctrl+4 - it will provide you full result.
Redgate's SQL Search is a great tool for doing this, it's a free plugin for SSMS.
Please take this as a "dirty" alternative but this saved my behind many times especially when I was not familiar with the DB project. Sometimes you are trying to search for a string within all SPs and forget that some of the related logic may have been hiding between Functions and Triggers or it can be simply worded differently than you thought.
From your MSSMS you may right click your DB and select
Tasks -> Generate Scripts wizard to output all the SPs, Fns and Triggers into a single .sql file.
Make sure to select Triggers too!
Then just use Sublime or Notepad to search for the string you need to find. I know this may be quite inefficient and paranoid approach but it works :)
You can also use this one:
SELECT *
FROM INFORMATION_SCHEMA.ROUTINES
WHERE ROUTINE_DEFINITION like '%Search_String%'
select top 10 * from
sys.procedures
where object_definition(object_id) like '%\[ABD\]%'
It might help you!
SELECT DISTINCT
A.NAME AS OBJECT_NAME,
A.TYPE_DESC
FROM SYS.SQL_MODULES M
INNER JOIN SYS.OBJECTS A ON M.OBJECT_ID = A.OBJECT_ID
WHERE M.DEFINITION LIKE '%['+#SEARCH_TEXT+']%'
ORDER BY TYPE_DESC
Also you can use:
SELECT OBJECT_NAME(id)
FROM syscomments
WHERE [text] LIKE '%flags.%'
AND OBJECTPROPERTY(id, 'IsProcedure') = 1
GROUP BY OBJECT_NAME(id)
Thats include comments
SELECT DISTINCT
o.name AS Object_Name,
o.type_desc
FROM sys.sql_modules m INNER JOIN sys.objects o
ON m.object_id = o.object_id WHERE m.definition Like '%[String]%';
SELECT DISTINCT OBJECT_NAME([id]),[text]
FROM syscomments
WHERE [id] IN (SELECT [id] FROM sysobjects WHERE xtype IN
('TF','FN','V','P') AND status >= 0) AND
([text] LIKE '%text to be search%' )
OBJECT_NAME([id]) --> Object Name (View,Store Procedure,Scalar Function,Table function name)
id (int) = Object identification number
xtype char(2) Object type. Can be one of the following object types:
FN = Scalar function
P = Stored procedure
V = View
TF = Table function
SELECT name , type_desc , create_date , modify_date
FROM sys.procedures
WHERE Object_definition(object_id) LIKE '%High%'
I created a procedure to search text in procedures/functions, tables, views, or jobs. The first parameter #search is the search criterion, #target the search target, i.e., procedures, tables, etc. If not specified, search all. #db is to specify the database to search, default to your current database. Here is my query in dynamic SQL.
ALTER PROCEDURE [dbo].[usp_find_objects]
(
#search VARCHAR(255),
#target VARCHAR(255) = NULL,
#db VARCHAR(35) = NULL
)
AS
SET NOCOUNT ON;
DECLARE #TSQL NVARCHAR(MAX), #USEDB NVARCHAR(50)
IF #db <> '' SET #USEDB = 'USE ' + #db
ELSE SET #USEDB = ''
IF #target IS NULL SET #target = ''
SET #TSQL = #USEDB + '
DECLARE #search VARCHAR(128)
DECLARE #target VARCHAR(128)
SET #search = ''%' + #search + '%''
SET #target = ''' + #target + '''
IF #target LIKE ''%Procedure%'' BEGIN
SELECT o.name As ''Stored Procedures''
FROM SYSOBJECTS o
INNER JOIN SYSCOMMENTS c ON o.id = c.id
WHERE c.text LIKE #search
AND o.xtype IN (''P'',''FN'')
GROUP BY o.name
ORDER BY o.name
END
ELSE IF #target LIKE ''%View%'' BEGIN
SELECT o.name As ''Views''
FROM SYSOBJECTS o
INNER JOIN SYSCOMMENTS c ON o.id = c.id
WHERE c.text LIKE #search
AND o.xtype = ''V''
GROUP BY o.name
ORDER BY o.name
END
/* Table - search table name only, need to add column name */
ELSE IF #target LIKE ''%Table%'' BEGIN
SELECT t.name AS ''TableName''
FROM sys.columns c
JOIN sys.tables t ON c.object_id = t.object_id
WHERE c.name LIKE #search
ORDER BY TableName
END
ELSE IF #target LIKE ''%Job%'' BEGIN
SELECT j.job_id,
s.srvname,
j.name,
js.step_id,
js.command,
j.enabled
FROM [msdb].dbo.sysjobs j
JOIN [msdb].dbo.sysjobsteps js
ON js.job_id = j.job_id
JOIN master.dbo.sysservers s
ON s.srvid = j.originating_server_id
WHERE js.command LIKE #search
END
ELSE BEGIN
SELECT o.name As ''Stored Procedures''
FROM SYSOBJECTS o
INNER JOIN SYSCOMMENTS c ON o.id = c.id
WHERE c.text LIKE #search
AND o.xtype IN (''P'',''FN'')
GROUP BY o.name
ORDER BY o.name
SELECT o.name As ''Views''
FROM SYSOBJECTS o
INNER JOIN SYSCOMMENTS c ON o.id = c.id
WHERE c.text LIKE #search
AND o.xtype = ''V''
GROUP BY o.name
ORDER BY o.name
SELECT t.name AS ''Tables''
FROM sys.columns c
JOIN sys.tables t ON c.object_id = t.object_id
WHERE c.name LIKE #search
ORDER BY Tables
SELECT j.name AS ''Jobs''
FROM [msdb].dbo.sysjobs j
JOIN [msdb].dbo.sysjobsteps js
ON js.job_id = j.job_id
JOIN master.dbo.sysservers s
ON s.srvid = j.originating_server_id
WHERE js.command LIKE #search
END
'
EXECUTE sp_executesql #TSQL
Update:
If you renamed a procedure, it only updates sysobjects but not syscomments, which keeps the old name and therefore that procedure will not be included in the search result unless you drop and recreate the procedure.
also try this :
SELECT ROUTINE_NAME
FROM INFORMATION_SCHEMA.ROUTINES
WHERE ROUTINE_DEFINITION like '%\[ABD\]%'
A different version, To make query more appropriate for different coding practices.
SELECT DISTINCT
O.NAME AS OBJECT_NAME,
O.TYPE_DESC
FROM SYS.SQL_MODULES M
INNER JOIN
SYS.OBJECTS O
ON M.OBJECT_ID = O.OBJECT_ID
WHERE UPPER(M.DEFINITION) LIKE UPPER('%Your Text%');
Using CHARINDEX:
SELECT DISTINCT o.name AS Object_Name,o.type_desc
FROM sys.sql_modules m
INNER JOIN sys.objects o
ON m.object_id=o.object_id
WHERE CHARINDEX('[ABD]',m.definition) >0 ;
Using PATINDEX:
SELECT DISTINCT o.name AS Object_Name,o.type_desc
FROM sys.sql_modules m
INNER JOIN sys.objects o
ON m.object_id=o.object_id
WHERE PATINDEX('[[]ABD]',m.definition) >0 ;
Using this double [[]ABD] is similar to escaping :
WHERE m.definition LIKE '%[[]ABD]%'
This query is search text in stored procedure from all databases.
DECLARE #T_Find_Text VARCHAR(1000) = 'Foo'
IF OBJECT_ID('tempdb..#T_DBNAME') IS NOT NULL DROP TABLE #T_DBNAME
IF OBJECT_ID('tempdb..#T_PROCEDURE') IS NOT NULL DROP TABLE #T_PROCEDURE
CREATE TABLE #T_DBNAME
(
IDX int IDENTITY(1,1) PRIMARY KEY
, DBName VARCHAR(255)
)
CREATE TABLE #T_PROCEDURE
(
IDX int IDENTITY(1,1) PRIMARY KEY
, DBName VARCHAR(255)
, Procedure_Name VARCHAR(MAX)
, Procedure_Description VARCHAR(MAX)
)
INSERT INTO #T_DBNAME (DBName)
SELECT name FROM master.dbo.sysdatabases
DECLARE #T_C_IDX INT = 0
DECLARE #T_C_DBName VARCHAR(255)
DECLARE #T_SQL NVARCHAR(MAX)
DECLARE #T_SQL_PARAM NVARCHAR(MAX)
SET #T_SQL_PARAM =
' #T_C_DBName VARCHAR(255)
, #T_Find_Text VARCHAR(255)
'
WHILE EXISTS(SELECT TOP 1 IDX FROM #T_DBNAME WHERE IDX > #T_C_IDX ORDER BY IDX ASC)
BEGIN
SELECT TOP 1
#T_C_DBName = DBName
FROM #T_DBNAME WHERE IDX > #T_C_IDX ORDER BY IDX ASC
SET #T_SQL = ''
SET #T_SQL = #T_SQL + 'INSERT INTO #T_PROCEDURE(DBName, Procedure_Name, Procedure_Description)'
SET #T_SQL = #T_SQL + 'SELECT SPECIFIC_CATALOG, ROUTINE_NAME, ROUTINE_DEFINITION '
SET #T_SQL = #T_SQL + 'FROM ' + #T_C_DBName + '.INFORMATION_SCHEMA.ROUTINES '
SET #T_SQL = #T_SQL + 'WHERE ROUTINE_DEFINITION LIKE ''%''+ #T_Find_Text + ''%'' '
SET #T_SQL = #T_SQL + 'AND ROUTINE_TYPE = ''PROCEDURE'' '
BEGIN TRY
EXEC SP_EXECUTESQL #T_SQL, #T_SQL_PARAM, #T_C_DBName, #T_Find_Text
END TRY
BEGIN CATCH
SELECT #T_C_DBName + ' ERROR'
END CATCH
SET #T_C_IDX = #T_C_IDX + 1
END
SELECT IDX, DBName, Procedure_Name FROM #T_PROCEDURE ORDER BY DBName ASC
Select distinct OBJECT_NAME(id) from syscomments where text like '%string%' AND OBJECTPROPERTY(id, 'IsProcedure') = 1
/*
SEARCH SPROCS & VIEWS
The following query will allow search within the definitions
of stored procedures and views.
It spits out the results as XML, with the full definitions,
so you can browse them without having to script them individually.
*/
/*
STEP 1: POPULATE SEARCH KEYS. (Set to NULL to ignore)
*/
DECLARE
#def_key varchar(128) = '%foo%', /* <<< definition search key */
#name_key varchar(128) = '%bar%', /* <<< name search key */
#schema_key varchar(128) = 'dbo'; /* <<< schema search key */
;WITH SearchResults AS (
/*
STEP 2: DEFINE SEARCH QUERY AS CTE (Common Table Expression)
*/
SELECT
[Object].object_id AS [object_id],
[Schema].name AS [schema_name],
[Object].name AS [object_name],
[Object].type AS [object_type],
[Object].type_desc AS [object_type_desc],
[Details].definition AS [module_definition]
FROM
/* sys.sql_modules = where the body of sprocs and views live */
sys.sql_modules AS [Details] WITH (NOLOCK)
JOIN
/* sys.objects = where the metadata for every object in the database lives */
sys.objects AS [Object] WITH (NOLOCK) ON [Details].object_id = [Object].object_id
JOIN
/* sys.schemas = where the schemas in the datatabase live */
sys.schemas AS [Schema] WITH (NOLOCK) ON [Object].schema_id = [Schema].schema_id
WHERE
(#def_key IS NULL OR [Details].definition LIKE #def_key) /* <<< searches definition */
AND (#name_key IS NULL OR [Object].name LIKE #name_key) /* <<< searches name */
AND (#schema_key IS NULL OR [Schema].name LIKE #schema_key) /* <<< searches schema */
)
/*
STEP 3: SELECT FROM CTE INTO XML
*/
/*
This outer select wraps the inner queries in to the <sql_object> root element
*/
SELECT
(
/*
This inner query maps stored procedure rows to <procedure> elements
*/
SELECT TOP 100 PERCENT
[object_id] AS [#object_id],
[schema_name] + '.' + [object_name] AS [#full_name],
[module_definition] AS [module_definition]
FROM
SearchResults
WHERE
object_type = 'P'
ORDER BY
[schema_name], [object_name]
FOR XML
PATH ('procedure'), TYPE
) AS [procedures], /* <<< as part of the outer query,
this alias causes the <procedure> elements
to be wrapped within the <procedures> element */
(
/*
This inner query maps view rows to <view> elements
*/
SELECT TOP 100 PERCENT
[object_id] AS [#object_id],
[schema_name] + '.' + [object_name] AS [#full_name],
[module_definition] AS [module_definition]
FROM
SearchResults
WHERE
object_type = 'V'
ORDER BY
[schema_name], [object_name]
FOR XML
PATH ('view'), TYPE
) AS [views] /* <<< as part of the outer query,
this alias causes the <view> elements
to be wrapped within the <views> element */
FOR XML
PATH ('sql_objects')
Every so often I use this script to figure out which procs to modify, or to figure out what uses a column of a table, or that table at all to remove some old junk. It checks each database on the instance it is ran on by the wonderfully supplied sp_msforeachdb.
if object_id('tempdb..##nothing') is not null
drop table ##nothing
CREATE TABLE ##nothing
(
DatabaseName varchar(30),
SchemaName varchar(30),
ObjectName varchar(100),
ObjectType varchar(50)
)
EXEC master.sys.sp_msforeachdb
'USE ?
insert into ##nothing
SELECT
db_name() AS [Database],
[Scehma]=schema_name(o.schema_id),
o.Name,
o.type
FROM sys.sql_modules m
INNER JOIN sys.objects o
ON o.object_id = m.object_id
WHERE
m.definition like ''%SOME_TEXT%'''
--edit this text
SELECT * FROM ##nothing n
order by OBJECTname
-- Applicable for SQL 2005+
USE YOUR_DATABASE_NAME //;
GO
SELECT [Scehma] = schema_name(o.schema_id)
,o.NAME
,o.type
FROM sys.sql_modules m
INNER JOIN sys.objects o ON o.object_id = m.object_id
WHERE m.DEFINITION LIKE '%YOUR SEARCH KEYWORDS%'
GO
This search routine is based on https://stackoverflow.com/a/33631029/2735286 and contains the schema name too in the search results:
CREATE PROCEDURE [dbo].[Searchinall] (#strFind AS VARCHAR(MAX))
AS
BEGIN
SET NOCOUNT ON;
--TO FIND STRING IN ALL PROCEDURES
BEGIN
SELECT s.name SP_Schema_Name, OBJECT_NAME(p.OBJECT_ID) SP_Name
,OBJECT_DEFINITION(p.OBJECT_ID) SP_Definition
FROM sys.procedures p
INNER JOIN sys.schemas s on p.schema_id = s.schema_id
WHERE OBJECT_DEFINITION(OBJECT_ID) LIKE '%'+#strFind+'%'
END
--TO FIND STRING IN ALL VIEWS
BEGIN
SELECT s.name SP_Schema_Name, OBJECT_NAME(OBJECT_ID) View_Name
,OBJECT_DEFINITION(OBJECT_ID) View_Definition
FROM sys.views v
INNER JOIN sys.schemas s on v.schema_id = s.schema_id
WHERE OBJECT_DEFINITION(OBJECT_ID) LIKE '%'+#strFind+'%'
END
--TO FIND STRING IN ALL FUNCTION
BEGIN
SELECT ROUTINE_SCHEMA, ROUTINE_NAME Function_Name
,ROUTINE_DEFINITION Function_definition
FROM INFORMATION_SCHEMA.ROUTINES
WHERE ROUTINE_DEFINITION LIKE '%'+#strFind+'%'
AND ROUTINE_TYPE = 'FUNCTION'
ORDER BY
ROUTINE_NAME
END
--TO FIND STRING IN ALL TABLES OF DATABASE.
BEGIN
SELECT s.name SP_Schema_Name, t.name AS Table_Name
,c.name AS COLUMN_NAME
FROM sys.tables AS t
INNER JOIN sys.columns c
ON t.OBJECT_ID = c.OBJECT_ID
INNER JOIN sys.schemas s on t.schema_id = s.schema_id
WHERE c.name LIKE '%'+#strFind+'%'
ORDER BY
Table_Name
END
END
Here is how you use it:
execute [dbo].[Searchinall] 'cust'
Here is an alternative which lists all objects with a specific keyword in one single query:
SELECT DISTINCT
s.name AS Schema_Name,
o.name AS Object_Name,
o.type_desc
FROM sys.sql_modules m
INNER JOIN
sys.objects o
ON m.object_id = o.object_id
INNER JOIN sys.schemas s on o.schema_id = s.schema_id
WHERE m.definition Like '%dim_forex%' ESCAPE '\' order by 3;
This query should return the same results and the procedure call in this answer.
You can also use
CREATE PROCEDURE [Search](
#Filter nvarchar(max)
)
AS
BEGIN
SELECT name
FROM procedures
WHERE definition LIKE '%'+#Filter+'%'
END
and then run
exec [Search] 'text'

How can I list all foreign keys referencing a given table in SQL Server?

I need to remove a highly referenced table in a SQL Server database. How can I get a list of all the foreign key constraints I will need to remove in order to drop the table?
(SQL answers preferable over clicking about in the GUI of the management studio.)
Not sure why no one suggested but I use sp_fkeys to query foreign keys for a given table:
EXEC sp_fkeys 'TableName'
You can also specify the schema:
EXEC sp_fkeys #pktable_name = 'TableName', #pktable_owner = 'dbo'
Without specifying the schema, the docs state the following:
If pktable_owner is not specified, the default table visibility rules
of the underlying DBMS apply.
In SQL Server, if the current user owns a table with the specified
name, that table's columns are returned. If pktable_owner is not
specified and the current user does not own a table with the specified
pktable_name, the procedure looks for a table with the specified
pktable_name owned by the database owner. If one exists, that table's
columns are returned.
This gives you:
The FK itself itself
Schema that the FK belongs to
The "referencing table" or the table that has the FK
The "referencing column" or the column inside referencing table that points to the FK
The "referenced table" or the table that has the key column that your FK is pointing to
The "referenced column" or the column that is the key that your FK is pointing to
Code below:
SELECT obj.name AS FK_NAME,
sch.name AS [schema_name],
tab1.name AS [table],
col1.name AS [column],
tab2.name AS [referenced_table],
col2.name AS [referenced_column]
FROM sys.foreign_key_columns fkc
INNER JOIN sys.objects obj
ON obj.object_id = fkc.constraint_object_id
INNER JOIN sys.tables tab1
ON tab1.object_id = fkc.parent_object_id
INNER JOIN sys.schemas sch
ON tab1.schema_id = sch.schema_id
INNER JOIN sys.columns col1
ON col1.column_id = parent_column_id AND col1.object_id = tab1.object_id
INNER JOIN sys.tables tab2
ON tab2.object_id = fkc.referenced_object_id
INNER JOIN sys.columns col2
ON col2.column_id = referenced_column_id AND col2.object_id = tab2.object_id
I'd use the Database Diagramming feature in SQL Server Management Studio, but since you ruled that out - this worked for me in SQL Server 2008 (don't have 2005).
To get list of referring table and column names...
select
t.name as TableWithForeignKey,
fk.constraint_column_id as FK_PartNo, c.
name as ForeignKeyColumn
from
sys.foreign_key_columns as fk
inner join
sys.tables as t on fk.parent_object_id = t.object_id
inner join
sys.columns as c on fk.parent_object_id = c.object_id and fk.parent_column_id = c.column_id
where
fk.referenced_object_id = (select object_id
from sys.tables
where name = 'TableOthersForeignKeyInto')
order by
TableWithForeignKey, FK_PartNo
To get names of foreign key constraints
select distinct name from sys.objects where object_id in
( select fk.constraint_object_id from sys.foreign_key_columns as fk
where fk.referenced_object_id =
(select object_id from sys.tables where name = 'TableOthersForeignKeyInto')
)
Try this :
sp_help 'TableName'
You should also mind the references to other objects.
If the table was highly referenced by other tables than it’s probably also highly referenced by other objects such as views, stored procedures, functions and more.
I’d really recommend GUI tool such as ‘view dependencies’ dialog in SSMS or free tool like ApexSQL Search for this because searching for dependencies in other objects can be error prone if you want to do it only with SQL.
If SQL is the only option you could try doing it like this.
select O.name as [Object_Name], C.text as [Object_Definition]
from sys.syscomments C
inner join sys.all_objects O ON C.id = O.object_id
where C.text like '%table_name%'
The original question asked to get a list of all foreign keys into a highly referenced table so that the table can be removed.
This little query returns all the 'drop foreign key' commands needed to drop all foreign keys into a particular table:
SELECT
'ALTER TABLE ['+sch.name+'].['+referencingTable.Name+'] DROP CONSTRAINT ['+foreignKey.name+']' '[DropCommand]'
FROM sys.foreign_key_columns fk
JOIN sys.tables referencingTable ON fk.parent_object_id = referencingTable.object_id
JOIN sys.schemas sch ON referencingTable.schema_id = sch.schema_id
JOIN sys.objects foreignKey ON foreignKey.object_id = fk.constraint_object_id
JOIN sys.tables referencedTable ON fk.referenced_object_id = referencedTable.object_id
WHERE referencedTable.name = 'MyTableName'
Example output:
[DropCommand]
ALTER TABLE [dbo].[OtherTable1] DROP CONSTRAINT [FK_OtherTable1_MyTable]
ALTER TABLE [dbo].[OtherTable2] DROP CONSTRAINT [FK_OtherTable2_MyTable]
Omit the WHERE-clause to get the drop commands for all foreign keys in the current database.
Here's the SQL code I would use.
SELECT
f.name AS 'Name of Foreign Key',
OBJECT_NAME(f.parent_object_id) AS 'Table name',
COL_NAME(fc.parent_object_id,fc.parent_column_id) AS 'Fieldname',
OBJECT_NAME(t.object_id) AS 'References Table name',
COL_NAME(t.object_id,fc.referenced_column_id) AS 'References fieldname',
'ALTER TABLE [' + OBJECT_NAME(f.parent_object_id) + '] DROP CONSTRAINT [' + f.name + ']' AS 'Delete foreign key',
'ALTER TABLE [' + OBJECT_NAME(f.parent_object_id) + '] WITH NOCHECK ADD CONSTRAINT [' +
f.name + '] FOREIGN KEY([' + COL_NAME(fc.parent_object_id,fc.parent_column_id) + ']) REFERENCES ' +
'[' + OBJECT_NAME(t.object_id) + '] ([' +
COL_NAME(t.object_id,fc.referenced_column_id) + '])' AS 'Create foreign key'
-- , delete_referential_action_desc AS 'UsesCascadeDelete'
FROM sys.foreign_keys AS f,
sys.foreign_key_columns AS fc,
sys.tables t
WHERE f.OBJECT_ID = fc.constraint_object_id
AND t.OBJECT_ID = fc.referenced_object_id
AND OBJECT_NAME(t.object_id) = 'Employees' -- Just show the FKs which reference a particular table
ORDER BY 2
It's not particularly clear SQL, so let's look at an example.
So, supposing I wanted to drop the Employees table in Microsoft's beloved Northwind database, but SQL Server told me that one or more Foreign Keys were preventing me from doing this.
The SQL command above would return these results...
It shows me that there are 3 Foreign Keys which reference the Employees table. In other words, I wouldn't be allowed to delete (drop) this table until these three Foreign Keys are first deleted.
In the results, the first row is how the following Foreign Key constraint would be shown in the results.
ALTER TABLE [dbo].[Employees] WITH NOCHECK
ADD CONSTRAINT [FK_Employees_Employees] FOREIGN KEY([ReportsTo])
REFERENCES [dbo].[Employees] ([EmployeeID])
The second-to-last column shows the SQL command I would need to use to delete one of these Foreign Keys, eg:
ALTER TABLE [Employees] DROP CONSTRAINT [FK_Employees_Employees]
...and the right-hand column shows the SQL to create it...
ALTER TABLE [Employees] WITH NOCHECK
ADD CONSTRAINT [FK_Employees_Employees]
FOREIGN KEY([ReportsTo]) REFERENCES [Employees] ([EmployeeID])
With all of these commands, you have everything you need to delete the relevant Foreign Keys to allow you to delete a table, then recreate them later.
Phew. Hope this helps.
The most Simplest one is by using sys.foreign_keys_columns in SQL. Here the table contains the Object ids of all the foreign keys wrt their Referenced column ID Referenced Table ID as well as the Referencing Columns and Tables. As the Id's remains constant the result will be reliable for further modifications in Schema as well as tables.
Query:
SELECT
OBJECT_NAME(fkeys.constraint_object_id) foreign_key_name
,OBJECT_NAME(fkeys.parent_object_id) referencing_table_name
,COL_NAME(fkeys.parent_object_id, fkeys.parent_column_id) referencing_column_name
,OBJECT_SCHEMA_NAME(fkeys.parent_object_id) referencing_schema_name
,OBJECT_NAME (fkeys.referenced_object_id) referenced_table_name
,COL_NAME(fkeys.referenced_object_id, fkeys.referenced_column_id)
referenced_column_name
,OBJECT_SCHEMA_NAME(fkeys.referenced_object_id) referenced_schema_name
FROM sys.foreign_key_columns AS fkeys
We can also add filter by using 'where'
WHERE OBJECT_NAME(fkeys.parent_object_id) = 'table_name' AND
OBJECT_SCHEMA_NAME(fkeys.parent_object_id) = 'schema_name'
SELECT PKTABLE_QUALIFIER = CONVERT(SYSNAME,DB_NAME()),
PKTABLE_OWNER = CONVERT(SYSNAME,SCHEMA_NAME(O1.SCHEMA_ID)),
PKTABLE_NAME = CONVERT(SYSNAME,O1.NAME),
PKCOLUMN_NAME = CONVERT(SYSNAME,C1.NAME),
FKTABLE_QUALIFIER = CONVERT(SYSNAME,DB_NAME()),
FKTABLE_OWNER = CONVERT(SYSNAME,SCHEMA_NAME(O2.SCHEMA_ID)),
FKTABLE_NAME = CONVERT(SYSNAME,O2.NAME),
FKCOLUMN_NAME = CONVERT(SYSNAME,C2.NAME),
-- Force the column to be non-nullable (see SQL BU 325751)
--KEY_SEQ = isnull(convert(smallint,k.constraint_column_id), sysconv(smallint,0)),
UPDATE_RULE = CONVERT(SMALLINT,CASE OBJECTPROPERTY(F.OBJECT_ID,'CnstIsUpdateCascade')
WHEN 1 THEN 0
ELSE 1
END),
DELETE_RULE = CONVERT(SMALLINT,CASE OBJECTPROPERTY(F.OBJECT_ID,'CnstIsDeleteCascade')
WHEN 1 THEN 0
ELSE 1
END),
FK_NAME = CONVERT(SYSNAME,OBJECT_NAME(F.OBJECT_ID)),
PK_NAME = CONVERT(SYSNAME,I.NAME),
DEFERRABILITY = CONVERT(SMALLINT,7) -- SQL_NOT_DEFERRABLE
FROM SYS.ALL_OBJECTS O1,
SYS.ALL_OBJECTS O2,
SYS.ALL_COLUMNS C1,
SYS.ALL_COLUMNS C2,
SYS.FOREIGN_KEYS F
INNER JOIN SYS.FOREIGN_KEY_COLUMNS K
ON (K.CONSTRAINT_OBJECT_ID = F.OBJECT_ID)
INNER JOIN SYS.INDEXES I
ON (F.REFERENCED_OBJECT_ID = I.OBJECT_ID
AND F.KEY_INDEX_ID = I.INDEX_ID)
WHERE O1.OBJECT_ID = F.REFERENCED_OBJECT_ID
AND O2.OBJECT_ID = F.PARENT_OBJECT_ID
AND C1.OBJECT_ID = F.REFERENCED_OBJECT_ID
AND C2.OBJECT_ID = F.PARENT_OBJECT_ID
AND C1.COLUMN_ID = K.REFERENCED_COLUMN_ID
AND C2.COLUMN_ID = K.PARENT_COLUMN_ID
SELECT
object_name(parent_object_id),
object_name(referenced_object_id),
name
FROM sys.foreign_keys
WHERE parent_object_id = object_id('Table Name')
List of all foreign keys referencing a given table in SQL Server :
You can get the referencing table name and column name through following query...
SELECT
OBJECT_NAME(f.parent_object_id) TableName,
COL_NAME(fc.parent_object_id,fc.parent_column_id) ColName
FROM
sys.foreign_keys AS f
INNER JOIN
sys.foreign_key_columns AS fc
ON f.OBJECT_ID = fc.constraint_object_id
INNER JOIN
sys.tables t
ON t.OBJECT_ID = fc.referenced_object_id
WHERE
OBJECT_NAME (f.referenced_object_id) = 'TableName'
And following screenshot for your understanding...
I am using this script to find all details related to foreign key.
I am using INFORMATION.SCHEMA.
Below is a SQL Script:
SELECT
ccu.table_name AS SourceTable
,ccu.constraint_name AS SourceConstraint
,ccu.column_name AS SourceColumn
,kcu.table_name AS TargetTable
,kcu.column_name AS TargetColumn
FROM INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE ccu
INNER JOIN INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS rc
ON ccu.CONSTRAINT_NAME = rc.CONSTRAINT_NAME
INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE kcu
ON kcu.CONSTRAINT_NAME = rc.UNIQUE_CONSTRAINT_NAME
ORDER BY ccu.table_name
First
EXEC sp_fkeys 'Table', 'Schema'
Then use NimbleText to play with your results
Some good answers above. But I prefer to have the answer with one query.
This piece of code is taken from sys.sp_helpconstraint (sys proc)
That's the way Microsoft looks up if there are foreign keys associated to the tbl.
--setup variables. Just change 'Customer' to tbl you want
declare #objid int,
#objname nvarchar(776)
select #objname = 'Customer'
select #objid = object_id(#objname)
if exists (select * from sys.foreign_keys where referenced_object_id = #objid)
select 'Table is referenced by foreign key' =
db_name() + '.'
+ rtrim(schema_name(ObjectProperty(parent_object_id,'schemaid')))
+ '.' + object_name(parent_object_id)
+ ': ' + object_name(object_id)
from sys.foreign_keys
where referenced_object_id = #objid
order by 1
The answer will look like this: test_db_name.dbo.Account: FK_Account_Customer
SELECT OBJECT_NAME(fk.parent_object_id) as ReferencingTable,
OBJECT_NAME(fk.constraint_object_id) as [FKContraint]
FROM sys.foreign_key_columns as fk
WHERE fk.referenced_object_id = OBJECT_ID('ReferencedTable', 'U')
This only shows the relationship if the are foreign key constraints. My database apparently predates the FK constraint.Some table use triggers to enforce referential integrity, and sometimes there's nothing but a similarly named column to indicate the relationship (and no referential integrity at all).
Fortunately, we do have a consistent naming scene so I am able to find referencing tables
and views like this:
SELECT OBJECT_NAME(object_id) from sys.columns where name like 'client_id'
I used this select as the basis for generating a script the does what I need to do on
the related tables.
SELECT
OBJECT_NAME(parent_object_id) 'Parent table',
c.NAME 'Parent column name',
OBJECT_NAME(referenced_object_id) 'Referenced table',
cref.NAME 'Referenced column name'
FROM
sys.foreign_key_columns fkc
INNER JOIN
sys.columns c
ON fkc.parent_column_id = c.column_id
AND fkc.parent_object_id = c.object_id
INNER JOIN
sys.columns cref
ON fkc.referenced_column_id = cref.column_id
AND fkc.referenced_object_id = cref.object_id where OBJECT_NAME(parent_object_id) = 'tablename'
If you want to get the foreign key relation of all the tables exclude the where clause else write your tablename instead of tablename
Most preferable answer by #BankZ
sp_help 'TableName'
additionally for different schema
sp_help 'schemaName.TableName'
Mysql server has information_schema.REFERENTIAL_CONSTRAINTS table FYI, you can filter it by table name or referenced table name.
Working off of what #Gishu did I was able to produce and use the following SQL in SQL Server 2005
SELECT t.name AS TableWithForeignKey, fk.constraint_column_id AS FK_PartNo,
c.name AS ForeignKeyColumn, o.name AS FK_Name
FROM sys.foreign_key_columns AS fk
INNER JOIN sys.tables AS t ON fk.parent_object_id = t.object_id
INNER JOIN sys.columns AS c ON fk.parent_object_id = c.object_id
AND fk.parent_column_id = c.column_id
INNER JOIN sys.objects AS o ON fk.constraint_object_id = o.object_id
WHERE fk.referenced_object_id = (SELECT object_id FROM sys.tables
WHERE name = 'TableOthersForeignKeyInto')
ORDER BY TableWithForeignKey, FK_PartNo;
Which Displays the tables, columns and Foreign Key names all in 1 query.
Determine primary keys and unique keys for all tables in a database...
This should list all the constraints and at the end you can put your filters
/* CAST IS DONE , SO THAT OUTPUT INTEXT FILE REMAINS WITH SCREEN LIMIT*/
WITH ALL_KEYS_IN_TABLE (CONSTRAINT_NAME,CONSTRAINT_TYPE,PARENT_TABLE_NAME,PARENT_COL_NAME,PARENT_COL_NAME_DATA_TYPE,REFERENCE_TABLE_NAME,REFERENCE_COL_NAME)
AS
(
SELECT CONSTRAINT_NAME= CAST (PKnUKEY.name AS VARCHAR(30)) ,
CONSTRAINT_TYPE=CAST (PKnUKEY.type_desc AS VARCHAR(30)) ,
PARENT_TABLE_NAME=CAST (PKnUTable.name AS VARCHAR(30)) ,
PARENT_COL_NAME=CAST ( PKnUKEYCol.name AS VARCHAR(30)) ,
PARENT_COL_NAME_DATA_TYPE= oParentColDtl.DATA_TYPE,
REFERENCE_TABLE_NAME='' ,
REFERENCE_COL_NAME=''
FROM sys.key_constraints as PKnUKEY
INNER JOIN sys.tables as PKnUTable
ON PKnUTable.object_id = PKnUKEY.parent_object_id
INNER JOIN sys.index_columns as PKnUColIdx
ON PKnUColIdx.object_id = PKnUTable.object_id
AND PKnUColIdx.index_id = PKnUKEY.unique_index_id
INNER JOIN sys.columns as PKnUKEYCol
ON PKnUKEYCol.object_id = PKnUTable.object_id
AND PKnUKEYCol.column_id = PKnUColIdx.column_id
INNER JOIN INFORMATION_SCHEMA.COLUMNS oParentColDtl
ON oParentColDtl.TABLE_NAME=PKnUTable.name
AND oParentColDtl.COLUMN_NAME=PKnUKEYCol.name
UNION ALL
SELECT CONSTRAINT_NAME= CAST (oConstraint.name AS VARCHAR(30)) ,
CONSTRAINT_TYPE='FK',
PARENT_TABLE_NAME=CAST (oParent.name AS VARCHAR(30)) ,
PARENT_COL_NAME=CAST ( oParentCol.name AS VARCHAR(30)) ,
PARENT_COL_NAME_DATA_TYPE= oParentColDtl.DATA_TYPE,
REFERENCE_TABLE_NAME=CAST ( oReference.name AS VARCHAR(30)) ,
REFERENCE_COL_NAME=CAST (oReferenceCol.name AS VARCHAR(30))
FROM sys.foreign_key_columns FKC
INNER JOIN sys.sysobjects oConstraint
ON FKC.constraint_object_id=oConstraint.id
INNER JOIN sys.sysobjects oParent
ON FKC.parent_object_id=oParent.id
INNER JOIN sys.all_columns oParentCol
ON FKC.parent_object_id=oParentCol.object_id /* ID of the object to which this column belongs.*/
AND FKC.parent_column_id=oParentCol.column_id/* ID of the column. Is unique within the object.Column IDs might not be sequential.*/
INNER JOIN sys.sysobjects oReference
ON FKC.referenced_object_id=oReference.id
INNER JOIN INFORMATION_SCHEMA.COLUMNS oParentColDtl
ON oParentColDtl.TABLE_NAME=oParent.name
AND oParentColDtl.COLUMN_NAME=oParentCol.name
INNER JOIN sys.all_columns oReferenceCol
ON FKC.referenced_object_id=oReferenceCol.object_id /* ID of the object to which this column belongs.*/
AND FKC.referenced_column_id=oReferenceCol.column_id/* ID of the column. Is unique within the object.Column IDs might not be sequential.*/
)
select * from ALL_KEYS_IN_TABLE
where
PARENT_TABLE_NAME in ('YOUR_TABLE_NAME')
or REFERENCE_TABLE_NAME in ('YOUR_TABLE_NAME')
ORDER BY PARENT_TABLE_NAME,CONSTRAINT_NAME;
For reference please read thru - http://blogs.msdn.com/b/sqltips/archive/2005/09/16/469136.aspx
I have been using this on 2008 and up. It's similar to some other solutions listed but, the field names are proper cased to handle case specific (LatBin) collations. Additionally, you can feed it a single table name and retrieve just the info for that table.
-->>SPECIFY THE DESIRED DB
USE ???
GO
/*********************************************************************************************
LIST OUT ALL PRIMARY AND FOREIGN KEY CONSTRAINTS IN A DB OR FOR A SPECIFIED TABLE
*********************************************************************************************/
DECLARE #tblName VARCHAR(255)
/*******************/
SET #tblName = NULL-->NULL will return all PK/FK constraints for every table in the database
/*******************/
SELECT PKTABLE_QUALIFIER = CONVERT(SYSNAME,DB_NAME()),
PKTABLE_OWNER = CONVERT(SYSNAME,SCHEMA_NAME(O1.schema_id)),
PKTABLE_NAME = CONVERT(SYSNAME,O1.name),
PKCOLUMN_NAME = CONVERT(SYSNAME,C1.name),
FKTABLE_QUALIFIER = CONVERT(SYSNAME,DB_NAME()),
FKTABLE_OWNER = CONVERT(SYSNAME,SCHEMA_NAME(O2.schema_id)),
FKTABLE_NAME = CONVERT(SYSNAME,O2.name),
FKCOLUMN_NAME = CONVERT(SYSNAME,C2.name),
-- Force the column to be non-nullable (see SQL BU 325751)
KEY_SEQ = isnull(convert(smallint,K.constraint_column_id),0),
UPDATE_RULE = CONVERT(SMALLINT,CASE OBJECTPROPERTY(F.object_id,'CnstIsUpdateCascade')
WHEN 1 THEN 0
ELSE 1
END),
DELETE_RULE = CONVERT(SMALLINT,CASE OBJECTPROPERTY(F.object_id,'CnstIsDeleteCascade')
WHEN 1 THEN 0
ELSE 1
END),
FK_NAME = CONVERT(SYSNAME,OBJECT_NAME(F.object_id)),
PK_NAME = CONVERT(SYSNAME,I.name),
DEFERRABILITY = CONVERT(SMALLINT,7) -- SQL_NOT_DEFERRABLE
FROM sys.all_objects O1,
sys.all_objects O2,
sys.all_columns C1,
sys.all_columns C2,
sys.foreign_keys F
INNER JOIN sys.foreign_key_columns K
ON (K.constraint_object_id = F.object_id)
INNER JOIN sys.indexes I
ON (F.referenced_object_id = I.object_id
AND F.key_index_id = I.index_id)
WHERE O1.object_id = F.referenced_object_id
AND O2.object_id = F.parent_object_id
AND C1.object_id = F.referenced_object_id
AND C2.object_id = F.parent_object_id
AND C1.column_id = K.referenced_column_id
AND C2.column_id = K.parent_column_id
AND ( O1.name = #tblName
OR O2.name = #tblName
OR #tblName IS null)
ORDER BY PKTABLE_NAME,FKTABLE_NAME
This gets any foreign key that involves the chosen table. *Assumes a _FIRSTABLENAME_SECONDTABLENAME format.
declare #tablename as varchar(MAX)
SET #tablename = 'yourtablename'
SELECT name
FROM YOURDATABASE.sys.objects
WHERE type_desc = 'FOREIGN_KEY_CONSTRAINT' and (name LIKE '%_' + #tablename + 'empdb_%' or name LIKE '%_' + #tablename )
This is a more general form:
SELECT name
FROM YOURDATABASE_PROD.sys.objects
WHERE type_desc = 'FOREIGN_KEY_CONSTRAINT' and name LIKE '%' + #tablename + '%' and
name NOT LIKE '[a-zA-Z0-9]' + #tablename + '%' and name NOT LIKE '%' + #tablename + '[a-zA-Z0-9]'
There is how to get count of all responsibilities for selected Id. Just change #dbTableName value, #dbRowId value and its type (if int you need to remove '' in line no 82 (..SET #SQL = ..)). Enjoy.
DECLARE #dbTableName varchar(max) = 'User'
DECLARE #dbRowId uniqueidentifier = '21d34ecd-c1fd-11e2-8545-002219a42e1c'
DECLARE #FK_ROWCOUNT int
DECLARE #SQL nvarchar(max)
DECLARE #PKTABLE_QUALIFIER sysname
DECLARE #PKTABLE_OWNER sysname
DECLARE #PKTABLE_NAME sysname
DECLARE #PKCOLUMN_NAME sysname
DECLARE #FKTABLE_QUALIFIER sysname
DECLARE #FKTABLE_OWNER sysname
DECLARE #FKTABLE_NAME sysname
DECLARE #FKCOLUMN_NAME sysname
DECLARE #UPDATE_RULE smallint
DECLARE #DELETE_RULE smallint
DECLARE #FK_NAME sysname
DECLARE #PK_NAME sysname
DECLARE #DEFERRABILITY sysname
IF OBJECT_ID('tempdb..#Temp1') IS NOT NULL
DROP TABLE #Temp1;
CREATE TABLE #Temp1 (
PKTABLE_QUALIFIER sysname,
PKTABLE_OWNER sysname,
PKTABLE_NAME sysname,
PKCOLUMN_NAME sysname,
FKTABLE_QUALIFIER sysname,
FKTABLE_OWNER sysname,
FKTABLE_NAME sysname,
FKCOLUMN_NAME sysname,
UPDATE_RULE smallint,
DELETE_RULE smallint,
FK_NAME sysname,
PK_NAME sysname,
DEFERRABILITY sysname,
FK_ROWCOUNT int
);
DECLARE FK_Counter_Cursor CURSOR FOR
SELECT PKTABLE_QUALIFIER = CONVERT(SYSNAME,DB_NAME()),
PKTABLE_OWNER = CONVERT(SYSNAME,SCHEMA_NAME(O1.SCHEMA_ID)),
PKTABLE_NAME = CONVERT(SYSNAME,O1.NAME),
PKCOLUMN_NAME = CONVERT(SYSNAME,C1.NAME),
FKTABLE_QUALIFIER = CONVERT(SYSNAME,DB_NAME()),
FKTABLE_OWNER = CONVERT(SYSNAME,SCHEMA_NAME(O2.SCHEMA_ID)),
FKTABLE_NAME = CONVERT(SYSNAME,O2.NAME),
FKCOLUMN_NAME = CONVERT(SYSNAME,C2.NAME),
-- Force the column to be non-nullable (see SQL BU 325751)
--KEY_SEQ = isnull(convert(smallint,k.constraint_column_id), sysconv(smallint,0)),
UPDATE_RULE = CONVERT(SMALLINT,CASE OBJECTPROPERTY(F.OBJECT_ID,'CnstIsUpdateCascade')
WHEN 1 THEN 0
ELSE 1
END),
DELETE_RULE = CONVERT(SMALLINT,CASE OBJECTPROPERTY(F.OBJECT_ID,'CnstIsDeleteCascade')
WHEN 1 THEN 0
ELSE 1
END),
FK_NAME = CONVERT(SYSNAME,OBJECT_NAME(F.OBJECT_ID)),
PK_NAME = CONVERT(SYSNAME,I.NAME),
DEFERRABILITY = CONVERT(SMALLINT,7) -- SQL_NOT_DEFERRABLE
FROM SYS.ALL_OBJECTS O1,
SYS.ALL_OBJECTS O2,
SYS.ALL_COLUMNS C1,
SYS.ALL_COLUMNS C2,
SYS.FOREIGN_KEYS F
INNER JOIN SYS.FOREIGN_KEY_COLUMNS K
ON (K.CONSTRAINT_OBJECT_ID = F.OBJECT_ID)
INNER JOIN SYS.INDEXES I
ON (F.REFERENCED_OBJECT_ID = I.OBJECT_ID
AND F.KEY_INDEX_ID = I.INDEX_ID)
WHERE O1.OBJECT_ID = F.REFERENCED_OBJECT_ID
AND O2.OBJECT_ID = F.PARENT_OBJECT_ID
AND C1.OBJECT_ID = F.REFERENCED_OBJECT_ID
AND C2.OBJECT_ID = F.PARENT_OBJECT_ID
AND C1.COLUMN_ID = K.REFERENCED_COLUMN_ID
AND C2.COLUMN_ID = K.PARENT_COLUMN_ID
AND O1.NAME = #dbTableName
OPEN FK_Counter_Cursor;
FETCH NEXT FROM FK_Counter_Cursor INTO #PKTABLE_QUALIFIER, #PKTABLE_OWNER, #PKTABLE_NAME, #PKCOLUMN_NAME, #FKTABLE_QUALIFIER, #FKTABLE_OWNER, #FKTABLE_NAME, #FKCOLUMN_NAME, #UPDATE_RULE, #DELETE_RULE, #FK_NAME, #PK_NAME, #DEFERRABILITY;
WHILE ##FETCH_STATUS = 0
BEGIN
SET #SQL = 'SELECT #dbCountOut = COUNT(*) FROM [' + #FKTABLE_NAME + '] WHERE [' + #FKCOLUMN_NAME + '] = ''' + CAST(#dbRowId AS varchar(max)) + '''';
EXECUTE sp_executesql #SQL, N'#dbCountOut int OUTPUT', #dbCountOut = #FK_ROWCOUNT OUTPUT;
INSERT INTO #Temp1 (PKTABLE_QUALIFIER, PKTABLE_OWNER, PKTABLE_NAME, PKCOLUMN_NAME, FKTABLE_QUALIFIER, FKTABLE_OWNER, FKTABLE_NAME, FKCOLUMN_NAME, UPDATE_RULE, DELETE_RULE, FK_NAME, PK_NAME, DEFERRABILITY, FK_ROWCOUNT) VALUES (#FKTABLE_QUALIFIER, #PKTABLE_OWNER, #PKTABLE_NAME, #PKCOLUMN_NAME, #FKTABLE_QUALIFIER, #FKTABLE_OWNER, #FKTABLE_NAME, #FKCOLUMN_NAME, #UPDATE_RULE, #DELETE_RULE, #FK_NAME, #PK_NAME, #DEFERRABILITY, #FK_ROWCOUNT)
FETCH NEXT FROM FK_Counter_Cursor INTO #PKTABLE_QUALIFIER, #PKTABLE_OWNER, #PKTABLE_NAME, #PKCOLUMN_NAME, #FKTABLE_QUALIFIER, #FKTABLE_OWNER, #FKTABLE_NAME, #FKCOLUMN_NAME, #UPDATE_RULE, #DELETE_RULE, #FK_NAME, #PK_NAME, #DEFERRABILITY;
END;
CLOSE FK_Counter_Cursor;
DEALLOCATE FK_Counter_Cursor;
GO
SELECT * FROM #Temp1
GO
The following solution work for me:
--Eliminar las llaves foraneas
declare #query varchar(8000)
declare cursorRecorrerTabla cursor for
SELECT 'ALTER TABLE [PoaComFinH].['+sch.name+'].['+referencingTable.Name+'] DROP CONSTRAINT ['+foreignKey.name+']' 'query'
FROM PoaComFinH.sys.foreign_key_columns fk
JOIN PoaComFinH.sys.tables referencingTable ON fk.parent_object_id = referencingTable.object_id
JOIN PoaComFinH.sys.schemas sch ON referencingTable.schema_id = sch.schema_id
JOIN PoaComFinH.sys.objects foreignKey ON foreignKey.object_id = fk.constraint_object_id
JOIN PoaComFinH.sys.tables referencedTable ON fk.referenced_object_id = referencedTable.object_id
--3ro. abrir el cursor.
open cursorRecorrerTabla
fetch next from cursorRecorrerTabla
into #query
while ##fetch_status = 0
begin
--inicio cuerpo del cursor
print #query
exec(#query)
--fin cuerpo del cursor
fetch next from cursorRecorrerTabla
into #query
end
--cerrar cursor
close cursorRecorrerTabla
deallocate cursorRecorrerTabla
You can find through below query :
SELECT OBJECT_NAME (FK.referenced_object_id) 'Referenced Table',
OBJECT_NAME(FK.parent_object_id) 'Referring Table', FK.name 'Foreign Key',
COL_NAME(FK.referenced_object_id, FKC.referenced_column_id) 'Referenced Column',
COL_NAME(FK.parent_object_id,FKC.parent_column_id) 'Referring Column'
FROM sys.foreign_keys AS FK
INNER JOIN sys.foreign_key_columns AS FKC
ON FKC.constraint_object_id = FK.OBJECT_ID
WHERE OBJECT_NAME (FK.referenced_object_id) = 'YourTableName'
AND COL_NAME(FK.referenced_object_id, FKC.referenced_column_id) = 'YourColumnName'
order by OBJECT_NAME(FK.parent_object_id)
Also try.
EXEC sp_fkeys 'tableName', 'schemaName'
with sp_fkeys you may filter the result by not only pk table name and schema but also with fk table name and schema. link
with tab_list as (
select t.name AS Table_Name, t.object_id, s.name AS Table_Schema from sys.tables t, sys.schemas s
where t.schema_id = s.schema_id
and s.name = 'your schema')
select IIF(col.column_id = 1, tab.TABLE_SCHEMA + '.' + tab.TABLE_NAME, NULL) Table_Name,
col.Name AS Column_Name, IIF(col.IS_NULLABLE= 0, 'NOT NULL', '') Nullable, st.name Type,
CASE WHEN st.name = 'decimal' THEN CONVERT(NVARCHAR(4000), col.Precision) + ',' + CONVERT(NVARCHAR(4000), col.Scale)
WHEN col.max_length = -1 THEN 'max'
WHEN st.name in ('int', 'bit', 'bigint', 'datetime2') THEN NULL
ELSE CONVERT(NVARCHAR(4000), col.max_length / 2)
END
AS Length,
ss.name + '.' + stab.name Referenced_Table, scol.name Referenced_Column
from sys.COLUMNS col
INNER JOIN tab_list tab ON col.object_id = tab.object_id
INNER JOIN sys.types st ON col.system_type_id = st.system_type_id AND col.user_type_id = st.user_type_id
LEFT JOIN [sys].[foreign_key_columns] sfkc ON col.object_id = sfkc.parent_object_id AND col.column_id = sfkc.parent_column_id
LEFT JOIN sys.tables stab ON sfkc.referenced_object_id = stab.object_id
LEFT JOIN sys.columns scol ON sfkc.referenced_object_id = scol.object_id AND sfkc.referenced_column_id = scol.column_id
LEFT JOIN sys.schemas ss ON ss.schema_id = stab.schema_id
Here is the best practice in my opinion to work over this scenario in SQL Server 2016.
You have to list the foreign keys using :
EXEC sp_fkeys 'TableName'
There you can see the full info of the FKs. Notice the columns FKTABLE_NAME, FKCOLUMN_NAME, FK_NAME, UPDATE_RULE, DELETE_RULE is the info you need to remove foreign keys and implement them again after truncate.
You can organise a script as follows:
-- EXEC sp_fkeys 'TableName'
-- DROP CONSTRAINTS: I drop one, here drop every constraint you desire.
BEGIN TRANSACTION
GO
ALTER TABLE dbo.TableName
DROP CONSTRAINT IF EXISTS FK_TableName_OtherTable
GO
ALTER TABLE dbo.TableName SET (LOCK_ESCALATION = TABLE)
GO
COMMIT
-- TRUNCATE
BEGIN TRANSACTION
TRUNCATE TABLE TableName
GO
COMMIT
-- RECREATE CONSTRAINTS: I recreate 1, here recreate every fk you desire
BEGIN TRANSACTION
GO
ALTER TABLE dbo.TableName SET (LOCK_ESCALATION = TABLE)
GO
ALTER TABLE dbo.TableName ADD CONSTRAINT
FK_TableName_OtherTable FOREIGN KEY
(
Id_FK
) REFERENCES dbo.OtherTable
(
Id
) ON UPDATE NO ACTION
ON DELETE NO ACTION
GO
COMMIT
** Values for UPDATE_RULE and DELETE_RULE can be seen in documentation of sp_fkeys:
I know that its a late(very late) reply, but I find these easy ways to find all the foreign_key_references. Here're the solutions;
Solution 01:
EXEC SP_FKEYS 'MyTableName'; // It'll show you the all the information(in multiple tables) regarding to the TableName with all ForeignKey_References.
Solution 02:
EXEC SP_HELP 'MyTableName'; // It'll show all ForeignKey references in a single table.
Solution 03:
// It'll show you the Column_Name with Referenced_Table_Name
SELECT
COL_NAME(fc.parent_object_id,fc.parent_column_id) Column_Name,
OBJECT_NAME(f.parent_object_id) Table_Name
FROM
sys.foreign_keys AS f
INNER JOIN
sys.foreign_key_columns AS fc
ON f.OBJECT_ID = fc.constraint_object_id
INNER JOIN
sys.tables t
ON t.OBJECT_ID = fc.referenced_object_id
WHERE
OBJECT_NAME (f.referenced_object_id) = 'MyTableName'
Hopefully, this'll help you a lot. ;-)
This answer builds on but is formatted like sp_fkeys, works on multiple columns and lists their order.
SELECT fk_obj.name AS FK_NAME,
pk_schema.name AS PKTABLE_OWNER,
pk_table.name AS PKTABLE_NAME,
pk_column.name AS PKCOLUMN_NAME,
fk_schema.name AS FKTABLE_OWNER,
fk_table.name AS FKTABLE_NAME,
fk_column.name AS FKCOLUMN_NAME,
ROW_NUMBER() over (
PARTITION BY fk_obj.name, fk_schema.name
ORDER BY fkc.constraint_column_id
) AS KEY_SEQ
FROM sys.foreign_key_columns fkc
INNER JOIN sys.objects fk_obj
ON fk_obj.object_id = fkc.constraint_object_id
INNER JOIN sys.tables fk_table
ON fk_table.object_id = fkc.parent_object_id
INNER JOIN sys.schemas fk_schema
ON fk_table.schema_id = fk_schema.schema_id
INNER JOIN sys.columns fk_column
ON fk_column.column_id = parent_column_id
AND fk_column.object_id = fk_table.object_id
INNER JOIN sys.tables pk_table
ON pk_table.object_id = fkc.referenced_object_id
INNER JOIN sys.schemas pk_schema
ON pk_table.schema_id = pk_schema.schema_id
INNER JOIN sys.columns pk_column
ON pk_column.column_id = fkc.referenced_column_id
AND pk_column.object_id = pk_table.object_id;