2011-09-15 8 views
2

あるデータベースから別のデータベースにデータをインポートしています。また、hierarchyid列は、関係をそのまま使用して移植する必要があります。SQL Server 2008のすべてのHierarchyIDノードを更新します

ターゲットテーブルが空の場合は簡単です。ターゲットに行が含まれている場合、ソース表内の階層はターゲット表で有効ではありません

階層フィールドのすべての値を、最初に移植された行の主キーの値で増やすのが最も簡単です。

ソース行のhierarchyid'/1/12/13/'だったとインポートする前にターゲットで使用可能な次のidは101だった、階層は各値は100でインクリメントされるので、変更する必要があるのであれば:'/101/112/113/'

私はUpdating “Hierarchyid” in SQL Serverを読んでいるが、表示されませんどのように私の問題に適用することができます。

各行の各hierarchyidの各数値を1つの設定値で増分する方法、つまり、階層フィールドのすべての数値を100ずつ増やす方法はありますか。

+0

あなたがテーブルをターゲットにソーステーブルからデータを転送する(1 )あなたは常に最初のレベルを転送するか、または(2)下位レベルのみをインポートする場合(たとえば、2番目のレベルからデータをインポートする=>インポートする/ 101/1 /インポートしないで101/)?/101/2 /、/ 101/2 /、/ 101/2/1 /(第1の場合)、/ 101/2 /、/ 101/2/1 /π –

答えて

3

このソリューションを見(説明は怒鳴る見つけることができます):

DECLARE @Source TABLE 
(
    ID HIERARCHYID PRIMARY KEY 
    ,Name NVARCHAR(50) NOT NULL 
); 

DECLARE @Target TABLE 
(
    ID HIERARCHYID PRIMARY KEY 
    ,Name NVARCHAR(50) NOT NULL 
    ,OldID HIERARCHYID 
); 

INSERT @Source 
VALUES 
     ('/1/','a'), ('/1/1/','aa'), ('/1/2/','ab'), ('/1/3/','ac') 
     ,('/2/','b') 
     ,('/3/','c'), ('/3/3/','cc') 
     ,('/4/','d'), ('/4/1/','da'), ('/4/2/','db'), ('/4/2/1/','dba'), ('/4/2/1/5/','dbaf'); 

DECLARE @LastTargetRootNodeAsInteger INT;  
SELECT @LastTargetRootNodeAsInteger = REPLACE(MAX(a.ID.GetAncestor(a.ID.GetLevel()-1)).ToString(), '/', '') 
FROM @Target a; 

WITH CteUpdate 
AS 
(
SELECT a.ID 
     ,a.Name 
     ,a.ID.GetAncestor(a.ID.GetLevel()-1) AS OldRootID 
     ,CONVERT(HIERARCHYID,'/'+CONVERT(VARCHAR(256),@LastTargetRootNodeAsInteger+DENSE_RANK()OVER(ORDER BY a.ID.GetAncestor(a.ID.GetLevel()-1)))+'/') NewRootID 
FROM @Source a 
) 
INSERT @Target(ID, Name, OldID) 
SELECT a.ID.GetReparentedValue(a.OldRootID, a.NewRootID), a.Name, a.ID 
FROM CteUpdate a; 

SELECT * 
     ,t.ID.ToString() AS CurrentNodeToString 
     ,t.OldID.ToString() AS OldNodeToString 
FROM @Target t 
ORDER BY t.ID; 

説明:ターゲット表から最後のルートノード(@LastTargetRootNodeAsInteger)を見つけると仮定

  1. 第一歩。
  2. 次に、ソーステーブルのすべてのIDに対して、ルートノード(古いルートノード:a.ID.GetAncestor(a.ID.GetLevel()-1))が取得されます。
  3. すべての古いルートノードに対して、新しいルートノード('/'[email protected]+DENSE_RANK()OVER(ORDER BY old_root_node)+'/')が取得されます。
  4. 最後に、新しいルートノード(a.ID.GetReparentedValue(old_root,new_root))で行を挿入します。

我々は新しいIDを取得する方法、このクエリを実行することができます参照してくださいするには、次の

SELECT * 
     ,c.ID.GetReparentedValue(c.OldRootNode,c.NewRootNode).ToString() AS NewCurrentNode 
FROM 
(
     SELECT * 
       ,'/'+CONVERT(VARCHAR(256),@LastTargetRootNodeAsInteger+DENSE_RANK() OVER(ORDER BY b.OldRootNode))+'/' AS NewRootNode 
     FROM 
     (
       SELECT * 
         ,a.ID.ToString() AS OldCurrentNode 
         ,a.ID.GetAncestor(a.ID.GetLevel()-1).ToString() AS OldRootNode 
       FROM @Source a 
     ) b 
) c 

結果:

results

関連する問題