2016-04-26 8 views
0

Ich habe eine Tabellenstruktur, wo FK-Spalten in untergeordneten Tabellen sind.So erstellen Sie eine Kopie der Daten, wenn die Daten eine Hierarchie haben

So sagen, es ist die folgende:

Company 
-company_id 
-name 

Location 
-location_id 
-company_name 
-name 

Store 
-store_id 
-location_id 
-name 

Inventory 
-inventory_id 
-store_id 

Jetzt möchte ich eine Kopie eines Unternehmens zu schaffen, zusammen mit allen Lage, zu speichern und Inventar Reihen.

Also sagen, ich möchte eine Kopie von company_id = 123 erstellen, ich muss alle Zeilen duplizieren.

Ich versuchte dies:

DECLARE @OriginalCompanyId = 123 

DECALRE @companyId AS INT 

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

SET @companyId = SCOPE_IDENTITY() 

Aber dieser Ansatz wird nicht funktionieren, weil die anderen Tabellen mehrere Zeilen haben und ich werde die neu eingefügten PK Werte nicht LinkUp der Lage sein.

Welchen Ansatz sollte ich nehmen?

+0

das macht keinen Sinn –

+0

@PouriaSharif was macht keinen Sinn? –

Antwort

0

Ich habe tatsächlich an einem Projekt gearbeitet, das genau das tut. Meine Lösung ist zwar nicht schick, hat sich bisher aber bewährt. Der nervige Teil ist der Setup-Prozess. Ich bin sehr offen für Kritik und Verbesserungsvorschläge.

  1. erstellen "Spiegel" schema/db aller notwendigen Tabellen (Ich habe mit New gegangen [ApplicationTableName])
  2. Für jede pKey/FKEY, erstellen Sie einen "Platzhalter" Spalte (I bin gegangen, mit p [Spaltenname])
  3. die vorhandenen Daten auf Karte Schlüssel zum Platzhalter, auf 1 indiziert (Dies ist ärgerlich, aber machbar mit Ranking-Funktionen.)
  4. in die Anwendung in absteigender Reihenfolge nach Ihren Platzhalter Schlüssel ein (absteigend ist wichtig!)
  5. Aktualisieren Sie Ihre "Spiegel" -Tabelle mit Ranking-Funktionen (siehe Beispiel)
  6. Wiederholen Sie dies bei Bedarf, indem Sie die Werte für driven/insert über beliebig viele Tabellen hinweg verwenden.

Beispiel:

dieses Schema gegeben ...

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) 
) 

und diese Daten

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

Say für jedes Mal, wenn wir "schaffen" ein Konto wir diese erstellen möchten 4 Standardbenutzer ... Dies wird ungefähr so ​​aussehen:

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 

Wenn nun eine zukünftige Tabelle UserID in der App benötigt (und eine abgeleitete pUserID hat), können wir sie aus NewUsers herausholen, indem wir pUserID beitreten.

Verwandte Themen