How to get column-wise constraints in SQL Server - sql-server

I am using below query to get constraints on required table:
SELECT
OBJECT_NAME(o.object_id) AS ConstraintName,
SCHEMA_NAME(schema_id) AS SchemaName,
OBJECT_NAME(parent_object_id) AS TableName,
type_desc AS ConstraintType
FROM
sys.objects o
-- INNER JOIN
-- sys.columns c ON o.object_id = c.object_id
WHERE
type_desc LIKE '%CONSTRAINT'
AND OBJECT_NAME(parent_object_id)= 'All_Data_Types'
Successfully getting table-wise constraint details. But, I want column's information as well.
Could someone help me with this?
Thanks in advance

Fast solution for default constraint is
SELECT dc.object_id AS ConstraintID, DC.name AS ConstraintName
, O.object_id AS TableID, O.name AS TableName
, C.object_id AS ColumnID, C.name AS ColName
FROM sys.default_constraints AS DC
LEFT JOIN sys.objects AS O ON O.object_id = DC.parent_object_id
LEFT JOIN sys.columns c ON o.object_id = c.object_id AND DC.parent_column_id = c.column_id

For table constraints you could use something like this:
SELECT KCU.*, TC.CONSTRAINT_TYPE
FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE AS KCU
LEFT JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS AS TC ON TC.CONSTRAINT_SCHEMA = KCU.CONSTRAINT_SCHEMA AND TC.CONSTRAINT_NAME = KCU.CONSTRAINT_NAME

If you are on SQL Server 2012 or later then you can use system view sys.sysconstraints:
Contains mappings of constraints to the objects that own the
constraints within the database.
So, this query:
SELECT *
FROM sys.sysconstraints s
INNER JOIN sys.objects o ON o.object_id = s.constid
theoretically returns the same number of rows as your query. But now you have the additional information about the ID of the column on which the constraint is defined. That is column colid of sys.sysconstraints:
ID of the column on which the constraint is defined.
0 = Table constraint
Thus, using this query:
SELECT OBJECT_NAME(o.object_id) AS ConstraintName,
SCHEMA_NAME(o.schema_id) AS SchemaName,
OBJECT_NAME(o.parent_object_id) AS TableName,
o.type_desc AS ConstraintType,
COALESCE(c.COLUMN_NAME, 'Table constraint') AS ColumnName
FROM sys.sysconstraints s
INNER JOIN sys.objects o ON o.object_id = s.constid
LEFT JOIN INFORMATION_SCHEMA.COLUMNS c ON c.ORDINAL_POSITION = s.colid AND s.colid <> 0
you also get the name the column related to the constraint.

Here is the query. You are using INNER JOIN on wrong column_name of tables.
You used this
INNER JOIN sys.columns c ON o.object_id = c.object_id
I replaced it with
INNER JOIN sys.columns c ON o.parent_object_id = c.object_id
Now you can see the column_name as well as table_name along with constraint_details.
SELECT OBJECT_NAME(o.object_id) AS ConstraintName,
SCHEMA_NAME(schema_id) AS SchemaName,
OBJECT_NAME(parent_object_id) AS TableName,
c.name as ColumnName,
type_desc AS ConstraintType
FROM sys.objects o
INNER JOIN sys.columns c ON o.parent_object_id = c.object_id
WHERE type_desc LIKE '%CONSTRAINT';
Also avoid using the below clause
AND OBJECT_NAME(parent_object_id)= 'All_Data_Types'

Related

How to select only numeric type of ccolumn names in sql server

Currently I am working with a table in sql server
I want to select numeric datatype columns from table
I am using query now but it was showing all column names with datatypes
SELECT column_name as [Columname], data_type as [Data_Type] FROM information_schema.columns WHERE table_name = 'Table_name';
ExTable:
ID Customername Profit Sales Country state
1 Paul 10 25 INDIA AP
2 John 5 20 USA NY
3 Prasanth 6 25 INDIA TN
This is the table but i want to get only ID,Profit,Sales with their datatypes
Please let me know the query
Extend your WHERE to include the column names?
SELECT c.[name] AS [Columname],
ct.[name] AS [Data_Type]
FROM sys.tables t
JOIN sys.columns c ON t.object_id = c.object_id
JOIN sys.types ct ON c.system_type_id = ct.system_type_id
WHERE t.[name] = 'Table_name'
AND c.[name] IN ('ID','Profit','Sales');
Or do you mean...?
SELECT c.[name] AS [Columname],
ct.[name] AS [Data_Type]
FROM sys.tables t
JOIN sys.columns c ON t.object_id = c.object_id
JOIN sys.types ct ON c.system_type_id = ct.system_type_id
WHERE t.[name] = 'Table_name'
AND ct.[name] IN ('tinyint','smallint','int','bigint','decimal','numeric','float');
That list is not exhaustive. For example you have smallmoney, money and real datatypes as well.
SELECT s.name AS 'schema', ts.name AS TableName,
c.name AS column_name, c.column_id, SCHEMA_NAME(t.schema_id) AS DatatypeSchema,
t.name AS Datatypename, t.is_user_defined, t.is_assembly_type, c.is_nullable,
c.max_length, c.PRECISION, c.scale
FROM sys.columns AS c
INNER JOIN sys.types AS t ON c.user_type_id=t.user_type_id
INNER JOIN sys.tables ts ON ts.OBJECT_ID = c.OBJECT_ID
INNER JOIN sys.schemas s ON s.schema_id = ts.schema_id
ORDER BY s.name, ts.name, c.column_id
Use where clause to filter results according to your requirement.

How to find a table with a primary key with a certain column name in Microsoft SQL?

In Microsoft SQL, if I want to get information about where a column with a certain column name appears in my database, I can run this query:
select * from information_schema.columns where column_name = 'XXXXX';
This query returns a wealth of information about the instances where a column with the name appears, but I don't see anything about referential constraints.
I've tried some other queries below, but none seem to yield the information I want:
select * from INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS
select * from INFORMATION_SCHEMA.TABLE_CONSTRAINTS
select * from INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE
I want to write a query that would do something like this:
select table_schema, table_name from INFORMATION_SCHEMA.COLUMNS
where column_name = 'XXXXX' and IsPrimaryKey = 1;
Edit: It was suggested that this question duplicates a question about finding the primary key of a given table. This question is related, but different because I am starting out knowing the name of a column (which may occur in many tables) and I want to be able to tell if there is a table with a primary key column with the same name.
SELECT TABLE_NAME
FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE
WHERE OBJECTPROPERTY(OBJECT_ID(CONSTRAINT_SCHEMA + '.' + CONSTRAINT_NAME), 'IsPrimaryKey') = 1
AND COLUMN_NAME = 'ColumnName' AND TABLE_SCHEMA = 'SchemaName'
SELECT
s.name AS schema_name,
o.name AS table_name
--, *
FROM sys.objects o
join sys.schemas s on s.schema_id = o.schema_id
join sys.indexes i on i.object_id = o.object_id
join sys.index_columns ic ON i.object_id = ic.object_id AND i.index_id = ic.index_id
join sys.columns c ON ic.object_id = c.object_id AND c.column_id = ic.column_id
WHERE i.is_primary_key = 1
and i.name = 'XXXXX';
EDIT:
I wrote the first way to show that PKs aren't always single column but forgot to note that and remove the extra rows. Here is the version that returns a single result.
SELECT
s.name AS schema_name,
o.name AS table_name
--, *
FROM sys.objects o
join sys.schemas s on s.schema_id = o.schema_id
join sys.indexes i on i.object_id = o.object_id
--join sys.index_columns ic ON i.object_id = ic.object_id AND i.index_id = ic.index_id
--join sys.columns c ON ic.object_id = c.object_id AND c.column_id = ic.column_id
WHERE i.is_primary_key = 1
and i.name = 'XXXXX';
EDIT 2
The original question was a little unclear as pointed out by SqlZim. In case you want to ask by column name I have added that option. WARNING: This will return multiple tables if you have tables with the same column name as PK. This is most likely in larger databases and many compound keys (e.g. a financial system where something like FinancialYear is often part of many compound keys).
SELECT
s.name AS schema_name,
o.name AS table_name
--, *
FROM sys.objects o
join sys.schemas s on s.schema_id = o.schema_id
join sys.indexes i on i.object_id = o.object_id
join sys.index_columns ic ON i.object_id = ic.object_id AND i.index_id = ic.index_id
join sys.columns c ON ic.object_id = c.object_id AND c.column_id = ic.column_id
WHERE i.is_primary_key = 1
and c.name = 'PROGRAM_YEAR';

Calculate number of primary and secondary key columns

Is there a tool or query that will give me output as the total number of primary and secondary keys in a database table?
UPDATE ANSWER
Please note that secondary key is different from foreign key.
So count of no. of primary keys is possible in 2 ways:-
SELECT *
FROM sys.indexes i
INNER JOIN sys.tables t ON i.object_id = t.object_id AND
t.type = 'U'
LEFT JOIN sys.extended_properties AS EP ON EP.major_id = T.[object_id]
where is_primary_key=1
OR
SELECT COUNT(*) AS 'PRIMARY_KEY_CONSTRAINT'
FROM sys.objects
WHERE type_desc IN ('PRIMARY_KEY_CONSTRAINT')
To count no. of secondary keys use:
SELECT *
FROM sys.indexes i
INNER JOIN sys.tables t ON i.object_id = t.object_id AND
t.type = 'U'
LEFT JOIN sys.extended_properties AS EP ON EP.major_id = T.[object_id]
where is_unique=1 and is_primary_key=0
USE database
SELECT OBJECT_NAME(OBJECT_ID) AS NameofConstraint,
SCHEMA_NAME(schema_id) AS SchemaName,
OBJECT_NAME(parent_object_id) AS TableName
FROM sys.objects
WHERE type_desc IN ('PRIMARY_KEY_CONSTRAINT')
SELECT OBJECT_NAME(OBJECT_ID) AS NameofConstraint,
SCHEMA_NAME(schema_id) AS SchemaName,
OBJECT_NAME(parent_object_id) AS TableName
FROM sys.objects
WHERE type_desc IN ('FOREIGN_KEY_CONSTRAINT')
Simple count
SELECT COUNT(*) AS 'PRIMARY_KEY_CONSTRAINT'
FROM sys.objects
WHERE type_desc IN ('PRIMARY_KEY_CONSTRAINT')
SELECT COUNT(*) AS 'FOREIGN_KEY_CONSTRAINT'
FROM sys.objects
WHERE type_desc IN ('FOREIGN_KEY_CONSTRAINT')
The tool is SQL and this is another method to get what you want. A bit more complex then #kevchadders, but this way you can also make a listing of column names, types, etc
Count Foreign keys
SELECT count(*) from
INFORMATION_SCHEMA.TABLE_CONSTRAINTS Tab,
INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE Col
WHERE
Col.Constraint_Name = Tab.Constraint_Name
AND Col.Table_Name = Tab.Table_Name
AND Constraint_Type in ( 'FOREIGN KEY')
AND Col.Table_Name in (select name from sysobjects where xtype = 'U')
Count Pirmairy keys
SELECT count(*) from
INFORMATION_SCHEMA.TABLE_CONSTRAINTS Tab,
INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE Col
WHERE
Col.Constraint_Name = Tab.Constraint_Name
AND Col.Table_Name = Tab.Table_Name
AND Constraint_Type in ('PRIMARY KEY')
AND Col.Table_Name in (select name from sysobjects where xtype = 'U')
For all tables, show the PK and FK
FK
SELECT *, Col.Column_Name from
INFORMATION_SCHEMA.TABLE_CONSTRAINTS Tab,
INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE Col
WHERE
Col.Constraint_Name = Tab.Constraint_Name
AND Col.Table_Name = Tab.Table_Name
AND Constraint_Type in ('PRIMARY KEY', 'FOREIGN KEY')
AND Col.Table_Name in (select name from sysobjects where xtype = 'U')
You can try this
SELECT 'PRIMARY KEYS' AS KeyType, COUNT(*) AS Total
FROM sys.tables AS TB INNER JOIN
sys.key_constraints AS KC ON KC.parent_object_id = TB.object_id
GROUP BY KC.type
UNION
SELECT 'FOREIGN KEYS' AS KeyType, COUNT(*) AS Total
FROM sys.tables AS TB INNER JOIN
sys.foreign_keys AS FK ON FK.referenced_object_id = TB.object_id
GROUP BY FK.type

How to get table columns according its schema and table name?

I want to get ColumnName and it's datatype and is_identity for each column of different databases for specific table and schema.
I use following code but SCHEMA_NAME is for current database but I want to run this query from master or another database.
How to check schema name?
SELECT
c.name AS column_name, tp.name as data_type, c.is_identity iden
FROM
DatabaseName.sys.tables AS t
INNER JOIN
DatabaseName.sys.columns c ON t.OBJECT_ID = c.OBJECT_ID
INNER JOIN
DatabaseName.sys.types tp ON c.user_type_id = tp.user_type_id
WHERE
t.name = 'PlaceType'
AND SCHEMA_NAME(t.schema_id) = 'Coding'
Instead of SCHEMA_NAME, use OBJECT_SCHEMA_NAME, like so:
SELECT c.name AS column_name,tp.name as data_type,c.is_identity iden FROM
DatabaseName.sys.tables AS t INNER JOIN
DatabaseName.sys.columns c ON t.OBJECT_ID = c.OBJECT_ID INNER JOIN
DatabaseName.sys.types tp ON c.user_type_id = tp.user_type_id where
t.name='PlaceType' and OBJECT_SCHEMA_NAME(t.object_id,DB_ID(Databasename))='Coding'
Just change the last condition like
and SCHEMA_NAME(t.schema_id) in (Select name from Sys.Databases where database_id > 4)

sql server 2008 - Integer columns with no foreign key

Having inherited a legacy Sql server database, I'd like to list by table all integer columns where there is no foreign key, on the basis that some will be missing an FK, and some will just be integer columns. Can anyone suggest a query to display this information? Clearly there's some human intervention involved here.
Thanks.
You can get it from information_schema. I would start with something like this:
SELECT * from INFORMATION_SCHEMA.COLUMNS c
LEFT JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE k
ON
c.TABLE_CATALOG = k.TABLE_CATALOG
AND c.TABLE_SCHEMA = k.TABLE_SCHEMA
AND c.TABLE_NAME = k.TABLE_NAME
AND c.COLUMN_NAME = k.COLUMN_NAME
WHERE c.DATA_TYPE in ('int') AND CONSTRAINT_NAME is null
this one uses sql-server-only views:
select so.name as TableName, col.name as ColumnName
from
sys.objects so
inner join sys.columns col on so.object_id = col.object_id and col.system_type_id in (48,52,56,127)
left outer join sys.foreign_key_columns fkc on fkc.parent_object_id = so.object_id and fkc.parent_column_id = col.column_id
where
so.type='U'
and fkc.constraint_column_id is null
order by so.name

Resources