从数据库导出/导入层次结构图

前端之家收集整理的这篇文章主要介绍了从数据库导出/导入层次结构图前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我有一个包含2个表的基本数据库模式;一个是简单的ID – >术语的文本列表,另一个有2列,父和子.第一个表中的ID是在db序列插入时生成的,而第二个表包含用于存储层次结构的“结构”的键之间的映射.

我的问题是我有时可能希望将树从一个数据库移动到另一个数据库.如果我有2个DB,每个有10个术语(数据库A的术语!=数据库B的术语,并且没有重叠),我只是将数据从A复制到B然后我会遇到一个明显的问题,即术语将是重新编号,但关系不会.显然,在这个例子中,只需在所有关系键上添加10即可,但有没有人知道这样做的通用算法?

DB是oracle 11g,oracle特定的解决方案很好……

解决方法

概观

我将给出四个解决方案,从最简单的开始.对于每个解决方案,我将解释它适用的情况.

这些解决方案中的每一个都假定数据库A和B具有以下表格:

create table Terms
(
  ID int identity(1,1),Text nvarchar(MAX)
)

create table Relationships
(
  ParentID int,ChildID int
)

解决方案1

这是最简单的解决方案.它应该用于:

>具有相同文本的术语可以合并在一起

以下将合并从A到B的所有术语和关系:

insert into A.Terms (Text)
  select Text
  from A.Terms
  where Text not in (select Text from B.Terms)

insert into B.Relationships (ParentID,ChildID)
  select
    (select ID
     from B.Terms BTerms inner join A.Terms ATerms on BTerms.Text = ATerms.Text
     where ATerms.ID = Relationships.ParentID),(select ID
     from B.Terms BTerms inner join A.Terms ATerms on BTerms.Text = ATerms.Text
     where ATerms.ID = Relationships.ChildID)
  from A.Relationships

基本上你首先复制这些术语,然后根据文本复制将旧id映射到新id的关系.

注意:在您的问题中,您说明两个输入数据库之间的术语是不相交的.在这种情况下,可以省略第一个插入中的where子句.

解决方案2

这是下一个最简单的解决方案.它应该用于:

>具有相同文本的术语必须保持不同,并且
>您可以向目标表添加

首先在您的Terms表中添加一个名为“OldID”的int列,然后使用以下内容合并从A到B的所有术语和关系:

insert into A.Terms (Text,OldID)
  select Text,ID
  from A.Terms
  where Text not in (select Text from B.Terms)

insert into B.Relationships (ParentID,ChildID)
  select
    (select ID from B.Terms where OldID = ParentID),(select ID from B.Terms where OldID = ChildID)
  from A.Relationships

解决方案3

解决方案使用迭代.它应该用于:

>具有相同文本的术语必须保持不同,并且
>您无法修改目标表,和
>(a)你的ID列是一个标识列(在Oracle中,这意味着它有一个使用序列的触发器),或者(b)你想要一个适用于任何数据库技术的通用方法

以下将合并从A到B的所有术语和关系:

declare TermsCursor sys_refcursor; 
begin 

-- Create temporary mapping table
create table #Temporary (OldID int,NewID int)

-- Add terms one at a time,remembering the id mapping
open TermsCursor for select * from A.Terms;
for term in TermsCursor 
loop
  insert into B.Terms (Text) values ( term.Text ) returning ID into NewID;
  insert into Temporary ( OldID,NewID ) values ( term.ID,NewID );
end loop; 

-- Transfer the relationships
insert into B.Relationships (ParentID,ChildID)
  select
    (select ID
     from B.Terms BTerms inner join Temporary on BTerms.ID = Temporary.NewID
     where Temporary.OldID = Relationships.ParentID),(select ID
     from B.Terms BTerms inner join Temporary on BTerms.ID = Temporary.NewID
     where Temporary.OldID = Relationships.ChildID),from A.Relationships

-- Drop the temporary table
drop table #Temporary

end

解决方案4

解决方案特定于Oracle,要求您了解用于生成ID值的序列,并且效率低于某些其他解决方案.它应该用于:

>具有相同文本的术语必须保持不同,和
>您可以访问生成ID列的序列,以及
>您可以使用不会移植到非Oracle数据库技术的技术

以下将合并从A到B的所有术语和关系:

-- Create temporary mapping table
create table #Temporary (OldID int,NewID int)

-- Add terms to temporary mapping table
insert into #Tempoarary ( OldID,NewID )
select ID,sequence.nexval
from A.Terms

-- Transfer the terms
insert into B.Terms ( ID,Text )
select NewID,Text
from A.Terms inner join Temporary on ID = OldID

-- Transfer the relationships
insert into B.Relationships (ParentID,from A.Relationships

-- Drop the temporary table
drop table #Temporary

猜你在找的MsSQL相关文章