Frage

Meine Datenbank enthält drei Tabellen genannt Object_Table, Data_Table und Link_Table. Die Verknüpfungstabelle enthält nur zwei Spalten, um die Identität eines Objektdatensatzes und eine Identität eines Datensatzes.

Ich mag die Daten von DATA_TABLE kopieren, in dem es zu einer bestimmten Objektidentität verknüpft ist, und fügen Sie Datensätze in Data_Table und Link_Table für eine andere bestimmte Objektidentität entspricht.

I können Dies geschieht, indem in eine Tabelle Variable auswählen und das Durchschleifen für jede Iteration zwei Einsätze zu tun.

Ist dies der beste Weg, es zu tun?

Bearbeiten : Ich habe eine Schleife aus zwei Gründen vermeiden will, die erste ist, dass ich faul bin und eine Schleife / temp Tabelle mehr Code erfordert, mehr Code mehr Orte bedeutet einen Fehler zu machen und der zweite Grund ist die Sorge über die Leistung.

kann ich alle Daten in einem Einsatz kopieren, sondern, wie die Link-Tabelle auf die neuen Datensätze zu verknüpfen erhalte, wo jeder Datensatz eine neue ID hat?

War es hilfreich?

Lösung 3

Die folgenden Sätze auf die Situation, die ich hatte, Tabellenvariablen verwendet wird.

DECLARE @Object_Table TABLE
(
    Id INT NOT NULL PRIMARY KEY
)

DECLARE @Link_Table TABLE
(
    ObjectId INT NOT NULL,
    DataId INT NOT NULL
)

DECLARE @Data_Table TABLE
(
    Id INT NOT NULL Identity(1,1),
    Data VARCHAR(50) NOT NULL
)

-- create two objects '1' and '2'
INSERT INTO @Object_Table (Id) VALUES (1)
INSERT INTO @Object_Table (Id) VALUES (2)

-- create some data
INSERT INTO @Data_Table (Data) VALUES ('Data One')
INSERT INTO @Data_Table (Data) VALUES ('Data Two')

-- link all data to first object
INSERT INTO @Link_Table (ObjectId, DataId)
SELECT Objects.Id, Data.Id
FROM @Object_Table AS Objects, @Data_Table AS Data
WHERE Objects.Id = 1

Durch eine andere Antwort , die mich auf die OUTPUT-Klausel habe ich darauf hingewiesen, eine Lösung nachweisen kann:

-- now I want to copy the data from from object 1 to object 2 without looping
INSERT INTO @Data_Table (Data)
OUTPUT 2, INSERTED.Id INTO @Link_Table (ObjectId, DataId)
SELECT Data.Data
FROM @Data_Table AS Data INNER JOIN @Link_Table AS Link ON Data.Id = Link.DataId
                INNER JOIN @Object_Table AS Objects ON Link.ObjectId = Objects.Id 
WHERE Objects.Id = 1

Es stellt sich heraus jedoch, dass es wegen des folgenden Fehlers

im wirklichen Leben ist nicht so einfach
  

der OUTPUT INTO-Klausel kann nicht auf seine   auf beiden Seiten eines (Primärschlüssel, Fremd   key) Beziehung

Ich kann immer noch eine temporäre Tabelle und dann fertig mit normalen Einsatz OUTPUT INTO. So kann ich meine Schleife vermeiden, aber ich kann die temporäre Tabelle nicht vermeiden.

Andere Tipps

In einer Anweisung . Nein

In einer Transaktion : Ja

BEGIN TRANSACTION
   DECLARE @DataID int;
   INSERT INTO DataTable (Column1 ...) VALUES (....);
   SELECT @DataID = scope_identity();
   INSERT INTO LinkTable VALUES (@ObjectID, @DataID);
COMMIT

Die gute Nachricht ist, dass der oben genannte Code auch sein garantiert Atom , und kann in einem einzigen Funktionsaufruf mit einer SQL-Zeichenfolge von einer Client-Anwendung an den Server gesendet werden, als ob es ein waren Aussage. Sie könnten auch einen Trigger auf eine Tabelle gelten die Wirkung eines einzelnen Einsatz zu bekommen. Allerdings ist es letztlich noch zwei Aussagen und Sie wahrscheinlich nicht wollen, den Auslöser für alle einfügen.

laufen

Sie müssen noch zwei INSERT Aussagen, aber es klingt wie Sie die IDENTITY aus dem ersten Einsatz zu bekommen und es in den zweiten verwenden, wobei in diesem Fall, Sie könnten in OUTPUT oder OUTPUT INTO aussehen wollen: http://msdn.microsoft.com/en-us/library/ms177564.aspx

Es klingt wie die Link-Tabelle, die die vielen einfängt. Beziehung zwischen der Objekttabelle und Datentabelle

Mein Vorschlag ist, eine gespeicherte Prozedur zu verwenden, um die Transaktionen zu verwalten. Wenn Sie zum Objekt oder Datentabelle einfügen mögen Ihre Einsätze durchführen, um die neue IDs erhalten und sie an die Link-Tabelle einfügen.

Auf diese Weise können alle Ihre Logik in Frage zu nennen sproc leicht eingekapselt bleiben.

Wenn Sie die Aktionen wollen mehr oder weniger Atom sein, würde ich sicherstellen, dass sie in einer Transaktion wickeln. Auf diese Weise können beide sicher sein, passiert oder beide nicht nach Bedarf geschehen.

Sie können eine Ansicht der Auswahl der Spaltennamen durch Ihre Insert-Anweisung erforderlich erstellen, fügen Sie ein STATT INSERT-Trigger, und legen Sie in dieser Ansicht.

Ich möchte auf mit

Stress
SET XACT_ABORT ON;

für die MSSQL-Transaktion mit mehreren SQL-Anweisungen.

Siehe auch: https://msdn.microsoft.com/en-us/ Bibliothek / ms188792.aspx Sie bieten ein sehr gutes Beispiel.

So sollte der endgültige Code wie folgt aussehen:

SET XACT_ABORT ON;

BEGIN TRANSACTION
   DECLARE @DataID int;
   INSERT INTO DataTable (Column1 ...) VALUES (....);
   SELECT @DataID = scope_identity();
   INSERT INTO LinkTable VALUES (@ObjectID, @DataID);
COMMIT

Einfügen kann nur auf einem Tisch zu einem Zeitpunkt, betreiben. Mehrere Einsätze haben mehrere Anweisungen haben.

Ich weiß nicht, dass Sie die Schleife durch eine Tabelle Variable tun müssen - können Sie nicht nur eine Masse in eine Tabelle einfügen verwenden, dann legen Sie die Masse in die anderen

Übrigens - ich vermute, Sie die Daten aus Object_Table kopieren bedeuten; sonst wird die Frage nicht sinnvoll ist.

Bevor man ein Multitable Einsatz in Oracle tun, könnten Sie einen Trick verwenden, um einen Einsatz in eine Ansicht, die Beteiligung definiert auf sie ein INSTEAD OF-Trigger musste die Einsätze durchzuführen. Kann dies in SQL Server durchgeführt werden?

-- ================================================
-- Template generated from Template Explorer using:
-- Create Procedure (New Menu).SQL
--
-- Use the Specify Values for Template Parameters 
-- command (Ctrl-Shift-M) to fill in the parameter 
-- values below.
--
-- This block of comments will not be included in
-- the definition of the procedure.
-- ================================================
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO

ALTER PROCEDURE InsetIntoTwoTable

(
@name nvarchar(50),
@Email nvarchar(50)
)

AS
BEGIN

    SET NOCOUNT ON;


    insert into dbo.info(name) values (@name)
    insert into dbo.login(Email) values (@Email)
END
GO

// Wenn Sie das gleiche wie erste Tabelle einfügen möchten

$qry = "INSERT INTO table (one, two, three) VALUES('$one','$two','$three')";

$result = @mysql_query($qry);

$qry2 = "INSERT INTO table2 (one,two, three) VVALUES('$one','$two','$three')";

$result = @mysql_query($qry2);

// oder wenn Sie wollen bestimmte Teile Tabelle ein

einfügen
 $qry = "INSERT INTO table (one, two, three) VALUES('$one','$two','$three')";


  $result = @mysql_query($qry);

 $qry2 = "INSERT INTO table2 (two) VALUES('$two')";

 $result = @mysql_query($qry2);

// Ich weiß es zu gut aussieht richtig zu sein, aber es funktioniert und Sie halten Abfrage Hinzufügen ist nur das ändern

    "$qry"-number and number in @mysql_query($qry"")

Ich habe 17 Tabellen dies in gearbeitet hat.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top