Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/sql-server/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql server SQL Server猜测缺少外键_Sql Server_Foreign Keys - Fatal编程技术网

Sql server SQL Server猜测缺少外键

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

我尝试使用以下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             
) 

-- 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;

你能举个例子更好地解释吗?比如,在给定一组起始表的情况下,显示您期望的结果?