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

Jak skopiować tabele unikając kursorów w SQL?

Możesz użyć klauzuli output z instrukcją merge, aby uzyskać mapowanie między identyfikatorem źródłowym a identyfikatorem docelowym. Opisane w tym pytaniu. Korzystanie merge..output, aby uzyskać mapowanie między source.id i target.id

Oto kod, który możesz przetestować. Używam zmiennych tabel zamiast prawdziwych tabel.

Ustaw przykładowe dane:

-- @A and @B is the source tables
declare @A as table
(
  id int,
  FK_A_B int,
  name varchar(10)
)

declare @B as table
(
  id int,
  visible bit
)  

-- Sample data in @A and @B
insert into @B values (21, 1),(32, 0)
insert into @A values (1, 21, 'n1'),(5, 32, 'n2')


-- @C and @D is the target tables with id as identity columns
declare @C as table
(
  id int identity,
  FK_C_D int not null,
  name varchar(10)
)

declare @D as table
(
  id int identity,
  visible bit
)  

-- Sample data already in @C and @D
insert into @D values (1),(0)
insert into @C values (1, 'x1'),(1, 'x2'),(2, 'x3')

Skopiuj dane:

-- The @IdMap is a table that holds the mapping between
-- the @B.id and @D.id (@D.id is an identity column)
declare @IdMap table(TargetID int, SourceID int)

-- Merge from @B to @D.
merge @D as D             -- Target table
using @B as B             -- Source table
on 0=1                    -- 0=1 means that there are no matches for merge
when not matched then
  insert (visible) values(visible)    -- Insert to @D
output inserted.id, B.id into @IdMap; -- Capture the newly created inserted.id and
                                      -- map that to the source (@B.id)

-- Add rows to @C from @A with a join to
-- @IdMap to get the new id for the FK relation
insert into @C(FK_C_D, name)
select I.TargetID, A.name 
from @A as A
  inner join @IdMap as I
    on A.FK_A_B = I.SourceID

Wynik:

select *
from @D as D
  inner join @C as C
    on D.id = C.FK_C_D

id          visible id          FK_C_D      name
----------- ------- ----------- ----------- ----------
1           1       1           1           x1
1           1       2           1           x2
2           0       3           2           x3
3           1       4           3           n1
4           0       5           4           n2

Możesz przetestować kod tutaj:https://data.stackexchange.com/stackoverflow/q/101643/using-merge-to-map-source-id-to-target-id



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Rozwiązania dotyczące bezbłędnego odczytywania pliku dziennika transakcji programu SQL Server

  2. Najszybszy sposób wykonywania zagnieżdżonych wstawek zbiorczych z użyciem scope_identity()?

  3. SQL Server:sys.master_files vs. sys.database_files

  4. Zachowanie unikalnego indeksu, kolumny varchar i (pustych) spacji

  5. Czy istnieje sposób wyświetlania wyników PRINT za pomocą sterownika JDBC serwera SQL?