2016-04-26 6 views
0

子テーブルにFK列があるテーブル構造があります。データに階層があるときにデータのコピーを作成する方法

したがって、次があると言う:

Company 
-company_id 
-name 

Location 
-location_id 
-company_name 
-name 

Store 
-store_id 
-location_id 
-name 

Inventory 
-inventory_id 
-store_id 

今、私は場所、店舗と在庫のすべての行と一緒に、会社のコピーを作成したいです。

私はcompany_id = 123のコピーを作成したいと思います。すべての行を複製する必要があります。

私はこの試みた:

DECLARE @OriginalCompanyId = 123 

DECALRE @companyId AS INT 

INSERT Companies (name) 
select c.name 
from companies c 
where c.companyId = @OrignalCOmpanyId 

SET @companyId = SCOPE_IDENTITY() 

をしかし、他のテーブルが複数の行を持っていると私は新たに挿入されたPK値をリンクアップすることができなくなりますので、このアプローチは動作しません。

私はどのようなアプローチを取っていますか?

+0

意味がありません –

+0

@PouriaSharif何が意味がありませんか? –

答えて

0

私は実際にこれを行うプロジェクトに取り組んできました。私の解決策は空想ではないが、これまでのところ効果的であると証明されている。迷惑な部分はセットアッププロセスである。私は改善のための批判と提案に非常に寛容です。

  1. (私が行ってきた「プレースホルダ」の列を作成し、各PKEY/FKEYに必要なすべてのテーブル(私は新しい[ApplicationTableName]で行ってきた)
  2. の「ミラー」スキーマ/ DBを作成します。
  3. 既存のデータを1でインデックス付けされたプレースホルダキーにマップします(これは迷惑ですが、ランキング機能で実行できます)。
  4. プレースホルダキーでアプリケーションに降順で挿入します重要!)
  5. ランキング機能を使用して「ミラー」テーブルを更新する(例を参照)
  6. 必要なだけ多くのテーブルに渡って、drived/inserted値を使用して、必要に応じて繰り返します。

例:このスキーマを考える

...

CREATE TABLE Accounts (
    AccountID int identity(1,1) not null, 
    Name varchar(500) not null 

) 

CREATE TABLE Users(
    UserID int identity(1,1) not null, 
    AccountID int not null, 
    Name varchar(500) not null 
) 

CREATE TABLE NewUsers(
    pUserID int not null, 
    UserID int not null, 
    AccountID int not null, 
    Name varchar(500) 
) 

そして、このデータ

INSERT INTO NewUsers VALUES 
(1,0,0,'Bob'), 
(2,0,0,'Sally'), 
(3,0,0,'Jeff'), 
(4,0,0,'Sam') 

セイたびに、私たちはこれらを作成するアカウントを "作成" 4人のデフォルトユーザー...これは次のようになります

DECLARE @AccountID int --this is scalar, so we'll use scope_identity() to grab it. 
INSERT INTO Account VALUES('MyNewAccountID') 
SELECT @AccountID = SCOPE_IDENTITY() 

--Prepare NewUsers w/ derived accountID 
UPDATE NewUsers SET AccountID = @AccountID 

--Do our "application" insert 
INSERT INTO Users(AccountID,Name) 

SELECT AccountID,Name 
FROM NewUsers 
ORDER BY pUserID DESC; 

--Capture inserted ID's for use in other tables (where we've derived pUserID) 
WITH InsertedUsers AS(
    SELECT 
     --use dense rank, it handles fkey mappings too 
     DENSE_RANK() OVER(ORDER BY UserID DESC) as pUserID, 
     UserID 
    FROM Users 
) 
UPDATE NewUsers SET UserID = iu.UserID 
FROM NewUsers nu 
JOIN InsertedUsers iu 
ON iu.pUserID = nu.pUserID 


SELECT TOP 100 * FROM Account ORDER BY 1 DESC 
SELECT TOP 100 * FROM Users ORDER BY 1 DESC 

将来のテーブルにAppIDが必要な場合(派生したpUserIDがある場合)、pUserIDに参加してNewUsersから取得できます。

関連する問題