自动外键创建的麻烦

时间:2016-02-10 13:51:16

标签: sql-server schema database-schema

我有一个与SQL Server中的动态外键创建有关的问题。 我编写了一个SQL脚本来删除并在特定表上创建外键。 它一切正常,但是当我使用数据库比较工具时,它显示了“参考密钥”的差异,我不明白。

当我在SQL Server中检查表和外键时,它确实显示了正确的外键和正确的引用表和列。但是这个工具以不同的方式显示它。

所以基本上我需要知道哪个SQL Server正在告诉事物和DB Comparer不同。

这是我删除和重新创建外键的脚本

DECLARE @tblForeignKeys TABLE (SourceTable NVARCHAR(250),SourceConstraint NVARCHAR(250),SourceColumn NVARCHAR(250),TargetTable NVARCHAR(250),TargetColumn NVARCHAR(250))

--STEP 1: GET ALL FOREIGN KEYS RELATED TO FOLLOWING TABLES

-----------------GET ALL FOREIGN KEYS RELATED TO FOLLOWING TABLES--------------------------------
INSERT INTO @tblForeignKeys(SourceConstraint,SourceTable,TargetTable,SourceColumn,TargetColumn) 
    SELECT t1.Name SourceConstraint,t2.name SourceTable,t3.name TargetTable,t4.name SourceColumn,t5.name TargetColumn FROM sys.sysforeignkeys t0
            INNER JOIN sys.objects t1
                ON t0.constid=t1.object_id
            INNER JOIN sys.objects t2
                ON t0.fkeyid=t2.object_id AND t2.type='U'
            INNER JOIN sys.objects t3
                ON t0.rkeyid=t3.object_id AND t3.type='U'
            INNER JOIN sys.columns t4
                ON t4.object_id=t2.object_id AND t4.column_id=t0.fkey
            INNER JOIN sys.columns t5
                ON t5.object_id=t3.object_id AND t5.column_id=t0.rkey

                WHERE t2.name IN ( 
                    'tblONE',
                    'tblTWO',
                    'tblTHREE')


--STEP 2: DROP ALL FOREIGN KEYS

-------------DROP ALL FOREIGN KEYS START----------------------
DECLARE fkReaderForDrop CURSOR LOCAL SCROLL STATIC FOR SELECT SourceTable,SourceConstraint  FROM @tblForeignKeys
OPEN fkReaderForDrop 
FETCH NEXT FROM fkReaderForDrop INTO @SourceTable, @SourceConstraint
WHILE @@FETCH_STATUS = 0
BEGIN
   FETCH NEXT FROM fkReaderForDrop INTO @SourceTable, @SourceConstraint
   SET @sql=N'IF EXISTS (SELECT * FROM sys.foreign_keys WHERE object_id = OBJECT_ID(N''dbo.'+@SourceConstraint+''')AND parent_object_id = OBJECT_ID(N''dbo.'+@SourceTable+'''))
                ALTER TABLE [dbo].['+@SourceTable+'] DROP CONSTRAINT ['+@SourceConstraint+']'

   BEGIN TRY
        EXEC(@sql)
        PRINT @sql
   END TRY
   BEGIN CATCH
        PRINT ERROR_MESSAGE()
        PRINT @sql
        ----- IF ANY DROP FOREIGN THROW EXCEPTION THEN
        ----- JUST JUMP TO STEP-4 (RECREATE ALL FOREIGN KEY) AND SKIP THE STEP-3 (TRUNCATE TABLE)
        GOTO RECREATE_FOREIGNKEYS;
   END CATCH
END
CLOSE fkReaderForDrop 
DEALLOCATE fkReaderForDrop 
-------------DROP ALL FOREIGN KEYS END----------------------

--STEP 3: TRUNCATE ALL RELATED TABLES

-------------TRUNCATE ALL RELATED TABLES START----------------------
BEGIN TRY

    TRUNCATE TABLE tblONE
    TRUNCATE TABLE tblTWO
    TRUNCATE TABLE tblTHREE

END Try
BEGIN Catch
    PRINT ERROR_MESSAGE()
END Catch
-------------TRUNCATE ALL RELATED TABLES END----------------------

--STEP 4: RECREATE ALL FOREIGN KEYS

RECREATE_FOREIGNKEYS:
-------------RECREATE ALL FOREIGN KEYS START----------------------
DECLARE fkReaderForReCreate CURSOR LOCAL SCROLL STATIC FOR SELECT SourceTable,SourceConstraint,SourceColumn,TargetTable,TargetColumn  FROM @tblForeignKeys
OPEN fkReaderForReCreate 
FETCH NEXT FROM fkReaderForReCreate INTO @SourceTable,@SourceConstraint,@SourceColumn,@TargetTable,@TargetColumn 
WHILE @@FETCH_STATUS = 0
BEGIN
  FETCH NEXT FROM fkReaderForReCreate INTO @SourceTable,@SourceConstraint,@SourceColumn,@TargetTable,@TargetColumn 
  SET @sql=N'IF NOT EXISTS (SELECT * FROM sys.foreign_keys WHERE object_id = OBJECT_ID(N''[dbo].['+@SourceConstraint+']'') AND parent_object_id = OBJECT_ID(N''[dbo].['+@SourceTable+']''))
            BEGIN 
                ALTER TABLE [dbo].['+@SourceTable+']  WITH CHECK  ADD  CONSTRAINT ['+@SourceConstraint+'] FOREIGN KEY(['+@SourceColumn+'])
                REFERENCES [dbo].['+@TargetTable+'] (['+@TargetColumn+'])
                ALTER TABLE [dbo].['+@SourceTable+'] CHECK CONSTRAINT ['+@SourceConstraint+']
            END'
       BEGIN TRY
            EXEC(@sql)
            PRINT @sql
       END TRY
       BEGIN CATCH
           PRINT ERROR_MESSAGE()
           PRINT @sql
       END CATCH
END
CLOSE fkReaderForReCreate 
DEALLOCATE fkReaderForReCreate 
-------------RECREATE ALL FOREIGN KEYS END----------------------
PRINT 'In case of exception, Please copy the all failed script and re-run in other windows'
RETURN

数据库比较工具显示“参考密钥”中的差异

DB Compare Tool

0 个答案:

没有答案