I created one script to display the foreign keys in the particular table.
SELECT i.CONSTRAINT_NAME FROM information_schema.TABLE_CONSTRAINTS i
LEFT JOIN information_schema.KEY_COLUMN_USAGE k ON
i.CONSTRAINT_NAME = k.CONSTRAINT_NAME WHERE i.CONSTRAINT_TYPE = 'FOREIGN KEY'
AND i.TABLE_NAME = 'sample';
When I execute this command in my host, it displays the list of foreign key constraints found in all the databases with table name "sample".
But i need particular database, sample table foreign keys.
just add at the end
AND i.table_schema = '<the name of your database which is a schema>'
EDIT :
Change the left join to
LEFT JOIN information_schema.KEY_COLUMN_USAGE
ON i.CONSTRAINT_NAME = k.CONSTRAINT_NAME AND
i.TABLE_SCHEMA = k.TABLE_SCHEMA
because you could find constraint with same name in different schemas.
what's a schema and a database in mysql
Need to select the database before run this query. Following may be helpful.
USE YourDatabaseName
SELECT i.CONSTRAINT_NAME
FROM information_schema.TABLE_CONSTRAINTS i
LEFT JOIN information_schema.KEY_COLUMN_USAGE k
ON i.CONSTRAINT_NAME = k.CONSTRAINT_NAME
WHERE i.CONSTRAINT_TYPE = 'FOREIGN KEY'
AND i.TABLE_NAME = 'sample'
Related
Based on SQL Server Schema Collections I'd like to use sqlConnection.GetSchema("IndexColumns"); to determine which columns are primary keys.
I did some experiments and found that with the above request I get a data table with the following information:
table_catalog table_schema table_name column_name ordinal_position KeyType index_name
---------------------------------------------------------------------------------------------------------------------------
TestDb dbo TestTableWithPrimaryKey Id 1 56 PK_TestTableWithPrimaryKey
I guess KeyType = 56 stands for primary-key but this is only deduced from this table definition:
CREATE TABLE [dbo].[TestTableWithPrimaryKey]
(
[Id] [int] IDENTITY(1,1) NOT NULL,
[Foo] [nvarchar](50) NOT NULL,
CONSTRAINT [PK_TestTableWithPrimaryKey]
PRIMARY KEY CLUSTERED ([Id] ASC)
) ON [PRIMARY]
I'd like to verify that my finding is correct before I actually use it in any project. Is there some place where I can get all key types?
The KeyType column appears to map to the column data type as enumerated by the SQL Server sys.types catalog view system_type column (value 56 is int). Consequently, this will not help identify the column as a member of the primary key.
There are multiple methods to get SQL Server primary key columns, including SMO and catalog view queries. Here's one example to get all the primary key columns in the database for SQL Server. If you need to support multiple DBMS products, you could instead use the INFORMATION_SCHEMA catalog views for DBMS products that implement those ANSI standard views.
SELECT
OBJECT_SCHEMA_NAME(i.object_id) AS SchemaName
, OBJECT_NAME(i.object_id) AS TableName
, c.name AS ColumnName
, ic.key_ordinal AS KeyOrdinal
FROM sys.key_constraints AS kc
JOIN sys.indexes AS i ON i.object_id = kc.parent_object_id AND kc.name = i.name
JOIN sys.index_columns AS ic ON ic.object_id = i.object_id AND ic.index_id = i.index_id
JOIN sys.columns AS c ON c.object_id = ic.object_id AND c.column_id = ic.column_id
WHERE kc.type_desc = N'PRIMARY_KEY_CONSTRAINT'
ORDER BY
SchemaName
, TableName
, KeyOrdinal;
By looking at the internal SqlMetaDataFactory the call to sqlConnection.GetSchema("IndexColumns"); does lookup which command to execute as found in the resource file System.Data.SqlClient.SqlMetaData.xml and that will show us for entry IndexColumns
<MetaDataCollections>
<CollectionName>IndexColumns</CollectionName>
<NumberOfRestrictions>5</NumberOfRestrictions>
<NumberOfIdentifierParts>4</NumberOfIdentifierParts>
<PopulationMechanism>SQLCommand</PopulationMechanism>
<PopulationString>EXEC sys.sp_indexcolumns_managed #Catalog, #Owner, #Table, #ConstraintName, #Column</PopulationString>
<MinimumVersion>10.00.0000</MinimumVersion>
</MetaDataCollections>
This means that it will execute EXEC sys.sp_indexcolumns_managed. That stored procedure will reveal with EXEC sp_helptext 'sys.sp_indexcolumns_managed' that it selects from sys.spt_indexcolumns_view_managed and that view is defined as:
select distinct
db_Name() as constraint_catalog,
constraint_schema = SCHEMA_NAME(o.schema_id),
constraint_name = x.name,
table_catalog = db_name(),
table_schema = SCHEMA_NAME(o.schema_id),
table_name = o.name,
column_name = c.name,
ordinal_position = xc.key_ordinal,
KeyType = c.system_type_id,
index_name = x.name
from
sys.objects o INNER JOIN sys.indexes x ON
(
o.object_id = x.object_id AND
o.type in ('U')
) INNER JOIN
sys.index_columns xc ON
(
xc.object_id = x.object_id AND
xc.index_id = x.index_id
) INNER JOIN
sys.columns c ON
(
o.object_id = c.object_id AND
xc.column_id = c.column_id
)
(You can find its definition with SELECT OBJECT_DEFINITION(OBJECT_ID('sys.sp_indexcolumns_managed')); because it is part of the Resource Database)
Now we can see that the column KeyType is projected over sys.columns.system_type_id which is documented in sys.columns as
ID of the system type of the column.
and Where do I find Sql Server metadata for column datatypes? details that joining with sys.types will give you the information of the type of the column.
Armed with that information we can already conclude that I guess KeyType = 56 stands for primary-key is not true and running
select name, system_type_id, user_type_id, schema_id, max_length, precision scale
from sys.types
where system_type_id = 56
will return
name system_type_id user_type_id schema_id max_length scale
---- -------------- ------------ --------- ---------- -----
int 56 56 4 4 10
and that is the columntype, not if it is the primarykey.
There doesn't seem to be reliable way to find the primary key by means of the GetSchema call, AFAICT. Use the query provided by Dan Guzman.
I have created a unique constraint in an SQL Server Database using the following statement:
ALTER TABLE mytable ADD CONSTRAINT mytable_unique UNIQUE (uid)
How can I get all unique constraint names programmatically with C# SQLConnection object?
query on information_schema.constraint_column_usage
SELECT TC.Constraint_Name ,
CC.Column_Name
FROM information_schema.table_constraints TC
INNER JOIN information_schema.constraint_column_usage CC
ON TC.Constraint_Name = CC.Constraint_Name
WHERE TC.constraint_type = 'Unique'
ORDER BY TC.Constraint_Name
You can also get these from sys.key_constraints:
select name from sys.key_constraints where type = 'UQ'
I am currently trying to retrieve the table names and primary key of each table by calling the following SQL in C#. This is what I've tried so far:
SELECT t.TABLE_NAME As 'Table Name',
Keys.COLUMN_NAME AS 'Primary Key'
FROM INFORMATION_SCHEMA.TABLES t
left outer join INFORMATION_SCHEMA.TABLE_CONSTRAINTS Constraints
on t.TABLE_NAME = Constraints.Table_name
and t.Table_Schema = Constraints.Table_Schema
left outer join INFORMATION_SCHEMA.KEY_COLUMN_USAGE AS Keys
ON Constraints.TABLE_NAME = Keys.TABLE_NAME
and Constraints.CONSTRAINT_NAME = Keys.CONSTRAINT_NAME
and Constraints.CONSTRAINT_TYPE = 'PRIMARY KEY'
The problem is that I would like the result to just contain a "null" entry if a table does not have a primary key. While it is working, for some reason the result contains a duplicate of the "Salary" table as shown below. The Salary and Employees tables both have primary keys, and the "Test" table does not:
EDIT: I've tried this now, and it seems to work. Are there any disadvantages to doing so?
SELECT T.TABLE_NAME As 'Table Name'
, (
Select K1.COLUMN_NAME
From INFORMATION_SCHEMA.TABLE_CONSTRAINTS As C1
Join INFORMATION_SCHEMA.KEY_COLUMN_USAGE As K1
On C1.TABLE_SCHEMA = K1.TABLE_SCHEMA
And C1.TABLE_NAME = K1.TABLE_NAME
And C1.CONSTRAINT_NAME = K1.CONSTRAINT_NAME
Where C1.CONSTRAINT_TYPE = 'PRIMARY KEY'
And T.TABLE_SCHEMA = C1.TABLE_SCHEMA
And T.TABLE_NAME = C1.TABLE_NAME
)As PrimaryKeyColumns
FROM INFORMATION_SCHEMA.TABLES As T
Try replace this condition Constraints.CONSTRAINT_TYPE = 'PRIMARY KEY' :
SELECT t.TABLE_NAME As 'Table Name',
Keys.COLUMN_NAME AS 'Primary Key'
FROM INFORMATION_SCHEMA.TABLES t
left outer join INFORMATION_SCHEMA.TABLE_CONSTRAINTS Constraints
on t.TABLE_NAME = Constraints.Table_name
and t.Table_Schema = Constraints.Table_Schema
and Constraints.CONSTRAINT_TYPE = 'PRIMARY KEY'
left outer join INFORMATION_SCHEMA.KEY_COLUMN_USAGE AS Keys
ON Constraints.TABLE_NAME = Keys.TABLE_NAME
and Constraints.CONSTRAINT_NAME = Keys.CONSTRAINT_NAME
You should account for your PK having multiple columns. You can do this by changing to a subquery:
SELECT T.TABLE_NAME As 'Table Name'
, Stuff(
(
Select ', ' + K1.COLUMN_NAME
From INFORMATION_SCHEMA.TABLE_CONSTRAINTS As C1
Join INFORMATION_SCHEMA.KEY_COLUMN_USAGE As K1
On C1.TABLE_SCHEMA = K1.TABLE_SCHEMA
And C1.TABLE_NAME = K1.TABLE_NAME
And C1.CONSTRAINT_NAME = K1.CONSTRAINT_NAME
Where C1.CONSTRAINT_TYPE = 'PRIMARY KEY'
And T.TABLE_SCHEMA = C1.TABLE_SCHEMA
And T.TABLE_NAME = C1.TABLE_NAME
For Xml Path(''), type
).value('.', 'nvarchar(max)')
, 1, 2, '') As PrimaryKeyColumns
FROM INFORMATION_SCHEMA.TABLES As T
Btw, if you really want to use Joins to the TABLES view, you need to nest the joins. The problem is that you have two outer joins and the columns from the foreign keys are generating rows in your output. It should be noted that the downside to the following approach over the earlier mentioned subquery approach is that you will get multiple rows if a primary key consists of multiple columns. That said, you can nest joins in SQL Server so that it processes the inner, inner join first and then the outer join:
SELECT T.TABLE_NAME As 'Table Name'
, Keys.COLUMN_NAME AS 'Primary Key'
FROM INFORMATION_SCHEMA.TABLES As T
Left Join( INFORMATION_SCHEMA.TABLE_CONSTRAINTS Constraints
Join INFORMATION_SCHEMA.KEY_COLUMN_USAGE As Keys
On Constraints.TABLE_SCHEMA = Keys.TABLE_SCHEMA
And Constraints.TABLE_NAME = Keys.TABLE_NAME
And Constraints.CONSTRAINT_NAME = Keys.CONSTRAINT_NAME
And Constraints.CONSTRAINT_TYPE = 'PRIMARY KEY' )
On T.TABLE_SCHEMA = Constraints.TABLE_SCHEMA
And T.TABLE_NAME = Constraints.TABLE_NAME
In this query, the Inner Join between TABLE_CONSTRAINTS and KEY_COLUMN_USAGE is processed first and the results are combined in a Left Join to TABLES view.
I see you have already accepted your answer, but here's a pure C# answer in case someone is interested:
static void Main(string[] args)
{
Server server = new Server("serverName");
Database db = server.Databases["DatabaseName"];
string tableName = "TableName";
Table table = db.Tables[tableName];
if (table != null)
{
Console.WriteLine("Table: {0}", tableName);
if (table.Columns.Count > 0)
{
Console.WriteLine(" Primary Key Columns:");
foreach (Column column in table.Columns)
{
if (column.InPrimaryKey)
{
Console.WriteLine(string.Format(" {0}", column.Name));
}
}
}
else
{
Console.WriteLine(" No primary key.", tableName);
}
}
Console.WriteLine("Press ENTER to exit...");
Console.ReadLine();
}
You will need to add references to the Microsoft.SqlServer.Management.Sdk.Sfc and Microsoft.SqlServer.Smo assemblies and import the appropriate namespaces.
select
TABLE_SCHEMA,
TABLE_NAME
from
INFORMATION_SCHEMA.TABLES
where
objectproperty(object_id(table_name),'TableHasPrimaryKey')=0
ORDER BY
TABLE_NAME
I need a query or C# code to get the primary key or foreign key details of each table in an MS Access database.
Try OleDBConnection.GetSchema
Additional information : Retrieving Database Schema Information (ADO.NET)
1. SELECT * FROM ALL_CONS_COLUMNS A
JOIN ALL_CONSTRAINTS C ON A.CONSTRAINT_NAME = C.CONSTRAINT_NAME
WHERE C.TABLE_NAME = <your table> AND C.CONSTRAINT_TYPE = 'P'
2. SELECT * FROM ALL_CONS_COLUMNS A
JOIN ALL_CONSTRAINTS C ON A.CONSTRAINT_NAME = C.CONSTRAINT_NAME
WHERE C.TABLE_NAME = <your table> AND C.CONSTRAINT_TYPE = 'R'
1st is for primary key & 2nd one is for foreign key..........I think this may help you.
I have table named Person and column named ID
how to check if ID is already FOREIGN KEY cause I want to make it with this code:
ALTER TABLE Person ADD FOREIGN KEY(ID) REFERENCES Job(ID)
ON DELETE CASCADE ON UPDATE CASCADE
but if ID is already a FOREIGN KEY it gives me the following error "may cause cycles or multiple cascade paths" because of the condition with two cascades... How to check if this field is FOREIGN KEY to avoid this error?
You'd want to look in the INFORMATION SCHEMA views
Though it's not as complete as it should be. This is the final query you'd want:
SELECT
KCU1.CONSTRAINT_NAME AS 'FK_CONSTRAINT_NAME'
, KCU1.TABLE_NAME AS 'FK_TABLE_NAME'
, KCU1.COLUMN_NAME AS 'FK_COLUMN_NAME'
, KCU1.ORDINAL_POSITION AS 'FK_ORDINAL_POSITION'
, KCU2.CONSTRAINT_NAME AS 'UQ_CONSTRAINT_NAME'
, KCU2.TABLE_NAME AS 'UQ_TABLE_NAME'
, KCU2.COLUMN_NAME AS 'UQ_COLUMN_NAME'
, KCU2.ORDINAL_POSITION AS 'UQ_ORDINAL_POSITION'
FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS RC
JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE KCU1
ON KCU1.CONSTRAINT_CATALOG = RC.CONSTRAINT_CATALOG
AND KCU1.CONSTRAINT_SCHEMA = RC.CONSTRAINT_SCHEMA
AND KCU1.CONSTRAINT_NAME = RC.CONSTRAINT_NAME
JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE KCU2
ON KCU2.CONSTRAINT_CATALOG =
RC.UNIQUE_CONSTRAINT_CATALOG
AND KCU2.CONSTRAINT_SCHEMA =
RC.UNIQUE_CONSTRAINT_SCHEMA
AND KCU2.CONSTRAINT_NAME =
RC.UNIQUE_CONSTRAINT_NAME
AND KCU2.ORDINAL_POSITION = KCU1.ORDINAL_POSITION
See here for more information
http://msdn.microsoft.com/en-us/library/aa175805(v=sql.80).aspx
Here is a simple little version
SELECT TOP(1) a.COLUMN_NAME FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS b JOIN
INFORMATION_SCHEMA.KEY_COLUMN_USAGE a ON a.CONSTRAINT_CATALOG = b.CONSTRAINT_CATALOG AND a.CONSTRAINT_NAME = b.CONSTRAINT_NAME WHERE a.COLUMN_NAME = *your column*)
You can easily add table name and DB name in the where clause as well