sql server加载数据而不修改表结构

时间:2014-07-22 09:32:31

标签: sql-server sql-server-2008

我正在开发一个将Access数据库迁移到SQL Server 2008的项目。我已成功将所有对象重新创建为SQL Server对象,但由于原始数据库仍在使用中,因此某些数据已更改。

在没有表格结构和关系被破坏的情况下,重新加载受影响的表格的最简单方法是什么。我尝试了安装中包含的导入和导出数据工具,但每当我要求它擦除服务器上的数据时,它就会抱怨外键。

3 个答案:

答案 0 :(得分:2)

  1. 您可以使用不同的架构(在SQL Server中)创建相同的新表,也可以 staging
  2. 使用导出/导入工具
  3. 将访问数据复制到登台
  4. 使用Red-Gate data compare的跟踪版本将登台表与源表进行比较
  5. 使用该工具同步数据。
  6. 这将允许您有一个临时区域进行测试。

答案 1 :(得分:2)

以下脚本可让您生成'创建'以及' drop'每个外键约束的语句。

请注意,我已在实时环境中对此进行了检查,并且工作正常。如果你给它一些时间,你可以放心解决方案。

  1. 复制以下脚本

  2. 执行它而不做任何更改,您将获得占用FOREIGN KEY的每个表的ALTER语句。

  3. 复制这些陈述并将其保存到另一个查询

  4. 现在更改行

    --SET @action='DROP'
    

    SET @action='DROP'
    
  5. 重复步骤2和3

    现在您可以删除脚本并创建所有外键。

  6. 执行在步骤4

  7. 之后获得的DROP语句
  8. 擦除数据后,执行ALTER Statements再次创建FOREIGN KEYS。

  9. 导入您的数据。

  10. 脚本

    DECLARE @schema_name SYSNAME;
    DECLARE @table_name SYSNAME;
    DECLARE @constraint_name SYSNAME;
    DECLARE @constraint_object_id INT;
    DECLARE @referenced_object_name SYSNAME;
    DECLARE @is_disabled BIT;
    DECLARE @is_not_for_replication BIT;
    DECLARE @is_not_trusted BIT;
    DECLARE @delete_referential_action TINYINT;
    DECLARE @update_referential_action TINYINT;
    DECLARE @tsql NVARCHAR(4000);
    DECLARE @tsql2 NVARCHAR(4000);
    DECLARE @fkCol SYSNAME;
    DECLARE @pkCol SYSNAME;
    DECLARE @col1 BIT;
    DECLARE @action CHAR(6);
    DECLARE @referenced_schema_name SYSNAME;
    
    --SET @action='DROP'
    
    DECLARE FKcursor CURSOR FOR
      SELECT Object_schema_name(parent_object_id),
         Object_name(parent_object_id),
         name,
         Object_name(referenced_object_id),
         object_id,
         is_disabled,
         is_not_for_replication,
         is_not_trusted,
         delete_referential_action,
         update_referential_action,
         Object_schema_name(referenced_object_id)
      FROM   sys.foreign_keys
      ORDER  BY 1,
                2;
    
    OPEN FKcursor;
    
    FETCH NEXT FROM FKcursor INTO @schema_name, @table_name, @constraint_name, @referenced_object_name, @constraint_object_id, @is_disabled, @is_not_for_replication, @is_not_trusted, @delete_referential_action, @update_referential_action, @referenced_schema_name;
    
    WHILE @@FETCH_STATUS = 0
      BEGIN
          IF @action <> 'CREATE'
            SET @tsql = 'ALTER TABLE ' + Quotename(@schema_name) + '.'
                    + Quotename(@table_name)
                    + ' DROP CONSTRAINT '
                    + Quotename(@constraint_name) + ';';
          ELSE
            BEGIN
                SET @tsql = 'ALTER TABLE ' + Quotename(@schema_name) + '.'
                        + Quotename(@table_name) + CASE @is_not_trusted WHEN 0 THEN ' WITH CHECK ' ELSE ' WITH NOCHECK ' END
                        + ' ADD CONSTRAINT '
                        + Quotename(@constraint_name)
                        + ' FOREIGN KEY (';
                SET @tsql2 = '';
    
                DECLARE ColumnCursor CURSOR FOR
                  SELECT Col_name(fk.parent_object_id, fkc.parent_column_id),
                         Col_name(fk.referenced_object_id, fkc.referenced_column_id)
                  FROM   sys.foreign_keys fk
                     INNER JOIN sys.foreign_key_columns fkc
                             ON fk.object_id = fkc.constraint_object_id
                  WHERE  fkc.constraint_object_id = @constraint_object_id
                  ORDER  BY fkc.constraint_column_id;
    
                OPEN ColumnCursor;
    
                SET @col1 = 1;
    
            FETCH NEXT FROM ColumnCursor INTO @fkCol, @pkCol;
    
            WHILE @@FETCH_STATUS = 0
              BEGIN
                  IF ( @col1 = 1 )
                    SET @col1 = 0;
                  ELSE
                    BEGIN
                        SET @tsql = @tsql + ',';
                        SET @tsql2 = @tsql2 + ',';
                    END;
    
                  SET @tsql = @tsql + Quotename(@fkCol);
                  SET @tsql2 = @tsql2 + Quotename(@pkCol);
    
                  FETCH NEXT FROM ColumnCursor INTO @fkCol, @pkCol;
              END;
    
            CLOSE ColumnCursor;
    
            DEALLOCATE ColumnCursor;
    
            SET @tsql = @tsql + ' ) REFERENCES '
                        + Quotename(@referenced_schema_name) + '.'
                        + Quotename(@referenced_object_name) + ' ('
                        + @tsql2 + ')';
            SET @tsql = @tsql + ' ON UPDATE ' + CASE @update_referential_action WHEN 0 THEN 'NO ACTION ' WHEN 1 THEN 'CASCADE ' WHEN 2 THEN 'SET NULL ' ELSE 'SET DEFAULT ' END + ' ON DELETE ' + CASE @delete_referential_action WHEN 0 THEN 'NO ACTION ' WHEN 1 THEN 'CASCADE ' WHEN 2 THEN 'SET NULL ' ELSE 'SET DEFAULT ' END + CASE @is_not_for_replication WHEN 1 THEN ' NOT FOR REPLICATION ' ELSE '' END
                        + ';';
        END;
    
      PRINT @tsql;
    
      IF @action = 'CREATE'
        BEGIN
            SET @tsql = 'ALTER TABLE ' + Quotename(@schema_name) + '.'
                        + Quotename(@table_name) + CASE @is_disabled WHEN 0 THEN ' CHECK ' ELSE ' NOCHECK ' END + 'CONSTRAINT '
                        + Quotename(@constraint_name) + ';';
    
            PRINT @tsql;            
        END;
    
      FETCH NEXT FROM FKcursor INTO @schema_name, @table_name, @constraint_name, @referenced_object_name, @constraint_object_id, @is_disabled, @is_not_for_replication, @is_not_trusted, @delete_referential_action, @update_referential_action, @referenced_schema_name;
      END;
    
    CLOSE FKcursor;
    
    DEALLOCATE FKcursor; 
    

    来自http://sqlblog.com/blogs/john_paul_cook/archive/2009/09/20/using-powershell-to-script-foreign-key-creation-statements.aspx

    的参考资料

答案 2 :(得分:1)

我建议使用SSIS(SQL Server集成服务)将数据从访问转换为数据库。

您还可以在新数据库中导入访问数据库,并使用Redgate Data Compare工具或其他工具来比较两个数据库和获取同步数据脚本之间的数据。