Sqlserver
 sql >> Baza danych >  >> RDS >> Sqlserver

Połącz OUTPUT insert.id z wartością z wybranego wiersza

Możesz (ab) użyć MERGE z OUTPUT klauzula.

MERGE może INSERT , UPDATE i DELETE wydziwianie. W naszym przypadku wystarczy tylko INSERT .1=0 jest zawsze fałszywe, więc NOT MATCHED BY TARGET część jest zawsze wykonywana.Ogólnie rzecz biorąc, mogą istnieć inne gałęzie, zobacz docs.WHEN MATCHED jest zwykle używany do UPDATE;WHEN NOT MATCHED BY SOURCE jest zwykle używany do DELETE , ale nie potrzebujemy ich tutaj.

Ta zawiła forma MERGE jest odpowiednikiem prostego INSERT , ale w przeciwieństwie do prostego INSERT jego OUTPUT klauzula pozwala na odwołanie się do kolumn, których potrzebujemy. Pozwala na pobranie kolumn zarówno z tabel źródłowych, jak i docelowych, zapisując w ten sposób mapowanie między starymi i nowymi identyfikatorami.

MERGE INTO [dbo].[Test]
USING
(
    SELECT [Data]
    FROM @Old AS O
) AS Src
ON 1 = 0
WHEN NOT MATCHED BY TARGET THEN
INSERT ([Data])
VALUES (Src.[Data])
OUTPUT Src.ID AS OldID, inserted.ID AS NewID
INTO @New(ID, [OtherID])
;

Jeśli chodzi o twoją aktualizację i poleganie na kolejności generowanej IDENTITY wartości.

W prostym przypadku, gdy [dbo].[Test] ma IDENTITY kolumna, a następnie INSERT z ORDER BY będzie zagwarantować, że wygenerowana IDENTITY wartości byłyby w określonej kolejności. Zobacz punkt 4 w Gwarancje zamawiania w SQL Server . Pamiętaj, że nie gwarantuje to fizycznej kolejności wstawianych wierszy, ale gwarantuje kolejność, w jakiej IDENTITY wartości są generowane.

INSERT INTO [dbo].[Test] ([Data])
SELECT [Data]
FROM @Old
ORDER BY [RowID]

Ale kiedy używasz OUTPUT klauzula:

INSERT INTO [dbo].[Test] ([Data])
OUTPUT inserted.[ID] INTO @New
SELECT [Data]
FROM @Old
ORDER BY [RowID]

wiersze w OUTPUT strumień nie jest uporządkowany. A przynajmniej, ściśle mówiąc, ORDER BY w zapytaniu dotyczy podstawowego INSERT operacji, ale nic tam nie mówi, jaka jest kolejność OUTPUT . Więc nie próbowałbym na tym polegać. Użyj MERGE lub dodaj dodatkową kolumnę, aby jawnie przechowywać mapowanie między identyfikatorami.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. LEFT() vs SET TEXTSIZE w SQL Server:jaka jest różnica?

  2. SQL:Normalizacja bazy danych przy zachowaniu ograniczeń

  3. Różnica między #temptable a ##TempTable?

  4. Jak przekonwertować varchar na datę tylko wtedy, gdy zawiera poprawną datę?

  5. Jaki jest powód użycia kontekstu Transakcji przez inną sesję?