Sql server SQL Server猜测缺少外键
我尝试使用以下SQL代码猜测缺少的外键Sql server SQL Server猜测缺少外键,sql-server,foreign-keys,Sql Server,Foreign Keys,我尝试使用以下SQL代码猜测缺少的外键 DECLARE @ColumnList AS TABLE ( TableName varchar(255) NOT NULL, ColumnName varchar(255) NOT NULL, PKTableName varchar(255), PKColumnName varchar(255), HasForeignKey bit NOT NULL
DECLARE @ColumnList AS TABLE
(
TableName varchar(255) NOT NULL,
ColumnName varchar(255) NOT NULL,
PKTableName varchar(255),
PKColumnName varchar(255),
HasForeignKey bit NOT NULL
)
-- Find all column names that occur more than once.
-- Exclude archive and staging tables.
INSERT INTO @ColumnList
(TableName,
ColumnName,
PKTableName,
PKColumnName,
HasForeignKey)
SELECT t.NAME AS TableName,
c.NAME AS ColumnName,
NULL AS PKTableName,
NULL AS PKColumnName,
CASE
WHEN f1.parent_object_id IS NOT NULL THEN 1
WHEN f2.referenced_object_id IS NOT NULL THEN 1
ELSE 0
END AS HasForeignKey
FROM sys.tables AS t
JOIN sys.columns AS c
ON c.object_id = t.object_id
JOIN sys.types AS y
ON c.system_type_id = y.system_type_id
LEFT JOIN sys.foreign_key_columns AS f1
ON f1.parent_object_id = t.object_id AND f1.parent_column_id = c.column_id
LEFT JOIN sys.foreign_key_columns AS f2
ON f2.referenced_object_id = t.object_id AND f2.referenced_column_id = c.column_id
WHERE t.is_ms_shipped = 0 AND y.NAME IN ('bigint', 'int', 'smallint', 'tinyint', 'uniqueidentifier');
SELECT TableName,
ColumnName,
PKTableName,
PKColumnName
FROM @ColumnList
WHERE HasForeignKey = 0
AND ColumnName IN (SELECT ColumnName
FROM @ColumnList
GROUP BY ColumnName
HAVING Count(*) > 1)
ORDER BY ColumnName,
TableName;
这很好,并显示了许多候选对象。但是,我不知道如何显示可能的主键的表名和列名。任何帮助都将不胜感激。我将尝试根据列名进行主键的左外连接:
LEFT OUTER JOIN
(
INFORMATION_SCHEMA.TABLE_CONSTRAINTS TC
INNER JOIN INFORMATION_SCHEMA.CONSTRAINT_COLUMN_USAGE CCU ON
CCU.CONSTRAINT_CATALOG = TC.CONSTRAINT_CATALOG AND
CCU.CONSTRAINT_SCHEMA = TC.CONSTRAINT_SCHEMA AND
CCU.CONSTRAINT_NAME = TC.CONSTRAINT_NAME AND
CCU.TABLE_CATALOG = TC.TABLE_CATALOG AND
CCU.TABLE_SCHEMA = TC.TABLE_SCHEMA AND
CCU.TABLE_NAME = TC.TABLE_NAME
) ON
CCU.COLUMN_NAME = C.ColumnName AND -- Use the @ColumnList.ColumnName here
TC.CONSTRAINT_TYPE = 'PRIMARY KEY'
这在复合PKs中有点崩溃。如果名字不匹配,它也将不起作用-例如,有些人将使用id作为Person的PK,但在FK中它将是Person_id。试试这个
DECLARE @ColumnList AS TABLE
(
TableName varchar(255) NOT NULL,
ColumnName varchar(255) NOT NULL,
PKTableName varchar(255),
PKColumnName varchar(255),
HasForeignKey bit NOT NULL
)
-- Find all column names that occur more than once.
-- Exclude archive and staging tables.
INSERT INTO @ColumnList
(TableName,
ColumnName,
PKTableName,
PKColumnName,
HasForeignKey)
SELECT t.NAME AS TableName,
c.NAME AS ColumnName,
t2.NAME AS PKTableName,
c2.NAME AS PKColumnName,
CASE
WHEN f1.parent_object_id IS NOT NULL THEN 1
WHEN f2.referenced_object_id IS NOT NULL THEN 1
ELSE 0
END AS HasForeignKey
FROM sys.tables AS t
JOIN sys.columns AS c
ON c.object_id = t.object_id
JOIN sys.types AS y
ON c.system_type_id = y.system_type_id
LEFT JOIN sys.columns c2
ON (c.Name = c2.Name)
JOIN sys.tables t2
ON (c2.object_id = t2.object_id AND t.object_id <> t2.object_id)
LEFT JOIN sys.foreign_key_columns AS f1
ON f1.parent_object_id = t.object_id AND f1.parent_column_id = c.column_id
LEFT JOIN sys.foreign_key_columns AS f2
ON f2.referenced_object_id = t.object_id AND f2.referenced_column_id = c.column_id
WHERE t.is_ms_shipped = 0 AND y.NAME IN ('bigint', 'int', 'smallint', 'tinyint', 'uniqueidentifier');
SELECT TableName,
ColumnName,
PKTableName,
PKColumnName
FROM @ColumnList
WHERE HasForeignKey = 0
AND ColumnName IN (SELECT ColumnName
FROM @ColumnList
GROUP BY ColumnName
HAVING Count(*) > 1)
ORDER BY ColumnName,
TableName;
你能举个例子更好地解释吗?比如,在给定一组起始表的情况下,显示您期望的结果?