表具有外键时同步数据库

时间:2017-02-23 17:20:11

标签: sql-server

我们的一个SQL数据库是其他人的数据库的同步。他们的数据库中大约有100个表,而我们的数据库大约有120个。

在我们的网站中,我们还有一些附加表可以帮助我们映射和跟踪其他数据。作为我们附加表的一部分,我们在一些从我们的提供商同步的DBO表上创建外键。

因此,从我们的Provider同步的Customers表现在在mySchema.Receipts表上具有外键约束,该表具有CustomerID字段。

提供商的同步中断,他们说他们不能删除客户表以便同步数据,因为它现在说对客户有一个Foriegn密钥。

我是否有办法在SQL中告诉他们SQL可以...在同步时忽略Foriegn Key约束?

1 个答案:

答案 0 :(得分:1)

如果同步作业正在从目标数据库中删除数据,则可以禁用约束,然后在同步后再次启用它们。如果同步作业正在截断表或删除并重建表,则需要删除外键约束,然后在同步后重新生成。

  

使用"从目标中删除"的方法:

如果目标表是" dbo"的一部分。架构,您的流程可能如下所示:

(1)禁用目标数据库中的所有外键约束 示例:

exec sp_MSforeachtable 'IF ''?'' like ''%[dbo]%'' ALTER TABLE ? NOCHECK CONSTRAINT ALL;'

(2)删除目标表中的所有数据

(3)将所有数据从源复制到目标表,包括身份列数据(如果需要)。

(4)恢复目标数据库中的所有外键约束 例如:

exec sp_MSforeachtable 'IF ''?'' like ''%[dbo]%'' ALTER TABLE ? CHECK CONSTRAINT ALL;'

**为了进一步自动化,请利用SQL Server中的INFORMATION_SCHEMA.TABLES视图。

SELECT 'dbo.' + TABLE_NAME  as TableName, 'SELECT * FROM dbo.['+ TABLE_NAME +'];' AS Script FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'dbo' and TABLE_NAME NOT IN (comma delimited list of tables to exclude)

如果需要,以下脚本将查询所有外键约束:

IF OBJECT_ID('tempdb..#TEMPCONS') IS NOT NULL DROP TABLE #TEMPCONS;

SELECT KCU1.TABLE_SCHEMA, KCU1.TABLE_NAME, KCU1.CONSTRAINT_NAME, KCU1.COLUMN_NAME, KCU1.ORDINAL_POSITION, RC.UPDATE_RULE, RC.DELETE_RULE,
    KCU2.TABLE_NAME AS REF_TABLE_NAME, KCU2.CONSTRAINT_NAME AS REF_CONSTRAINT_NAME, KCU2.COLUMN_NAME AS REF_COLUMN_NAME, KCU2.ORDINAL_POSITION AS REF_ORDINAL_POSITION,
    KCU2.TABLE_SCHEMA AS REF_TABLE_SCHEMA   INTO #TEMPCONS
FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS RC INNER JOIN
    INFORMATION_SCHEMA.KEY_COLUMN_USAGE 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 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
ORDER BY TABLE_NAME, CONSTRAINT_NAME, ORDINAL_POSITION;

ALTER TABLE #TEMPCONS ADD COLUMN_LIST VARCHAR(MAX), REF_COLUMN_LIST VARCHAR(MAX);

-- Rows to column concatenation
DECLARE @COLUMN_NAME varchar(MAX), @Columns VARCHAR(MAX);
UPDATE #TEMPCONS SET @Columns = COLUMN_LIST = COALESCE(CASE COALESCE(@COLUMN_NAME, '') 
      WHEN CONSTRAINT_NAME THEN @Columns + ', ' + '['+ COLUMN_NAME +']' ELSE '['+ COLUMN_NAME +']' END, ''), @COLUMN_NAME = CONSTRAINT_NAME;

UPDATE #TEMPCONS SET @Columns = REF_COLUMN_LIST = COALESCE( CASE COALESCE(@COLUMN_NAME, '') 
      WHEN CONSTRAINT_NAME THEN @Columns + ', ' + '['+REF_COLUMN_NAME +']' ELSE '['+REF_COLUMN_NAME +']' END, ''), @COLUMN_NAME = CONSTRAINT_NAME;

SELECT TABLE_SCHEMA, TABLE_NAME, CONSTRAINT_NAME, UPDATE_RULE, DELETE_RULE, MAX(COLUMN_LIST) AS COLUMN_LIST, 
REF_TABLE_SCHEMA, REF_TABLE_NAME, REF_CONSTRAINT_NAME, MAX(REF_COLUMN_LIST) AS REF_COLUMN_LIST
FROM #TEMPCONS
GROUP BY REF_TABLE_SCHEMA, TABLE_SCHEMA, TABLE_NAME, CONSTRAINT_NAME, UPDATE_RULE, DELETE_RULE, REF_TABLE_NAME, REF_CONSTRAINT_NAME;