Information schema and Primary Keys - sql-server

How do I just print out a 'primary key' for the column with the primary key?
I get 'primary key' for all the columns if the table has a primary key, instead of the one column with the primary key and the other columns as blank in keyType.
SELECT c.TABLE_NAME,
c.COLUMN_NAME,
c.DATA_TYPE,
c.Column_default,
c.character_maximum_length,
c.numeric_precision,
c.is_nullable,
CASE
WHEN u.CONSTRAINT_TYPE = 'PRIMARY KEY' THEN 'primary key'
ELSE ''
END AS KeyType
FROM INFORMATION_SCHEMA.COLUMNS as c
LEFT JOIN information_schema.table_constraints as u ON c.table_name = u.table_name
ORDER BY table_name

SELECT c.TABLE_NAME, c.COLUMN_NAME,c.DATA_TYPE, c.Column_default, c.character_maximum_length, c.numeric_precision, c.is_nullable
,CASE WHEN pk.COLUMN_NAME IS NOT NULL THEN 'PRIMARY KEY' ELSE '' END AS KeyType
FROM INFORMATION_SCHEMA.COLUMNS c
LEFT JOIN (
SELECT ku.TABLE_CATALOG,ku.TABLE_SCHEMA,ku.TABLE_NAME,ku.COLUMN_NAME
FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS AS tc
INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE AS ku
ON tc.CONSTRAINT_TYPE = 'PRIMARY KEY'
AND tc.CONSTRAINT_NAME = ku.CONSTRAINT_NAME
) pk
ON c.TABLE_CATALOG = pk.TABLE_CATALOG
AND c.TABLE_SCHEMA = pk.TABLE_SCHEMA
AND c.TABLE_NAME = pk.TABLE_NAME
AND c.COLUMN_NAME = pk.COLUMN_NAME
ORDER BY c.TABLE_SCHEMA,c.TABLE_NAME, c.ORDINAL_POSITION

As an addition, consider looking at:
sp_helptext N'sp_help'
Sometimes learning from the MS team is a great thing. :-)

a very small add to the first answer. It's possible to view in same time the MS_Description (or other extend properties)
SELECT c.TABLE_NAME, c.COLUMN_NAME,c.DATA_TYPE, c.Column_default, c.character_maximum_length, c.numeric_precision, c.is_nullable
,CASE WHEN pk.COLUMN_NAME IS NOT NULL THEN 'PRIMARY KEY' ELSE '' END AS KeyType, c.ORDINAL_POSITION
,convert(varchar(8000), ex.value) as coln
FROM INFORMATION_SCHEMA.COLUMNS c
LEFT JOIN (
SELECT ku.TABLE_CATALOG,ku.TABLE_SCHEMA,ku.TABLE_NAME,ku.COLUMN_NAME
FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS AS tc
INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE AS ku
ON tc.CONSTRAINT_TYPE = 'PRIMARY KEY'
AND tc.CONSTRAINT_NAME = ku.CONSTRAINT_NAME
) pk
ON c.TABLE_CATALOG = pk.TABLE_CATALOG
AND c.TABLE_SCHEMA = pk.TABLE_SCHEMA
AND c.TABLE_NAME = pk.TABLE_NAME
AND c.COLUMN_NAME = pk.COLUMN_NAME
outer apply ::fn_listextendedproperty('MS_Description', 'schema', 'dbo', 'table', c.TABLE_NAME, 'column', c.COLUMN_NAME) ex
ORDER BY c.TABLE_SCHEMA,c.TABLE_NAME, c.ORDINAL_POSITION

I've found this code below to be the simplest method to find the primary key for a table. It only requires a left outer join between the information_schema.columns table and the information_schema.key_column_usage table.
Select
col.column_name,
col.data_type,
col.ordinal_position,
col.is_nullable,
case when ky.COLUMN_NAME is null then 0 else 1 end as primary_key_flag
from <your-catalog>.Information_Schema.columns col
left outer join <your-catalog>.INFORMATION_SCHEMA.KEY_COLUMN_USAGE ky
on ky.COLUMN_NAME = col.COLUMN_NAME and ky.TABLE_NAME = col.TABLE_NAME
and ky.TABLE_CATALOG = col.TABLE_CATALOG and ky.table_name = col.table_name
where
col.TABLE_NAME = '<your-table-name>'
and col.table_catalog = '<your-catalog>';
Note: This code was built using SQL Server 2017 Express (14.0.1000) and after I created the primary key, I was able to see those values in the KEY_COLUMN_USAGE table. I also saw a record in the CONSTRAINT_TABLE_USAGE which identified the constraint_name, but I didn't find that to be a requirement in order to get the join into which revealed the primary key.
Final note: I'm just getting back into SQL server on a personal project after nearly a decade away from the DB (using MySQL), and so I'm nowhere near an expert on the subject.

Related

Primary Key Ordinal Number

Does anyone know how to get the Ordinal_Position of the column that contains the Primary Key in an SQL Server table?
Tested in SQL Server 2012. This is for a particular column:
SELECT
KU.ORDINAL_POSITION AS ORDINAL_POSITION
FROM
INFORMATION_SCHEMA.TABLE_CONSTRAINTS AS TC
INNER JOIN
INFORMATION_SCHEMA.KEY_COLUMN_USAGE AS KU ON TC.CONSTRAINT_TYPE = 'PRIMARY KEY'
AND TC.CONSTRAINT_NAME = KU.CONSTRAINT_NAME
AND ku.table_name = 'YourTable'
AND column_name = 'YourColumn'
And if you don't know column name, this gives you all columns in primary key
SELECT KU.ORDINAL_POSITION AS ORDINAL_POSITION
,column_name AS ColumnName
FROM
INFORMATION_SCHEMA.TABLE_CONSTRAINTS AS TC
INNER JOIN
INFORMATION_SCHEMA.KEY_COLUMN_USAGE AS KU ON TC.CONSTRAINT_TYPE = 'PRIMARY KEY'
AND TC.CONSTRAINT_NAME = KU.CONSTRAINT_NAME
AND ku.table_name = 'yourTable'
Take a look at this: https://msdn.microsoft.com/en-us/library/ms188348.aspx
Query the columns table, and set the "TABLE_NAME" = to the table you're after to get the ordinal position.
SELECT ordinal_position
FROM columns
WHERE table_name = 'MYTABLE'

How to print all along with their column names and primary keys?

This SQL query prints table name, column name and column type (Data, varchar, etc).
Table_name Column_name Data_type
SELECT T.TABLE_NAME,C.COLUMN_NAME,C.DATA_TYPE
FROM INFORMATION_SCHEMA.COLUMNS C
INNER JOIN INFORMATION_SCHEMA.TABLES T ON C.TABLE_NAME = T.TABLE_NAME
AND C.TABLE_SCHEMA = T.TABLE_SCHEMA
WHERE T.TABLE_TYPE = 'BASE TABLE'
How to change it so that it also prints if this column is a part of compound primary key (see below)?
Table_name Column_Name Is_Primary(y/n) Data_Type
Update: The suggested duplicate is a far cry, because it talks about a single table. The accepted answer resolved my question.
Constraint name and types are in INFORMATION_SCHEMA.TABLE_CONSTRAINTS and Column Name and Constraint Name are in INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE. So, basically you end up adding more JOINS.
SELECT
T.TABLE_NAME,
C.COLUMN_NAME,
C.DATA_TYPE,
CCU.Constraint_Name,
CASE TC.Constraint_Type
WHEN 'PRIMARY KEY' THEN 'Yes'
ELSE 'No'
END IsPrimaryKey
FROM INFORMATION_SCHEMA.COLUMNS C
INNER JOIN INFORMATION_SCHEMA.TABLES T
ON C.TABLE_NAME = T.TABLE_NAME
AND C.TABLE_SCHEMA = T.TABLE_SCHEMA
LEFT JOIN INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE CCU
ON CCU.TABLE_SCHEMA = T.TABLE_SCHEMA
AND CCU.TABLE_NAME = T.TABLE_NAME
AND CCU.COLUMN_NAME = C.COLUMN_NAME
LEFT JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS TC
ON CCU.Constraint_Name = TC.Constraint_Name
AND CCU.Table_Name = TC.Table_Name
AND CCU.TABLE_SCHEMA = TC.TABLE_SCHEMA
WHERE T.TABLE_TYPE = 'BASE TABLE'
ORDER BY T.TABLE_NAME, C.COLUMN_NAME

How can I find all the tables of db that contains primary key or particular column of a single table in Postgresql

How can I find all the tables of db that contains primary key or particular column of a single table in Postgresql Database....Means a column of a perticular table that is included in many tables either as foreign key or non - foreign key...column can be primary key or a non - primary key....
Use below Query to find particular column of a single table:
SELECT table_name
FROM information_schema.columns
WHERE table_schema = 'public'
AND column_name = 'YOUR_COLUMN_NAME'
Use below Query to find List of all the tables of db that contains primary key
SELECT t.table_catalog,
t.table_schema,
t.table_name,
kcu.constraint_name,
kcu.column_name,
kcu.ordinal_position
FROM INFORMATION_SCHEMA.TABLES t
LEFT JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS tc
ON tc.table_catalog = t.table_catalog
AND tc.table_schema = t.table_schema
AND tc.table_name = t.table_name
AND tc.constraint_type = 'PRIMARY KEY'
LEFT JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE kcu
ON kcu.table_catalog = tc.table_catalog
AND kcu.table_schema = tc.table_schema
AND kcu.table_name = tc.table_name
AND kcu.constraint_name = tc.constraint_name
WHERE t.table_schema NOT IN ('pg_catalog', 'information_schema')
ORDER BY t.table_catalog,
t.table_schema,
t.table_name,
kcu.constraint_name,
kcu.ordinal_position;
Use below Query to find List of table having Foreign Key in another Table
SELECT t.table_name as FK_Table, tc.constraint_name,tc.constraint_type,ccu.table_name as PK_Table
FROM INFORMATION_SCHEMA.TABLES t
INNER JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS tc
ON tc.table_catalog = t.table_catalog
AND tc.table_schema = t.table_schema
AND tc.table_name = t.table_name
INNER JOIN INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE ccu
ON ccu.constraint_name = tc.constraint_name
/* Remove comments for check based on CONSTRAINT'name OR 'PRIMARY_KEY' name */
--and ccu.constraint_name = 'CONSTRAINT_NAME'
--and AND ccu.column_name = 'COLUMN_NAME'
WHERE t.table_schema NOT IN ('pg_catalog', 'information_schema')

Get info (especial pk) of all column in a table

I try to get info of all column in a table
Example info about type, name column, especially info about primary key but it missing
I use
SELECT * FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME='tablename'
It's not contain info about primary key. How to get that thanks
How about something like
SELECT *
FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE
WHERE OBJECTPROPERTY(OBJECT_ID(constraint_name), 'IsPrimaryKey') = 1
AND table_name = 'TableName'
Also maybe try
SELECT i.name AS IndexName,
OBJECT_NAME(ic.OBJECT_ID) AS TableName,
COL_NAME(ic.OBJECT_ID,ic.column_id) AS ColumnName,
c.*
FROM sys.indexes AS i INNER JOIN
sys.index_columns AS ic ON i.OBJECT_ID = ic.OBJECT_ID
AND i.index_id = ic.index_id INNER JOIN
sys.columns c ON ic.object_id = c.object_id
AND ic.column_id = c.column_id
WHERE i.is_primary_key = 1
try with sp_help [tablename] it will give you primary key details
sp_help [tablename]
sp_help
Or if you need only details about primary key column try with Mr.Astander answer
SELECT *
FROM INFORMATION_SCHEMA.KEY_COLUMN_USAGE
WHERE OBJECTPROPERTY(OBJECT_ID(constraint_name), 'IsPrimaryKey') = 1
AND table_name = 'TableName'
You could retrieve primary key information and join it to INFORMATION_SCHEMA.COLUMNS and get primary key information with other columns. Please see the below query.
SELECT c.*,
CASE WHEN keys.COLUMN_NAME IS NULL
THEN 0
ELSE 1
END AS is_primary
FROM
INFORMATION_SCHEMA.COLUMNS c
LEFT OUTER JOIN (
SELECT col.COLUMN_NAME,col.TABLE_NAME
FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS tab
INNER JOIN INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE Col
ON Col.Constraint_Name = tab.Constraint_Name
AND Col.Table_Name = tab.Table_Name
WHERE Constraint_Type = 'PRIMARY KEY') keys
ON c.COLUMN_NAME=keys.COLUMN_NAME AND c.TABLE_NAME=keys.TABLE_NAME
ORDER BY c.TABLE_NAME
Try:
SELECT TC.TABLE_NAME, CU.CONSTRAINT_NAME, C.DATA_TYPE
FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS TC
INNER JOIN INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE CU
ON TC.CONSTRAINT_NAME = CU.CONSTRAINT_NAME
INNER JOIN INFORMATION_SCHEMA.COLUMNS C
ON CU.TABLE_NAME = C.TABLE_NAME AND CU.TABLE_SCHEMA = C.TABLE_SCHEMA AND C.COLUMN_NAME = CU.COLUMN_NAME
WHERE TC.TABLE_NAME = 'tablename' AND CONSTRAINT_TYPE = 'PRIMARY KEY'

How do I determine if a column is in the primary key of its table? (SQL Server)

I am currently using...
select Table_Name, Column_name, data_type, is_Nullable
from information_Schema.Columns
...to determine information about columns in a given database for the purposes of generating a DataAccess Layer.
From where can I retrieve information about if these columns are participants in the primary key of their table?
Here is one way (replace 'keycol' with the column name you are searching
for):
SELECT K.TABLE_NAME ,
K.COLUMN_NAME ,
K.CONSTRAINT_NAME
FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS AS C
JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE AS K ON C.TABLE_NAME = K.TABLE_NAME
AND C.CONSTRAINT_CATALOG = K.CONSTRAINT_CATALOG
AND C.CONSTRAINT_SCHEMA = K.CONSTRAINT_SCHEMA
AND C.CONSTRAINT_NAME = K.CONSTRAINT_NAME
WHERE C.CONSTRAINT_TYPE = 'PRIMARY KEY'
AND K.COLUMN_NAME = 'keycol';
Similarly, the following will give you information about all the tables and their keys, instead of information about specific columns. This way, you make sure you have all the columns of interest and know what they participate in. In order to see all keys (primary, foreign, unique), comment the WHERE clause.
SELECT K.TABLE_NAME, C.CONSTRAINT_TYPE, K.COLUMN_NAME, K.CONSTRAINT_NAME
FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS AS C
JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE AS K
ON C.TABLE_NAME = K.TABLE_NAME
AND C.CONSTRAINT_CATALOG = K.CONSTRAINT_CATALOG
AND C.CONSTRAINT_SCHEMA = K.CONSTRAINT_SCHEMA
AND C.CONSTRAINT_NAME = K.CONSTRAINT_NAME
WHERE C.CONSTRAINT_TYPE = 'PRIMARY KEY'
ORDER BY K.TABLE_NAME, C.CONSTRAINT_TYPE, K.CONSTRAINT_NAME
For your need, full outer join with INFORMATION_SCHEMA.COLUMNS and INFORMATION_SCHEMA.KEY_COLUMN_USAGE. At the select statement, add CONSTRAINT_NAME column from INFORMATION_SCHEMA.KEY_COLUMN_USAGE that will give you null or keyname.
select C.Table_Name, C.Column_name, data_type, is_Nullable, U.CONSTRAINT_NAME
from information_Schema.Columns C FULL OUTER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE U ON C.COLUMN_NAME = U.COLUMN_NAME
WHERE C.TABLE_NAME=#TABLENAME
this query return column with is primary key.
SELECT col.COLUMN_NAME ,
col.DATA_TYPE ,
col.CHARACTER_MAXIMUM_LENGTH ln ,
CAST(ISNULL(j.is_primary, 0) AS BIT) is_primary
FROM INFORMATION_SCHEMA.COLUMNS col
LEFT JOIN ( SELECT K.TABLE_NAME ,
K.COLUMN_NAME ,
CASE WHEN K.CONSTRAINT_NAME IS NULL THEN 0
WHEN K.CONSTRAINT_NAME IS NOT NULL THEN 1
END is_primary
FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS AS C
JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE AS K ON C.TABLE_NAME = K.TABLE_NAME
AND C.CONSTRAINT_CATALOG = K.CONSTRAINT_CATALOG
AND C.CONSTRAINT_SCHEMA = K.CONSTRAINT_SCHEMA
AND C.CONSTRAINT_NAME = K.CONSTRAINT_NAME
WHERE C.CONSTRAINT_TYPE = 'PRIMARY KEY'
AND C.TABLE_NAME = 'tablename'
) j ON col.COLUMN_NAME = j.COLUMN_NAME
WHERE col.TABLE_NAME = 'tablename'

Resources