We have all inherited bad data models. I have a data model where the FK constraint is going to a data type that isn't implicitly castable. For example, I have a VARCHAR reference column (constraintColumn) which has an FK relationship with an INT parent column (constrainedColumn).
SELECT
OBJECT_NAME(fk.constraint_object_id) KeyName
, t.name constrainedTable
, c.name constrainedColumn
, t2.name constraintTable
, c2.name constraintColumn
FROM
sys.foreign_key_columns AS fk
INNER JOIN
sys.tables AS t ON
fk.parent_object_id = t.object_id
INNER JOIN
sys.columns AS c ON
fk.parent_object_id = c.object_id
AND
fk.parent_column_id = c.column_id
INNER JOIN
sys.tables AS t2 ON
fk.referenced_object_id = t2.object_id
INNER JOIN
sys.columns AS c2 ON
fk.referenced_object_id = c2.object_id
AND
fk.constraint_column_id = c2.column_id
ORDER BY
t.name
, c.name;
How can I use sys.types or something else to determine which data types are implicitly castable?
Related
How can I get list of tables having primary key of DataType 'DateTime'?
I couldn't find any proper way to do it.
Based on the this query, I've updated query to meet your requirement :
select
t.name as TableName,
tc.name as ColumnName
from
sys.schemas s
inner join sys.tables t on s.schema_id=t.schema_id
inner join sys.indexes i on t.object_id=i.object_id
inner join sys.index_columns ic on i.object_id=ic.object_id
and i.index_id=ic.index_id
inner join sys.columns tc on ic.object_id=tc.object_id
and ic.column_id=tc.column_id
inner join sys.types ty on tc.system_type_id = ty.system_type_id
where i.is_primary_key=1 and ty.name = 'datetime'
I need to get a list of all foreign keys, which schema/table they belong to, which schema/table they reference, and the name of the column that is referenced. This is what I have so far but the column being returned is not correct. Any ideas?
select distinct
ParentSchema.name as PARENT_SCHEMA_NAME,
ParentTable.name as PARENT_TABLE_NAME,
TheSchema.name as TABLE_SCHEMA,
TheTable.name as TABLE_NAME,
fks.name as KEY_NAME ,
COL_NAME(ParentTable.OBJECT_ID,fkcs.constraint_column_id) as CHILD_COLUMN_NAME
from
sys.foreign_keys fks
inner join
Sys.foreign_key_columns fkcs
on
fks.parent_object_id = fkcs.parent_object_id
inner join
sys.tables TheTable
on
fks.parent_object_id = TheTable.object_id
inner join
sys.tables ParentTable
on
fks.referenced_object_id = ParentTable.object_id
inner join
sys.schemas TheSchema
on
TheTable.schema_id = TheSchema.schema_id
inner join
sys.schemas ParentSchema
on
ParentTable.schema_id = ParentSchema.schema_id
order by
fks.name
I use the following script for getting the information I need related to foreign keys, could be useful for you too:
SELECT KCU1.CONSTRAINT_NAME AS FK_CONSTRAINT_NAME
, KCU1.TABLE_NAME AS FK_TABLE_NAME
, KCU1.COLUMN_NAME AS FK_COLUMN_NAME
, KCU2.CONSTRAINT_NAME AS REFERENCED_CONSTRAINT_NAME
, KCU2.TABLE_NAME AS REFERENCED_TABLE_NAME
, KCU2.COLUMN_NAME AS REFERENCED_COLUMN_NAME
FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS AS RC
INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE AS KCU1 ON KCU1.CONSTRAINT_CATALOG = RC.CONSTRAINT_CATALOG AND KCU1.CONSTRAINT_SCHEMA = RC.CONSTRAINT_SCHEMA AND KCU1.CONSTRAINT_NAME = RC.CONSTRAINT_NAME
INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE AS 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
WHERE KCU1.TABLE_NAME = 'PurchaseOrders'
For the table PurchaseOrders, in the WideWorldImporters database it shows the following information:
You can check out all the columns included in the information_schema.referential_constraints and
information_schema.key_column_usage and then change the query to fit your needs.
I am trying to get names of columns with a specific type (so I can dynamically query the result). Code below seems to be getting me close (with i.e. type=56 standing for int) but it just seems to be incorrect. Not to mention that I've failed to find a good mapping from types to int representation.
SELECT c.system_type_id as type
FROM SYS.COLUMNS c
JOIN SYS.TABLES t ON c.object_id = t.object_id
WHERE t.name = 'MyTableName'
Thanks
You can find the mapping to types in the sys.types catalog view:
SELECT c.name as column_name, ty.name as type_name
FROM SYS.COLUMNS c
JOIN SYS.TABLES t ON c.object_id = t.object_id
JOIN SYS.TYPES ty ON c.system_type_id = ty.system_type_id
WHERE t.name = 'MyTableName'
SELECT
c.name 'Column Name',
t.Name 'Data type'
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('TableName')
Assuming you're using SQL Server you can do something like this;
DECLARE #DataType varchar(20); SET #DataType = 'int'
SELECT
o.name TableName
,c.name ColumnName
,t.name ColumnType
,t.max_length ColumnLength
FROM sys.columns c
JOIN sys.objects o
ON c.object_id = o.object_id
JOIN sys.types t
ON c.user_type_id = t.user_type_id
WHERE t.name LIKE '%' + #DataType + '%'
AND o.type_desc = 'USER_TABLE'
Just change the data type in the variable and it will give you a list like this
TableName ColumnName ColumnType ColumnLength
Employees empid int 4
Employees mgrid int 4
Suppliers supplierid int 4
Categories categoryid int 4
Products productid int 4
Products supplierid int 4
You can modify this to add in the table name if that's what you want to do.
i need list of tableName , columnName ,constraintsType and cascade type in sql server 2008 so i tried below query but cascade type is null
SELECT TB.name AS "TableName",CL.name AS
"ColumnName",KC.type,FK.delete_referential_action,FK.update_referential_action
FROM SYS.key_constraints KC JOIN SYS.tables TB ON
KC.parent_object_id=TB.object_id JOIN SYS.columns CL ON
KC.parent_object_id=CL.object_id LEFT JOIN SYS.foreign_keys FK ON FK.name = KC.name
I believe this is what you are looking for
SELECT
o1.name AS FK_table,
c1.name AS FK_column,
fk.name AS FK_name,
fk.type as FK_TYPE,
pk.name AS PK_name,
pk.type as PK_TYPE,
fk.delete_referential_action_desc AS Delete_Action,
fk.update_referential_action_desc AS Update_Action
FROM sys.objects o1
INNER JOIN sys.foreign_keys fk
ON o1.object_id = fk.parent_object_id
INNER JOIN sys.foreign_key_columns fkc
ON fk.object_id = fkc.constraint_object_id
INNER JOIN sys.columns c1
ON fkc.parent_object_id = c1.object_id
AND fkc.parent_column_id = c1.column_id
INNER JOIN sys.key_constraints pk
ON fk.referenced_object_id = pk.parent_object_id
AND fk.key_index_id = pk.unique_index_id
ORDER BY o1.name, fkc.constraint_column_id
I didn't try out your query as I don't a sql server in front of me but I believe you are missing a DMV and that is why your left join is returning nulls.
The following query returns a listing of all my database primary keys and additional columns.
SELECT *
FROM sysobjects AS s
WHERE xtype='pk'
None of the aforementioned additional columns are related to a primary key's identity, seed value, increment value, etc.
What query should I use, or how may I find all primary keys in a database and their identity and seed values?
UPDATED
(now uses identity_columns table instead of the IDENT_... functions)
SELECT object_name(i.object_id) tableName,
i.name indexName,
c.name columnName,
c.is_identity,
idc.seed_value,
idc.increment_value,
idc.last_value
FROM sys.indexes i
INNER JOIN sys.index_columns ic ON ic.object_id = i.object_id AND ic.index_id = i.index_id
INNER JOIN sys.columns c ON c.object_id = ic.object_id AND c.column_id = ic.column_id
LEFT OUTER JOIN sys.identity_columns idc ON idc.object_id = c.object_id AND idc.column_id = c.column_id
WHERE i.is_primary_key = 1
Here is an alternate answer b/c I combined selects and added create and modified dates for sorting and schema name for possible dupes between schemas b/c key names are unique:
SELECT schema_name = ( SELECT top 1 pk.CONSTRAINT_SCHEMA FROM information_schema.table_constraints pk INNER JOIN information_schema.key_column_usage c ON c.TABLE_NAME = pk.TABLE_NAME WHERE pk.CONSTRAINT_NAME like '%' + i.name + '%')
,object_name(i.object_id) tableName, i.name indexName, c.name columnName, c.is_identity
,ident_seed(object_name(i.object_id)) seed
,ident_incr(object_name(i.object_id)) increment
,ident_current(object_name(i.object_id)) lastAssignedId
,CreateDate = ( SELECT s.crdate FROM sysobjects s INNER JOIN (SELECT COUNT(1) cnt, xtype FROM sysobjects group by xtype) c ON s.xtype = c.xtype WHERE s.name = i.name)
,ModifiedDate = (SELECT s.refdate FROM sysobjects s INNER JOIN (SELECT COUNT(1) cnt, xtype FROM sysobjects group by xtype) c on s.xtype = c.xtype WHERE s.name = i.name)
FROM sys.indexes i
INNER JOIN sys.index_columns ic ON ic.object_id = i.object_id AND ic.index_id = i.index_id
INNER JOIN sys.columns c ON c.object_id = ic.object_id AND c.column_id = ic.column_id
WHERE i.is_primary_key = 1
ORDER BY ModifiedDate, CreateDate DESC