2016-12-12 2 views
7

Ich habe die folgenden TabellenSyntax für Identität einfügen FROM mit keine Spalten einfügen?

CREATE TABLE dbo.T_Comments_Paths 
(
    path_id bigint IDENTITY(1,1) NOT NULL 
    ,CONSTRAINT [PK_T_Comments_Paths] PRIMARY KEY(path_id) 
); 


CREATE TABLE dbo.T_Comments 
(
    COM_Id int IDENTITY(1,1) NOT NULL 
    ,COM_Text NATIONAL CHARACTER VARYING(255) NULL 
    ,CONSTRAINT [PK_T_Comments] PRIMARY KEY(COM_Id) 
); 

definiert Wenn ich brauche eine Pfad-ID für einen Kommentar für einen Single-Wert zu erhalten, habe ich es wie folgt zu erreichen:

jedoch
DECLARE @outputTable TABLE (path_id bigint); 
INSERT INTO T_Comments_Paths OUTPUT INSERTED.path_id INTO @outputTable DEFAULT VALUES; 
SET @__pathuid = (SELECT TOP 1 id FROM @outputTable); 

, Ich finde die Syntax zum Abrufen der eingefügten IDs (multiple) für eine Einfügung aus einer anderen Tabelle nicht.

z.B. Ich möchte, dies zu tun:

DECLARE @outputTable TABLE (path_id bigint, com_id bigint); 
INSERT INTO T_Comments_Paths 
OUTPUT INSERTED.path_id, com_id INTO @outputTable DEFAULT VALUES 
FROM T_Comments 

ergibt dies

"Falsche Syntax in der Nähe von FROM-Schlüsselwort"

Wie kann ich tun, dass (ohne Cursor)?
Hinweis: muss ich mit MySQL kompatibel sein, also kann ich nicht newid() verwenden, weil es keine UUID-Typ in MySQL ist, und ich will es auch nicht varchar oder varbinary verwenden ...

+0

@Ivan Starostin: Das ist kein Duplikat, er fügt nur einen Wert ein. Habe diesen Beitrag auch gefunden. Das ist nicht was ich will. –

+0

Haben Sie versucht, com_id mit INSERTED zu versehen? Also: OUTPUT INSERTED.path_id, INSERTED.com_id INTO @outputTable DEFAULT VALUES? –

+0

@John Joseph: Ich füge com_id nicht in T_Comments_Paths ein, ich füge es nur zusammen mit dem generierten Autoid in die Ausgabetabelle ein. –

Antwort

1

Wenn ich richtig verstehe, läuft Ihr Problem auf diese: Hinzufügen neuer Zeilen zu einer Identitätsspalte und dann diese neu hinzugefügten Werte, um eine leere Spalte in einer Tabelle mit n Zeilen (@outputTable) zu aktualisieren, ohne sich um die Übereinstimmung kümmern.

Einstellung für die Prüfung bis

CREATE TABLE #T_Comments_Paths (
    path_id BIGINT IDENTITY(1,1) NOT NULL 
    , CONSTRAINT [PK1] PRIMARY KEY (path_id) 
); 

CREATE TABLE #T_Comments (
    com_id BIGINT IDENTITY(1,1) NOT NULL 
    , com_text NVARCHAR(20) NULL 
    , CONSTRAINT [PK2] PRIMARY KEY (com_id) 
); 

INSERT INTO #T_comments (com_text) 
VALUES 
('com1') 
, ('com2'); 

** SOLUTION 1 **

Wenn Sie bereit sind, eine zusätzliche Spalte mit dem @outputTable (aka ROWNO) hinzufügen möchten, können Sie eine kürzere Lösung erhalten wie dies:

--Add a few values to make #T_Comment_Paths not empty, for testing purpose, making things not matching 
INSERT INTO #T_Comments_Paths DEFAULT VALUES; 
INSERT INTO #T_Comments_Paths DEFAULT VALUES; 
INSERT INTO #T_Comments_Paths DEFAULT VALUES; 

DECLARE @currentID BIGINT; 
SELECT @currentID = IDENT_CURRENT('#T_Comments_Paths'); 
-- @currentID should be 3 

DECLARE @outputTable TABLE (path_id bigint, com_id bigint, rowNo bigInt); 

INSERT INTO @outputTable (com_id, rowNo) 
SELECT 
    com_id 
    , ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) 
FROM 
    #T_comments; 

MERGE #T_Comments_Paths tgt 
USING @outputTable src 
ON tgt.path_id = src.path_id 
WHEN NOT MATCHED THEN INSERT DEFAULT VALUES; 

MERGE @outputTable tgt 
USING (
    SELECT 
     path_id 
     , ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS RowNo 
    FROM 
     #T_Comments_Paths 
    WHERE 
     path_id > @currentID 
) src 
ON tgt.RowNo = src.RowNo 
WHEN MATCHED THEN UPDATE SET 
    tgt.path_id = src.PATH_ID; 

SELECT * 
FROM 
    @outputTable; 

SELECT * 
FROM 
    #T_Comments_Paths 

DROP TABLE #T_Comments; 
DROP TABLE #T_Comments_Paths; 

** SOLUTION 2 **

Wenn Sie darauf bestehen, nur haben 2 Spalten in der @outputTable, dann ist dies eine Lösung (länger)

--Add a few values to make #T_Comment_Paths not empty, for testing purpose 
INSERT INTO #T_Comments_Paths DEFAULT VALUES; 
INSERT INTO #T_Comments_Paths DEFAULT VALUES; 
INSERT INTO #T_Comments_Paths DEFAULT VALUES; 
DECLARE @currentID BIGINT; 
SELECT @currentID = IDENT_CURRENT('#T_Comments_Paths'); 
-- @currentID should be 3 

DECLARE @outputTable TABLE (path_id bigint, com_id bigint); 
DECLARE @outputMiddleTable TABLE (rowNo bigint, com_id bigint); 


INSERT INTO @outputTable (com_id) 
SELECT 
    com_id 
FROM 
    #T_comments; 

WITH cte AS (
    SELECT 
     com_id 
     , ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS RowNo 
    FROM 
     @outputTable 
) 
INSERT INTO @outputMiddleTable (rowNo,com_id) 
SELECT RowNo, com_id 
FROM cte; 

MERGE #T_Comments_Paths tgt 
USING @outputTable src 
ON tgt.path_id = src.path_id 
WHEN NOT MATCHED THEN INSERT DEFAULT VALUES; 

WITH cte1 AS (
SELECT 
    path_id 
    , ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS RowNo 
FROM 
    #T_Comments_Paths 
WHERE 
    path_id > @currentID 
), cte2 AS (
SELECT 
    cte1.path_id 
    , t1.com_id 
FROM 
    @outputMiddleTable t1 
    JOIN cte1 ON t1.rowNo = cte1.RowNo 
) 
UPDATE ot 
SET path_id = cte2.path_id 
FROM @outputTable ot 
    JOIN cte2 ON ot.com_id = cte2.com_id 

SELECT * 
FROM 
    @outputTable; 


DROP TABLE #T_Comments; 
DROP TABLE #T_Comments_Paths; 
+1

Falls es nicht klar war: Ich bestehe auf 0 zusätzlichen Spalten, und die beiden Ausgabespalten, streng. Mit einer zusätzlichen Spalte ist es viel kürzer als jede Ihrer Lösungen, die alle eine zusätzliche Spalte hinzufügen. Eine Zusammenführung ist nicht notwendig oder erwünscht. Es ist nur eine Fehlerquelle für eine Multithread-Umgebung. –

+0

Ich meinte eine zusätzliche Spalte zu der Variablentabelle outputTable, nicht die ursprüngliche Tabelle T_Comments_Paths (die in meinen Lösungen ist es #T_Comments_Paths). Ich gebe zwei Lösungen ein, eine mit einer zusätzlichen Spalte in der Variablen outputTable, die andere ohne zusätzliche Spalte in der Variablen outputTable (aber es braucht eine zusätzliche Tabellenvariable) – DVT

+1

Ich glaube nicht, dass jemand, der dies liest, versteht, was vor sich geht. Schon deshalb kann es nicht als "Lösung" bezeichnet werden. Außerdem sehe ich nicht, welche Vorteile dies über einen Cursor bietet. Es ist länger und komplizierter. Ich versuche portablen, RDBMS-unabhängigen Code zu schreiben, möchte also so wenig wie technisch möglich. Ging mit einer zusätzlichen Spalte, als das ist die einzige Lösung, die Dinge wie Cursor oder dies verhindert. Die richtige Antwort auf die Frage lautet also: "Es ist nicht möglich". –

Verwandte Themen