getschema("foreignkeys") against SqlClient doesn't yield enough information - sql

I need two tables and two sets of fields, not the name of the foreign key and one of the table names. Does anyone know how to query SQL Server for complete foreign key information? Thanks!

This can be an involved venture. The GetSchema as well as INFORMATION_SCHEMA views are incomplete, leading to the need to query the sys views directly for authoritive info.
try running this against your db and learn what you can.
This is from a thought experiment that got out of hand ;-)
BEGIN -- Get a table full of PK and UQ columns
DECLARE #tbl_unique_key_columns TABLE ( -- contains PK and UQ indexes
table_schema NVARCHAR(128),
table_name NVARCHAR(128),
index_name NVARCHAR(128),
column_id INT,
column_name NVARCHAR(128),
is_primary_key BIT,
is_unique_constraint BIT,
is_unique BIT,
is_nullable BIT,
is_rowguidcol BIT,
is_identity BIT,
default_definition NVARCHAR(MAX),
user_type NVARCHAR(128),
table_object_id INT )
INSERT INTO #tbl_unique_key_columns ( table_schema, table_name, index_name, column_id, column_name, is_primary_key, is_unique_constraint, is_unique, is_nullable, is_rowguidcol, is_identity, default_definition, user_type, table_object_id )
-- selects PK and UQ indexes
SELECT S.name AS schema_name, T.name AS table_name, IX.name AS index_name, IC.column_id, C.name AS column_name, IX.is_primary_key, IX.is_unique_constraint, IX.is_unique, C.is_nullable, C.is_rowguidcol, C.is_identity, d.definition, tp.NAME, T.[object_id]
FROM sys.tables AS T
INNER JOIN sys.schemas AS S
ON T.schema_id = S.schema_id
INNER JOIN sys.indexes AS IX
ON T.object_id = IX.object_id
INNER JOIN sys.index_columns AS IC
ON IX.object_id = IC.object_id
AND IX.index_id = IC.index_id
INNER JOIN sys.columns AS C
ON IC.column_id = C.column_id
AND IC.object_id = C.OBJECT_ID
INNER JOIN sys.types AS tp
ON C.user_type_id = tp.user_type_id
LEFT OUTER JOIN sys.default_constraints AS d
ON T.object_id = d.parent_object_id
AND C.column_id = d.parent_column_id
WHERE ( IX.is_unique = 1 )
AND ( IX.is_unique = 1 )
ORDER BY schema_name, table_name, index_name, C.column_id
END
BEGIN -- Get a table full of FK columns
DECLARE #tbl_foreign_key_columns TABLE ( constraint_name NVARCHAR(128),
base_schema_name NVARCHAR(128),
base_table_name NVARCHAR(128),
base_column_id INT,
base_column_name NVARCHAR(128),
unique_schema_name NVARCHAR(128),
unique_table_name NVARCHAR(128),
unique_column_id INT,
unique_column_name NVARCHAR(128),
base_object_id INT,
unique_object_id INT )
INSERT INTO #tbl_foreign_key_columns ( constraint_name, base_schema_name, base_table_name, base_column_id, base_column_name, unique_schema_name, unique_table_name, unique_column_id, unique_column_name, base_object_id, unique_object_id )
SELECT FK.name AS constraint_name, S.name AS base_schema_name, T.name AS base_table_name, C.column_id AS base_column_id, C.name AS base_column_name, US.name AS unique_schema_name, UT.name AS unique_table_name, UC.column_id AS unique_column_id, UC.name AS unique_column_name, T.[object_id], UT.[object_id]
FROM sys.tables AS T
INNER JOIN sys.schemas AS S
ON T.schema_id = S.schema_id
INNER JOIN sys.foreign_keys AS FK
ON T.object_id = FK.parent_object_id
INNER JOIN sys.foreign_key_columns AS FKC
ON FK.object_id = FKC.constraint_object_id
INNER JOIN sys.columns AS C
ON FKC.parent_object_id = C.object_id
AND FKC.parent_column_id = C.column_id
INNER JOIN sys.columns AS UC
ON FKC.referenced_object_id = UC.object_id
AND FKC.referenced_column_id = UC.column_id
INNER JOIN sys.tables AS UT
ON FKC.referenced_object_id = UT.object_id
INNER JOIN sys.schemas AS US
ON UT.schema_id = US.schema_id
ORDER BY base_schema_name, base_table_name
END
SELECT * FROM #tbl_unique_key_columns
SELECT * from #tbl_foreign_key_columns

Related

How to identify Foreign Keys from sys tables in SQL Server?

I used the following query to return Primary Keys of two tables. Is there a similar way to query for the Foreign Keys? I am not familiar with creating DBs but I dont see any Foreign Keys defined in the Object Explorer in SSMS. Thanks
select schema_name(tab.schema_id) as [schema_name],
pk.[name] as pk_name,
ic.index_column_id as column_id,
col.[name] as column_name,
tab.[name] as table_name
from sys.tables tab
inner join sys.indexes pk
on tab.object_id = pk.object_id
and pk.is_primary_key = 1
inner join sys.index_columns ic
on ic.object_id = pk.object_id
and ic.index_id = pk.index_id
inner join sys.columns col
on pk.object_id = col.object_id
and col.column_id = ic.column_id
where tab.name = 'custtable' or tab.name = 'custtrans'
order by schema_name(tab.schema_id),
pk.[name],
ic.index_column_id
Here is the output, but I need this to return Foreign Keys for these two tables.
schema_name pk_name column_id column_name table_name
dbo I_077ACCOUNTIDX 1 ACCOUNTNUM CUSTTABLE
dbo I_077ACCOUNTIDX 2 DATAAREAID CUSTTABLE
dbo I_077ACCOUNTIDX 3 PARTITION CUSTTABLE
dbo I_078RECID 1 RECID CUSTTRANS
Does this work for you? (This handles multi-key references by displaying them as comma-separated lists of columns, just FYI):
SELECT fkeys.[name] AS FKName,
OBJECT_NAME(fkeys.parent_object_id) AS TableName,
(SELECT STUFF((SELECT ',' + c.[name]
FROM sys.foreign_keys fk INNER JOIN sys.tables t ON fk.parent_object_id = t.object_id
INNER JOIN sys.columns as c ON t.object_id = c.object_id
INNER JOIN sys.foreign_key_columns AS fc ON c.column_id = fc.parent_column_id
AND fc.constraint_object_id = fk.object_id
AND fc.parent_object_id = fk.parent_object_id
WHERE fk.[name] = fkeys.[name]
FOR XML PATH ('')), 1, 1, '')) AS FKFolumns,
OBJECT_NAME(fkeys.referenced_object_id) AS ReferencedTableName,
(SELECT STUFF((SELECT ',' + c.[name]
FROM sys.foreign_keys fk INNER JOIN sys.tables t ON fk.referenced_object_id = t.object_id
INNER JOIN sys.columns as c ON t.object_id = c.object_id
INNER JOIN sys.foreign_key_columns AS fc ON c.column_id = fc.referenced_column_id
AND fc.constraint_object_id = fk.object_id
AND fc.referenced_object_id = fk.referenced_object_id
WHERE fk.[name] = fkeys.[name]
FOR XML PATH ('')), 1, 1, '')) AS ReferencedFKFolumns
FROM sys.foreign_keys fkeys
ORDER BY FKName;

How can you retrieve relationsships from a MSSQL database

I'm getting data from my MS-SQL 2016 Database. To determine the type of input fields, I need to know if there are any relations set up for any of my retrieved columns. I need this information to switch between input-fields and dropdown-menus.
I've already looked up in microsofts documentation (https://learn.microsoft.com/de-de/sql/relational-databases/system-catalog-views/sys-sql-dependencies-transact-sql?view=sql-server-2017) but couldn't find any sys-table containing the information I need. Am I even looking at the right place?
This may help.
;WITH Relationship
AS(
SELECT
ROW_NUMBER() OVER(ORDER BY fk.name) as Id,
CAST(fk.name as NVARCHAR(250)) as RelationName,
CAST(tr.name as NVARCHAR(250)) as ParentTable,
CAST((tr.name+'.'+cr.name) as NVARCHAR(250)) as ParentColumn,
CAST(tp.name as NVARCHAR(250)) as ReferencedTable,
CAST((tp.name+'.'+cp.name) as NVARCHAR(250)) as ReferencedColumn
FROM
sys.foreign_keys fk
INNER JOIN
sys.tables tp ON fk.parent_object_id = tp.object_id
INNER JOIN
sys.tables tr ON fk.referenced_object_id = tr.object_id
INNER JOIN
sys.foreign_key_columns fkc ON fkc.constraint_object_id = fk.object_id
INNER JOIN
sys.columns cp ON fkc.parent_column_id = cp.column_id AND fkc.parent_object_id = cp.object_id
INNER JOIN
sys.columns cr ON fkc.referenced_column_id = cr.column_id AND fkc.referenced_object_id = cr.object_id
--ORDER BY
-- tp.name, cp.column_id
)
SELECT * FROM Relationship
--Where ParentTable = 'Product' AND
--ReferencedTable='BillOfMaterials'
Use following two queries. Replace #schemaName, #tableName and #columnName as shown at the begging of the snippet.
DECLARE #schemaName AS SYSNAME= 'put here your schema name';
DECLARE #tableName AS SYSNAME= 'put here your table name';
DECLARE #columnName AS SYSNAME= 'put here your column name';
--The first one
SELECT f.name AS ForeignKey,
SCHEMA_NAME(f.SCHEMA_ID) SchemaName,
OBJECT_NAME(f.parent_object_id) AS TableName,
COL_NAME(fc.parent_object_id, fc.parent_column_id) AS ColumnName,
SCHEMA_NAME(o.SCHEMA_ID) ReferenceSchemaName,
OBJECT_NAME(f.referenced_object_id) AS ReferenceTableName,
COL_NAME(fc.referenced_object_id, fc.referenced_column_id) AS ReferenceColumnName
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.objects AS o ON o.OBJECT_ID = fc.referenced_object_id
WHERE SCHEMA_NAME(o.SCHEMA_ID) = #schemaName
AND OBJECT_NAME(f.referenced_object_id) = #tableName
AND COL_NAME(fc.parent_object_id, fc.parent_column_id) = #columnName
ORDER BY SCHEMA_NAME(f.SCHEMA_ID);
--The second one
SELECT f.name AS ForeignKey,
SCHEMA_NAME(f.SCHEMA_ID) SchemaName,
OBJECT_NAME(f.parent_object_id) AS TableName,
COL_NAME(fc.parent_object_id, fc.parent_column_id) AS ColumnName,
SCHEMA_NAME(o.SCHEMA_ID) ReferenceSchemaName,
OBJECT_NAME(f.referenced_object_id) AS ReferenceTableName,
COL_NAME(fc.referenced_object_id, fc.referenced_column_id) AS ReferenceColumnName
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.objects AS o ON o.OBJECT_ID = fc.referenced_object_id
WHERE OBJECT_NAME(F.PARENT_object_id) = #tableName
AND SCHEMA_NAME(F.SCHEMA_ID) = #schemaName
AND COL_NAME(fc.parent_object_id, fc.parent_column_id) = #columnName
ORDER BY SCHEMA_NAME(O.SCHEMA_ID),
OBJECT_NAME(f.referenced_object_id);

Query to pull all unique indexes from all tables in database using sql

Query to pull all unique indexes from all tables in database using sql. The output should display schema name, table name and column name.
I tried the following query:
SELECT
t.[name] AS TableName
,i.[name] AS IndexName
,c.[name] AS ColumnName
FROM sys.schemas s
INNER JOIN sys.tables t ON t.schema_id = s.schema_id
AND s.[name] = 'dbo'
INNER JOIN sys.columns c ON c.object_id = t.object_id
INNER JOIN sys.indexes i ON i.object_id = t.object_id
AND i.index_id > 0
AND i.is_primary_key = 0
AND i.is_unique = 1
INNER JOIN sys.index_columns ic ON ic.object_id = t.object_id
AND ic.column_id = c.column_id
but it displays TableName and IndexName multiple times if they have more than one unique index column.
It want to display:
TableName IndexName ColumnName
Customers IX_customer_name FirstName, LastName
You can use the sp_MSforEachDB stored procedure:
EXECUTE master.sys.sp_MSforeachdb '
USE [?];
select db_name(), *
from sys.indexes
where is_unique = 1';
You can also exclude system databases by adding if db_id() > 4 begin end.

SQL server query to get the list of columns in a table along with Data types, NOT NULL, and PRIMARY KEY constraints

I need to write a query on SQL server to get the list of columns in a particular table, its associated data types (with length) and if they are not null. And I have managed to do this much.
But now i also need to get, in the same table, against a column - TRUE if that column is a primary key.
How do i do this?
My expected output is:
Column name | Data type | Length | isnull | Pk
To avoid duplicate rows for some columns, use user_type_id instead of system_type_id.
SELECT
c.name 'Column Name',
t.Name 'Data type',
c.max_length 'Max Length',
c.precision ,
c.scale ,
c.is_nullable,
ISNULL(i.is_primary_key, 0) 'Primary Key'
FROM
sys.columns c
INNER JOIN
sys.types t ON c.user_type_id = t.user_type_id
LEFT OUTER JOIN
sys.index_columns ic ON ic.object_id = c.object_id AND ic.column_id = c.column_id
LEFT OUTER JOIN
sys.indexes i ON ic.object_id = i.object_id AND ic.index_id = i.index_id
WHERE
c.object_id = OBJECT_ID('YourTableName')
Just replace YourTableName with your actual table name - works for SQL Server 2005 and up.
In case you are using schemas, replace YourTableName by YourSchemaName.YourTableName where YourSchemaName is the actual schema name and YourTableName is the actual table name.
The stored procedure sp_columns returns detailed table information.
exec sp_columns MyTable
You could use the query:
select COLUMN_NAME, DATA_TYPE, CHARACTER_MAXIMUM_LENGTH,
NUMERIC_PRECISION, DATETIME_PRECISION,
IS_NULLABLE
from INFORMATION_SCHEMA.COLUMNS
where TABLE_NAME='TableName'
to get all the metadata you require except for the Pk information.
In SQL 2012 you can use:
EXEC sp_describe_first_result_set N'SELECT * FROM [TableName]'
This will give you the column names along with their properties.
Try this:
select COLUMN_NAME, DATA_TYPE, CHARACTER_MAXIMUM_LENGTH, IS_NULLABLE
from INFORMATION_SCHEMA.COLUMNS IC
where TABLE_NAME = 'tablename' and COLUMN_NAME = 'columnname'
To ensure you obtain the right length you would need to consider unicode types as a special case. See code below.
For further information see: https://msdn.microsoft.com/en-us/library/ms176106.aspx
SELECT
c.name 'Column Name',
t.name,
t.name +
CASE WHEN t.name IN ('char', 'varchar','nchar','nvarchar') THEN '('+
CASE WHEN c.max_length=-1 THEN 'MAX'
ELSE CONVERT(VARCHAR(4),
CASE WHEN t.name IN ('nchar','nvarchar')
THEN c.max_length/2 ELSE c.max_length END )
END +')'
WHEN t.name IN ('decimal','numeric')
THEN '('+ CONVERT(VARCHAR(4),c.precision)+','
+ CONVERT(VARCHAR(4),c.Scale)+')'
ELSE '' END
as "DDL name",
c.max_length 'Max Length in Bytes',
c.precision ,
c.scale ,
c.is_nullable,
ISNULL(i.is_primary_key, 0) 'Primary Key'
FROM
sys.columns c
INNER JOIN
sys.types t ON c.user_type_id = t.user_type_id
LEFT OUTER JOIN
sys.index_columns ic ON ic.object_id = c.object_id AND ic.column_id = c.column_id
LEFT OUTER JOIN
sys.indexes i ON ic.object_id = i.object_id AND ic.index_id = i.index_id
WHERE
c.object_id = OBJECT_ID('YourTableName')
I am a little bit surprised nobody mentioned
sp_help 'mytable'
Expanding on Alex's answer, you can do this to get the PK constraint
Select C.COLUMN_NAME, C.DATA_TYPE, C.CHARACTER_MAXIMUM_LENGTH, C.NUMERIC_PRECISION, C.IS_NULLABLE, TC.CONSTRAINT_NAME
From INFORMATION_SCHEMA.COLUMNS As C
Left Join INFORMATION_SCHEMA.TABLE_CONSTRAINTS As TC
On TC.TABLE_SCHEMA = C.TABLE_SCHEMA
And TC.TABLE_NAME = C.TABLE_NAME
And TC.CONSTRAINT_TYPE = 'PRIMARY KEY'
Where C.TABLE_NAME = 'Table'
I must have missed that you want a flag to determine if the given column was part of the PK instead of the name of the PK constraint. For that you would use:
Select C.COLUMN_NAME, C.DATA_TYPE, C.CHARACTER_MAXIMUM_LENGTH
, C.NUMERIC_PRECISION, C.NUMERIC_SCALE
, C.IS_NULLABLE
, Case When Z.CONSTRAINT_NAME Is Null Then 0 Else 1 End As IsPartOfPrimaryKey
From INFORMATION_SCHEMA.COLUMNS As C
Outer Apply (
Select CCU.CONSTRAINT_NAME
From INFORMATION_SCHEMA.TABLE_CONSTRAINTS As TC
Join INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE As CCU
On CCU.CONSTRAINT_NAME = TC.CONSTRAINT_NAME
Where TC.TABLE_SCHEMA = C.TABLE_SCHEMA
And TC.TABLE_NAME = C.TABLE_NAME
And TC.CONSTRAINT_TYPE = 'PRIMARY KEY'
And CCU.COLUMN_NAME = C.COLUMN_NAME
) As Z
Where C.TABLE_NAME = 'Table'
Throwing another answer into the ring, this will give you those columns and more:
SELECT col.TABLE_CATALOG AS [Database]
, col.TABLE_SCHEMA AS Owner
, col.TABLE_NAME AS TableName
, col.COLUMN_NAME AS ColumnName
, col.ORDINAL_POSITION AS OrdinalPosition
, col.COLUMN_DEFAULT AS DefaultSetting
, col.DATA_TYPE AS DataType
, col.CHARACTER_MAXIMUM_LENGTH AS MaxLength
, col.DATETIME_PRECISION AS DatePrecision
, CAST(CASE col.IS_NULLABLE
WHEN 'NO' THEN 0
ELSE 1
END AS bit)AS IsNullable
, COLUMNPROPERTY(OBJECT_ID('[' + col.TABLE_SCHEMA + '].[' + col.TABLE_NAME + ']'), col.COLUMN_NAME, 'IsIdentity')AS IsIdentity
, COLUMNPROPERTY(OBJECT_ID('[' + col.TABLE_SCHEMA + '].[' + col.TABLE_NAME + ']'), col.COLUMN_NAME, 'IsComputed')AS IsComputed
, CAST(ISNULL(pk.is_primary_key, 0)AS bit)AS IsPrimaryKey
FROM INFORMATION_SCHEMA.COLUMNS AS col
LEFT JOIN(SELECT SCHEMA_NAME(o.schema_id)AS TABLE_SCHEMA
, o.name AS TABLE_NAME
, c.name AS COLUMN_NAME
, i.is_primary_key
FROM sys.indexes AS i JOIN sys.index_columns AS ic ON i.object_id = ic.object_id
AND i.index_id = ic.index_id
JOIN sys.objects AS o ON i.object_id = o.object_id
LEFT JOIN sys.columns AS c ON ic.object_id = c.object_id
AND c.column_id = ic.column_id
WHERE i.is_primary_key = 1)AS pk ON col.TABLE_NAME = pk.TABLE_NAME
AND col.TABLE_SCHEMA = pk.TABLE_SCHEMA
AND col.COLUMN_NAME = pk.COLUMN_NAME
WHERE col.TABLE_NAME = 'YourTableName'
AND col.TABLE_SCHEMA = 'dbo'
ORDER BY col.TABLE_NAME, col.ORDINAL_POSITION;
SELECT COLUMN_NAME, IS_NULLABLE, DATA_TYPE, CHARACTER_MAXIMUM_LENGTH FROM information_schema.columns WHERE table_name = '<name_of_table_or_view>'
Run SELECT * in the above statement to see what information_schema.columns returns.
This question has been previously answered - https://stackoverflow.com/a/11268456/6169225
wite the table name in the query editor select the name and press Alt+F1 and it will bring all the information of the table.
IF EXISTS (SELECT 1 FROM INFORMATION_SCHEMA.TABLES
WHERE TABLE_TYPE = 'BASE TABLE' AND TABLE_NAME = 'Table')
BEGIN
SELECT COLS.COLUMN_NAME, COLS.DATA_TYPE, COLS.CHARACTER_MAXIMUM_LENGTH,
(SELECT 'Yes' FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS TC JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE KCU
ON COLS.TABLE_NAME = TC.TABLE_NAME
AND TC.CONSTRAINT_TYPE = 'PRIMARY KEY'
AND KCU.TABLE_NAME = TC.TABLE_NAME
AND KCU.CONSTRAINT_NAME = TC.CONSTRAINT_NAME
AND KCU.COLUMN_NAME = COLS.COLUMN_NAME) AS KeyX
FROM INFORMATION_SCHEMA.COLUMNS COLS WHERE TABLE_NAME = 'Table' ORDER BY KeyX DESC, COLUMN_NAME
END
marc_s's answer is good but it has a flaw if the primary key column(s) appear in other indexes in that those columns will appear more than once. e.g.
Demo:
create table dbo.DummyTable
(
id int not null identity(0,1) primary key,
Msg varchar(80) null
);
create index NC_DummyTable_id ON DummyTable(id);
Here's my stored procedure to solve problem:
create or alter procedure dbo.GetTableColumns
(
#schemaname nvarchar(128),
#tablename nvarchar(128)
)
AS
BEGIN
SET NOCOUNT ON;
with ctePKCols as
(
select
i.object_id,
ic.column_id
from
sys.indexes i
join sys.index_columns ic ON i.object_id = ic.object_id AND i.index_id = ic.index_id
where
i.is_primary_key = 1
)
SELECT
c.name AS column_name,
t.name AS typename,
c.max_length AS MaxLength,
c.precision,
c.scale,
c.is_nullable,
is_primary_key = CASE WHEN ct.column_id IS NOT NULL THEN 1 ELSE 0 END
FROM
sys.columns c
JOIN sys.types t ON t.user_type_id = c.user_type_id
LEFT JOIN ctePKCols ct ON ct.column_id = c.column_id AND ct.object_id = c.object_id
WHERE
c.object_ID = OBJECT_ID(quotename(#schemaname) + '.' + quotename(#tablename))
END
GO
exec dbo.GetTableColumns 'dbo', 'DummyTable'
Find combine result for Datatype and Length and is nullable in form of "NULL" and "Not null" Use below query.
SELECT c.name AS 'Column Name',
t.name + '(' + cast(c.max_length as varchar(50)) + ')' As 'DataType',
case
WHEN c.is_nullable = 0 then 'null' else 'not null'
END AS 'Constraint'
FROM sys.columns c
JOIN sys.types t
ON c.user_type_id = t.user_type_id
WHERE c.object_id = Object_id('TableName')
you will find result as shown below.
Thank you.
Query : EXEC SP_DESCRIBE_FIRST_RESULT_SET N'SELECT ANNUAL_INCOME FROM
[DB_NAME].[DBO].[EMPLOYEE]'
NOTE: IN SOME IDE BEFORE SELECT N IS WORKING OR, IN SOME IDE WITHOUT N IS WORKING
select
c.name as [column name],
t.name as [type name],
tbl.name as [table name]
from sys.columns c
inner join sys.types t
on c.system_type_id = t.system_type_id
inner join sys.tables tbl
on c.object_id = tbl.object_id
where
c.object_id = OBJECT_ID('YourTableName1')
and
t.name like '%YourSearchDataType%'
union
(select
c.name as [column name],
t.name as [type name],
tbl.name as [table name]
from sys.columns c
inner join sys.types t
on c.system_type_id = t.system_type_id
inner join sys.tables tbl
on c.object_id = tbl.object_id
where
c.object_id = OBJECT_ID('YourTableName2')
and
t.name like '%YourSearchDataType%')
union
(select
c.name as [column name],
t.name as [type name],
tbl.name as [table name]
from sys.columns c
inner join sys.types t
on c.system_type_id = t.system_type_id
inner join sys.tables tbl
on c.object_id = tbl.object_id
where
c.object_id = OBJECT_ID('YourTableName3')
and
t.name like '%YourSearchDataType%')
order by tbl.name
To search which column is in which table based on your search data type for three different table in one database. This query is expandable to 'n' tables.
Throwing another way to tackle the problem in SQL server.
My little script here should return the Column Name, Data Type, Is Nullable, Constraints, and Indexes Names.
You can also include any additional columns such as precision, scale...
(You will need to replace the DB name, Schema Name, and Table Name with yours)
.The Columns are returned in the same order you would get from 'select * from table'
USE DBA -- Replace Database Name with yours
DECLARE #SCHEMA VARCHAR(MAX)
DECLARE #TABLE_NAME VARCHAR(MAX)
DECLARE #SCHEMA_TABLE_NAME VARCHAR(MAX)
SET #SCHEMA = REPLACE(REPLACE('[SCHEMA NAME]', '[', ''), ']', '')--Replace Schema Name with yours
SET #TABLE_NAME = REPLACE(REPLACE('[TABLE NAME]', '[', ''), ']', '') --' Replace Table Name with yours
SET #SCHEMA_TABLE_NAME = #SCHEMA + '.' + #TABLE_NAME;
WITH SchemaColumns
AS (
SELECT C.COLUMN_NAME,
IS_NULLABLE,
DATA_TYPE,
CHARACTER_MAXIMUM_LENGTH,
C.ORDINAL_POSITION
FROM INFORMATION_SCHEMA.COLUMNS AS C
WHERE C.TABLE_SCHEMA = #SCHEMA
AND C.TABLE_NAME = #TABLE_NAME
),
SchemaConstraints
AS (
SELECT CN.COLUMN_NAME,
CC.CONSTRAINT_TYPE
FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS AS CC
INNER JOIN INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE AS CN ON CC.CONSTRAINT_NAME = CC.CONSTRAINT_NAME
WHERE CC.TABLE_SCHEMA = #SCHEMA
AND CC.TABLE_NAME = #TABLE_NAME
),
SchemaIndex
AS (
SELECT I.name AS index_name,
COL_NAME(IC.object_id, IC.column_id) AS column_name,
IC.index_column_id,
IC.key_ordinal,
IC.is_included_column
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
WHERE I.object_id = OBJECT_ID(#SCHEMA_TABLE_NAME)
)
SELECT ISNULL(SchemaColumns.COLUMN_NAME, '') "Column Name",
CASE
WHEN SchemaColumns.CHARACTER_MAXIMUM_LENGTH IS NULL
THEN UPPER(ISNULL(SchemaColumns.DATA_TYPE, ''))
ELSE CONCAT (
UPPER(ISNULL(SchemaColumns.DATA_TYPE, '')),
'(',
CAST(SchemaColumns.CHARACTER_MAXIMUM_LENGTH AS VARCHAR(50)),
')'
)
END "Data Type",
SchemaColumns.IS_NULLABLE "Is Nullable",
ISNULL(SchemaConstraints.CONSTRAINT_TYPE, '-') "Constraints",
ISNULL(STRING_AGG(CONVERT(NVARCHAR(max), SchemaIndex.INDEX_NAME), CHAR(13)), '-') "Indexes Names"
FROM SchemaColumns
LEFT JOIN SchemaConstraints ON SchemaConstraints.COLUMN_NAME = SchemaColumns.COLUMN_NAME
LEFT JOIN SchemaIndex ON SchemaColumns.COLUMN_NAME = SchemaIndex.COLUMN_NAME
GROUP BY SchemaColumns.COLUMN_NAME,
SchemaColumns.DATA_TYPE,
SchemaColumns.CHARACTER_MAXIMUM_LENGTH,
SchemaColumns.IS_NULLABLE,
SchemaConstraints.CONSTRAINT_TYPE,
SchemaColumns.ORDINAL_POSITION
ORDER BY SchemaColumns.ORDINAL_POSITION
SELECT
T.NAME AS [TABLE NAME]
,C.NAME AS [COLUMN NAME]
,P.NAME AS [DATA TYPE]
,P.MAX_LENGTH AS [Max_SIZE]
,C.[max_length] AS [ActualSizeUsed]
,CAST(P.PRECISION AS VARCHAR) +'/'+ CAST(P.SCALE AS VARCHAR) AS [PRECISION/SCALE]
FROM SYS.OBJECTS AS T
JOIN SYS.COLUMNS AS C
ON T.OBJECT_ID = C.OBJECT_ID
JOIN SYS.TYPES AS P
ON C.SYSTEM_TYPE_ID = P.SYSTEM_TYPE_ID
AND C.[user_type_id] = P.[user_type_id]
WHERE T.TYPE_DESC='USER_TABLE'
AND T.name = 'InventoryStatus'
ORDER BY 2
There is no primary key here, but this can help other users who would just like to have a table name with field name and basic field properties
USE [**YourDB**]
GO
SELECT tbl.name, fld.[Column Name],fld.[Constraint],fld.DataType
FROM sys.all_objects as tbl left join
(SELECT c.OBJECT_ID, c.name AS 'Column Name',
t.name + '(' + cast(c.max_length as varchar(50)) + ')' As 'DataType',
case
WHEN c.is_nullable = 0 then 'null' else 'not null'
END AS 'Constraint'
FROM sys.columns c
JOIN sys.types t
ON c.user_type_id = t.user_type_id
) as fld on tbl.OBJECT_ID = fld.OBJECT_ID
WHERE ( tbl.[type]='U' and tbl.[is_ms_shipped] = 0)
ORDER BY tbl.[name],fld.[Column Name]
GO
I just made marc_s "presentation ready":
SELECT
c.name 'Column Name',
t.name 'Data type',
IIF(t.name = 'nvarchar', c.max_length / 2, c.max_length) 'Max Length',
c.precision 'Precision',
c.scale 'Scale',
IIF(c.is_nullable = 0, 'No', 'Yes') 'Nullable',
IIF(ISNULL(i.is_primary_key, 0) = 0, 'No', 'Yes') 'Primary Key'
FROM
sys.columns c
INNER JOIN
sys.types t ON c.user_type_id = t.user_type_id
LEFT OUTER JOIN
sys.index_columns ic ON ic.object_id = c.object_id AND ic.column_id = c.column_id
LEFT OUTER JOIN
sys.indexes i ON ic.object_id = i.object_id AND ic.index_id = i.index_id
WHERE
c.object_id = OBJECT_ID('YourTableName')

How to determine the primary key for a table in SQL Server?

What I'd like to be able to do in SQL Server 2005 somehow is with a table name as input determine all the fields that make up the primary key. sp_columns doesn't seem to have this field. Any ideas as to where to look?
I use this in a code generator I wrote to get the primary key:
SELECT i.name AS IndexName,
OBJECT_NAME(ic.OBJECT_ID) AS TableName,
COL_NAME(ic.OBJECT_ID,ic.column_id) AS ColumnName,
c.is_identity, c.user_type_id, CAST(c.max_length AS int) AS max_length,
CAST(c.precision AS int) AS precision, CAST(c.scale AS int) AS scale
FROM sys.indexes AS i
INNER JOIN sys.index_columns AS ic
INNER JOIN sys.columns AS c ON ic.object_id = c.object_id AND ic.column_id = c.column_id
ON i.OBJECT_ID = ic.OBJECT_ID AND i.index_id = ic.index_id
WHERE i.is_primary_key = 1 AND ic.OBJECT_ID = OBJECT_ID('dbo.YourTableNameHere')
ORDER BY OBJECT_NAME(ic.OBJECT_ID), ic.key_ordinal
Actually, the primary key is something else than the indexes on the table. Is also something else than the clustered index. Is a constraint, so the proper place to look for it is sys.key_constraints:
select ic.key_ordinal, cl.name, ic.is_descending_key
from sys.key_constraints c
join sys.indexes i on c.parent_object_id = i.object_id
and c.unique_index_id = i.index_id
join sys.index_columns ic on ic.object_id = i.object_id
and ic.index_id = i.index_id
join sys.columns cl on cl.object_id = i.object_id
and ic.column_id = cl.column_id
where c.type = 'PK'
and 0 = ic.is_included_column
and i.object_id = object_id('<tablename>')
order by ic.key_ordinal
-- ANSI SQL compatible and works from SQL70 onwards:
select kcu.TABLE_SCHEMA, kcu.TABLE_NAME, kcu.CONSTRAINT_NAME, tc.CONSTRAINT_TYPE, kcu.COLUMN_NAME, kcu.ORDINAL_POSITION
from INFORMATION_SCHEMA.TABLE_CONSTRAINTS as tc
join INFORMATION_SCHEMA.KEY_COLUMN_USAGE as kcu
on kcu.CONSTRAINT_SCHEMA = tc.CONSTRAINT_SCHEMA
and kcu.CONSTRAINT_NAME = tc.CONSTRAINT_NAME
and kcu.TABLE_SCHEMA = tc.TABLE_SCHEMA
and kcu.TABLE_NAME = tc.TABLE_NAME
where tc.CONSTRAINT_TYPE in ( 'PRIMARY KEY', 'UNIQUE' )
order by kcu.TABLE_SCHEMA, kcu.TABLE_NAME, tc.CONSTRAINT_TYPE, kcu.CONSTRAINT_NAME, kcu.ORDINAL_POSITION;
-- SQL Server 2005 specific:
select s.name as TABLE_SCHEMA, t.name as TABLE_NAME
, k.name as CONSTRAINT_NAME, k.type_desc as CONSTRAINT_TYPE
, c.name as COLUMN_NAME, ic.key_ordinal AS ORDINAL_POSITION
from sys.key_constraints as k
join sys.tables as t
on t.object_id = k.parent_object_id
join sys.schemas as s
on s.schema_id = t.schema_id
join sys.index_columns as ic
on ic.object_id = t.object_id
and ic.index_id = k.unique_index_id
join sys.columns as c
on c.object_id = t.object_id
and c.column_id = ic.column_id
order by TABLE_SCHEMA, TABLE_NAME, CONSTRAINT_TYPE, CONSTRAINT_NAME, ORDINAL_POSITION;
Try This:
SELECT *
FROM INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE
WHERE table_name = 'your_table_name'
AND constraint_name LIKE 'PK%'
select *
from information_schema.Table_Constraints
where Table_Name = #tableName
See this MSDN Listing for Table Constraints.
I normally find that...
sp_help <table>
gives me all I need to know about a table (including index information).
In SQL2005 this brings back a row that names the primary key and then gives a list of the column under "index_keys"
sp_help myTable
I ended up using this...
select cu.constraint_catalog,
cu.constraint_schema,
cu.table_name,
cu.constraint_name,
constraint_type,
column_name,
ordinal_position
from information_schema.key_column_usage cu
join information_schema.table_constraints as tc
on tc.constraint_catalog = cu.constraint_catalog and
tc.constraint_schema = cu.constraint_schema and
tc.constraint_name = cu.constraint_name and
tc.table_name = cu.table_name
where cu.table_name = 'table_name_goes_here'
order by constraint_name, ordinal_position