Table Name, Column Name, Column Position, Data Type, Domain Name (user defined data type name), Length (in characters for nvarchar/nchar please), Is it nullable, Is it computed, Referenced Table Name, Referenced Column Name, Is it part of the primary key
I enforce that the schema allows a column to reference at most one column in one other table, so the "referenced" columns will either be null or contain at most one value. I've constructed this so far:
select o.name TableName
, c.name ColumnName
, fko.name ReferenceTableName
, fkc.name ReferenceColumnName
, COALESCE(t.name, t.name) ColumnType
, c.prec ColumnLength
, c.isnullable IsNullable
, c.iscomputed IsComputed
, c.colid ColumnOrder
from syscolumns c
inner join sysobjects o on c.id=o.id
inner join systypes t on c.xusertype=t.xusertype
left outer join sysforeignkeys fk on c.id=fk.fkeyid and c.colid=fk.fkey
left outer join sysobjects fko on fk.rkeyid=fko.id
left outer join syscolumns fkc on fk.rkeyid=fkc.id and fk.rkey=fkc.colid
where o.xtype='U'
Where can I find out if a column is a primary key?I don't see a way for you to get all of the information you are looking for out of the Information_Schema views, either.
I normally get the "is this a primary key?" information out of the Information_Schema.Key_Column_Usage view joined on the Information_Schema.Table_Constraints view. I am not certain of the underlying sys tables (althought perusal of those views will obviously tell you). Below is some incomplete code showing how I'd join the KCU and TC views:
SELECT
Tables.Table_Name AS [Table Name],
Columns.Column_Name AS [Column Name],
Columns.Ordinal_Position AS [Column Position],
CASE WHEN TC.Constraint_Name IS NULL Then 'No' Else 'Yes' END AS [Part of the Primary Key]
FROM
information_schema.tables AS Tables
LEFT OUTER JOIN
information_schema.columns AS Columns ON Tables.Table_Catalog = Columns.Table_Catalog AND Tables.Table_Schema = Columns.Table_Schema AND Tables.Table_Name = Columns.Table_name
LEFT OUTER JOIN
information_schema.key_column_usage AS KCU ON Tables.Table_Catalog = KCU.Table_Catalog AND Tables.Table_Schema = KCU.Table_Schema AND Columns.Column_Name = KCU.Column_Name
LEFT OUTER JOIN
information_schema.table_constraints AS TC ON Tables.Table_Catalog = TC.Table_Catalog AND Tables.Table_Schema = TC.Table_Schema AND KCU.Constraint_Name = TC.Constraint_Name AND TC.constraint_type = 'PRIMARY KEY'
Terri|||Thanks for the idea to look at the INFORMATION_SCHEMA.KEY_COLUMN_USAGE directly! You can execute "sp_helptext [INFORMATION_SCHEMA.KEY_COLUMN_USAGE]" if you want to see how this view is defined. It uses an undocumented table master.dbo.spt_values, but it did lead me to the sysindexkeys and sysindexes table as I was looking for documentation of the spt_values table.
Here is my solution, for anyone who is interested. I use only explicitly documented columns of sysXXX tables, so that hopefully it might work in SQL Server versions other than SQL Server 2000.
select o.name TableName
, c.name ColumnName
, t.name ColumnType
, c.prec ColumnLength
, CONVERT(bit, COALESCE(pko.id, 0)) IsKey
, CONVERT(bit, c.isnullable) IsNullable
, CONVERT(bit, c.iscomputed) IsComputed
, c.colid ColumnOrder
, fko.name ReferenceTableName
, fkc.name ReferenceColumnName
from syscolumns c
inner join sysobjects o on c.id=o.id
inner join systypes t on c.xusertype=t.xusertype
left outer join sysforeignkeys fk on c.id=fk.fkeyid and c.colid=fk.fkey
left outer join sysobjects fko on fk.rkeyid=fko.id
left outer join syscolumns fkc on fk.rkeyid=fkc.id and fk.rkey=fkc.colid
left outer join sysindexkeys ik on c.id=ik.id and c.colid=ik.colid
left outer join sysindexes i on ik.id=i.id and ik.indid=i.indid
left outer join sysobjects pko on c.id=pko.parent_obj and i.name=pko.name
where o.xtype='U'
This assumes that each column references at most one other column. If you have a column that references more than one column, you'll get a row for each referenced column due to the left outer joins. It is ok for more than one column to be part of a primary key. ColumnType is either the user defined data type or the system defined data type if the column was not specified with a user defined data type. ColumnLength is the length in characters for nvarchar and nchar, NULL for text, ntext and image, and the length in bytes for all other types. The IsKey, IsNullable and IsComputed columns are converted to bit type so that ASP.NET can automatically treat them as Boolean values.